diff --git a/Makefile b/Makefile
index e7f12b5fb..3f5ea360b 100644
--- a/Makefile
+++ b/Makefile
@@ -361,6 +361,7 @@ SOURCES += src/simutrans/descriptor/tunnel_desc.cc
 SOURCES += src/simutrans/descriptor/vehicle_desc.cc
 SOURCES += src/simutrans/descriptor/way_desc.cc
 SOURCES += src/simutrans/display/font.cc
+SOURCES += src/simutrans/display/simgraph.cc
 SOURCES += src/simutrans/display/simgraph$(COLOUR_DEPTH).cc
 SOURCES += src/simutrans/display/simview.cc
 SOURCES += src/simutrans/display/viewport.cc
diff --git a/Simutrans-Main.vcxitems b/Simutrans-Main.vcxitems
index 9b972e6f3..394b18fd3 100644
--- a/Simutrans-Main.vcxitems
+++ b/Simutrans-Main.vcxitems
@@ -82,6 +82,7 @@
     <ClCompile Include="$(MSBuildThisFileDirectory)src\simutrans\descriptor\vehicle_desc.cc" />
     <ClCompile Include="$(MSBuildThisFileDirectory)src\simutrans\descriptor\way_desc.cc" />
     <ClCompile Include="$(MSBuildThisFileDirectory)src\simutrans\display\font.cc" />
+    <ClCompile Include="$(MSBuildThisFileDirectory)src\simutrans\display\simgraph.cc" />
     <ClCompile Include="$(MSBuildThisFileDirectory)src\simutrans\display\simview.cc" />
     <ClCompile Include="$(MSBuildThisFileDirectory)src\simutrans\display\viewport.cc" />
     <ClCompile Include="$(MSBuildThisFileDirectory)src\simutrans\freight_list_sorter.cc" />
diff --git a/cmake/SimutransSourceList.cmake b/cmake/SimutransSourceList.cmake
index 2bbde1707..ba78610c0 100644
--- a/cmake/SimutransSourceList.cmake
+++ b/cmake/SimutransSourceList.cmake
@@ -68,6 +68,7 @@ target_sources(simutrans PRIVATE
 		src/simutrans/descriptor/way_desc.cc
 		src/simutrans/display/font.cc
 		src/simutrans/display/simview.cc
+		src/simutrans/display/simgraph.cc
 		src/simutrans/display/viewport.cc
 		src/simutrans/freight_list_sorter.cc
 		src/simutrans/ground/boden.cc
diff --git a/src/simutrans/dataobj/environment.cc b/src/simutrans/dataobj/environment.cc
index 1d7bb1bf1..6f9bd9ebe 100644
--- a/src/simutrans/dataobj/environment.cc
+++ b/src/simutrans/dataobj/environment.cc
@@ -423,11 +423,11 @@ void env_t::rdwr(loadsave_t *file)
 	if (  file->is_version_less(120, 5)  ) {
 		uint8 color_idx = COL_SOFT_BLUE;
 		file->rdwr_byte( color_idx );
-		env_t::tooltip_color_rgb = get_color_rgb(color_idx);
+		env_t::tooltip_color_rgb = g_simgraph->get_color_rgb(color_idx);
 
 		color_idx = COL_BLACK;
 		file->rdwr_byte( color_idx );
-		env_t::tooltip_textcolor_rgb = get_color_rgb(color_idx);
+		env_t::tooltip_textcolor_rgb = g_simgraph->get_color_rgb(color_idx);
 	}
 
 	file->rdwr_long( autosave );
@@ -504,13 +504,13 @@ void env_t::rdwr(loadsave_t *file)
 			file->rdwr_byte( color ); // to skip old parameter front_window_bar_color
 
 			file->rdwr_byte( color );
-			env_t::front_window_text_color_rgb = get_color_rgb(color);
+			env_t::front_window_text_color_rgb = g_simgraph->get_color_rgb(color);
 
 			file->rdwr_byte( color ); // to skip old parameter bottom_window_bar_color
 
 			color = 209; // CITY_KI
 			file->rdwr_byte( color );
-			env_t::bottom_window_text_color_rgb = get_color_rgb(color);
+			env_t::bottom_window_text_color_rgb = g_simgraph->get_color_rgb(color);
 		}
 	}
 
@@ -539,7 +539,7 @@ void env_t::rdwr(loadsave_t *file)
 		if(  file->is_version_less(120, 5)  ) {
 			uint8 color = COL_GREY2;
 			file->rdwr_byte( color );
-			env_t::background_color_rgb = get_color_rgb(color);
+			env_t::background_color_rgb = g_simgraph->get_color_rgb(color);
 		}
 		file->rdwr_bool( draw_earth_border );
 		file->rdwr_bool( draw_outside_tile );
diff --git a/src/simutrans/dataobj/gameinfo.cc b/src/simutrans/dataobj/gameinfo.cc
index 5ee6d864d..70486d6f6 100644
--- a/src/simutrans/dataobj/gameinfo.cc
+++ b/src/simutrans/dataobj/gameinfo.cc
@@ -54,7 +54,7 @@ gameinfo_t::gameinfo_t(karte_t *welt) :
 			const koord pos(i * gr_x / MINIMAP_SIZE, j * gr_y / MINIMAP_SIZE);
 			const grund_t* gr = welt->lookup_kartenboden(pos);
 			map_rgb.at(i,j) = minimap_t::calc_ground_color(gr);
-			map_idx.at(i,j) = color_rgb_to_idx( map_rgb.at(i,j) );
+			map_idx.at(i,j) = g_simgraph->palette_indexof( map_rgb.at(i,j) );
 		}
 	}
 
@@ -132,7 +132,7 @@ void gameinfo_t::rdwr(loadsave_t *file)
 		for( int x=0;  x<MINIMAP_SIZE;  x++  ) {
 			file->rdwr_short( map_idx.at(x,y) );
 			if (file->is_loading()) {
-				map_rgb.at(x,y) = color_idx_to_rgb(map_idx.at(x,y));
+				map_rgb.at(x,y) = g_simgraph->palette_lookup(map_idx.at(x,y));
 			}
 		}
 	}
diff --git a/src/simutrans/dataobj/objlist.cc b/src/simutrans/dataobj/objlist.cc
index 76fbbc527..d7e838ea5 100644
--- a/src/simutrans/dataobj/objlist.cc
+++ b/src/simutrans/dataobj/objlist.cc
@@ -1337,7 +1337,7 @@ inline bool local_display_obj_vh(const obj_t *draw_obj, const sint16 xpos, const
 		if(  ontile  ||  (veh_ribi & ribi) == ribi  ||  (ribi_t::backward(veh_ribi) & ribi )== ribi  ||  draw_obj->get_typ() == obj_t::air_vehicle  ) {
 			// activate clipping only for our direction masked by the ribi argument
 			// use non-convex clipping (16) only if we are on the currently drawn tile or its n/w neighbours
-			activate_ribi_clip( ((veh_ribi|ribi_t::backward(veh_ribi))&ribi) | (ontile  ||  ribi == ribi_t::north  ||  ribi == ribi_t::west ? 16 : 0)  CLIP_NUM_PAR);
+			g_simgraph->activate_ribi_clip( ((veh_ribi|ribi_t::backward(veh_ribi))&ribi) | (ontile  ||  ribi == ribi_t::north  ||  ribi == ribi_t::west ? 16 : 0)  CLIP_NUM_PAR);
 			draw_obj->display( xpos, ypos  CLIP_NUM_PAR);
 		}
 		return true;
@@ -1357,7 +1357,7 @@ uint8 objlist_t::display_obj_vh( const sint16 xpos, const sint16 ypos, const uin
 
 	if(  capacity <= 1  ) {
 		uint8 i = local_display_obj_vh( obj.one, xpos, ypos, ribi, ontile  CLIP_NUM_PAR);
-		activate_ribi_clip( ribi_t::all  CLIP_NUM_PAR);
+		g_simgraph->activate_ribi_clip( ribi_t::all  CLIP_NUM_PAR);
 		return i;
 	}
 
@@ -1370,7 +1370,8 @@ uint8 objlist_t::display_obj_vh( const sint16 xpos, const sint16 ypos, const uin
 			break;
 		}
 	}
-	activate_ribi_clip( ribi_t::all  CLIP_NUM_PAR);
+
+	g_simgraph->activate_ribi_clip( ribi_t::all  CLIP_NUM_PAR);
 	return nr_v+1;
 }
 
diff --git a/src/simutrans/dataobj/pakset_manager.cc b/src/simutrans/dataobj/pakset_manager.cc
index bffe01d0d..9abe33545 100644
--- a/src/simutrans/dataobj/pakset_manager.cc
+++ b/src/simutrans/dataobj/pakset_manager.cc
@@ -101,7 +101,7 @@ void pakset_manager_t::open_doubled_warning_window()
 
 bool pakset_manager_t::load_paks_from_directory(const std::string &path, bool load_addons, const char *message)
 {
-	const bool drawing = is_display_init();
+	const bool drawing = g_simgraph->is_display_init();
 
 	// step is a bitmask to decide when it's time to update the progress bar.
 	// It takes the biggest power of 2 less than the number of elements and
@@ -121,7 +121,9 @@ bool pakset_manager_t::load_paks_from_directory(const std::string &path, bool lo
 	step = (2<<step)-1;
 
 	if(drawing  &&  skinverwaltung_t::biglogosymbol==NULL) {
-		display_fillbox_wh_rgb( 0, 0, display_get_width(), display_get_height(), color_idx_to_rgb(COL_BLACK), true );
+		const scr_size screen = g_simgraph->get_screen_size();
+		g_simgraph->draw_rect( 0, 0, screen.w, screen.h, g_simgraph->palette_lookup(COL_BLACK), true);
+
 		if (!load_pak_file(path + "symbol.BigLogo.pak")) {
 			dbg->warning("pakset_manager_t::load_paks_from_directory", "File 'symbol.BigLogo.pak' cannot be read, startup logo will not be displayed!");
 		}
diff --git a/src/simutrans/dataobj/settings.cc b/src/simutrans/dataobj/settings.cc
index 62e06bd75..aa15a72f3 100644
--- a/src/simutrans/dataobj/settings.cc
+++ b/src/simutrans/dataobj/settings.cc
@@ -759,7 +759,6 @@ void settings_t::parse_simuconf( tabfile_t& simuconf, sint16& disp_width, sint16
 
 	simuconf.read( contents );
 
-#if COLOUR_DEPTH != 0
 	// special day/night colors
 	for( int i = 0; i < LIGHT_COUNT; i++ ) {
 		char str[ 256 ];
@@ -768,16 +767,12 @@ void settings_t::parse_simuconf( tabfile_t& simuconf, sint16& disp_width, sint16
 
 		if( c.get_count() >= 6 ) {
 			// now update RGB values
-			display_day_lights[i].r = c[0];
-			display_day_lights[i].g = c[1];
-			display_day_lights[i].b = c[2];
+			const rgb888_t day_light   = { (uint8)c[0], (uint8)c[1], (uint8)c[2] };
+			const rgb888_t night_light = { (uint8)c[3], (uint8)c[4], (uint8)c[5] };
 
-			display_night_lights[i].r = c[3];
-			display_night_lights[i].g = c[4];
-			display_night_lights[i].b = c[5];
+			g_simgraph->set_light_color(i, day_light, night_light);
 		}
 	}
-#endif
 
 	// check for fontname, must be a valid name!
 	// will be only changed if default!
diff --git a/src/simutrans/dataobj/tabfile.cc b/src/simutrans/dataobj/tabfile.cc
index dcf76b1d2..8ff4cba22 100644
--- a/src/simutrans/dataobj/tabfile.cc
+++ b/src/simutrans/dataobj/tabfile.cc
@@ -161,10 +161,10 @@ PIXVAL tabfileobj_t::get_color(const char *key, PIXVAL def, rgb888_t *color_rgb)
 			uint8 index = (uint8)strtoul( value, NULL, 0 );
 			// we save in settings as RGB888
 			if (color_rgb) {
-				*color_rgb = get_color_rgb(index);
+				*color_rgb = g_simgraph->get_color_rgb(index);
 			}
 			// but the functions expect in the system colour (like RGB565)
-			return color_idx_to_rgb(index);
+			return g_simgraph->palette_lookup(index);
 		}
 #else
 		(void)color_rgb;
diff --git a/src/simutrans/dataobj/translator.cc b/src/simutrans/dataobj/translator.cc
index ab177cb46..6f03da5bb 100644
--- a/src/simutrans/dataobj/translator.cc
+++ b/src/simutrans/dataobj/translator.cc
@@ -597,7 +597,7 @@ void translator::set_language(int lang)
 		env_t::language_iso = langs[lang].iso;
 		env_t::default_settings.set_name_language_iso( langs[lang].iso );
 		init_custom_names(lang);
-		current_langinfo->ellipsis_width = proportional_string_width( translate("...") );
+		current_langinfo->ellipsis_width = g_simgraph->calc_text_width( translate("...") );
 		DBG_MESSAGE("translator::set_language()", "%s, unicode %d", langs[lang].name, true);
 	}
 	else {
diff --git a/src/simutrans/descriptor/factory_desc.h b/src/simutrans/descriptor/factory_desc.h
index 59576cb28..75feccaf8 100644
--- a/src/simutrans/descriptor/factory_desc.h
+++ b/src/simutrans/descriptor/factory_desc.h
@@ -273,7 +273,7 @@ public:
 	site_t get_placement() const { return placement; }
 	uint16 get_distribution_weight() const { return distribution_weight; }
 
-	PIXVAL get_color() const { return color_idx_to_rgb(color); }
+	PIXVAL get_color() const { return g_simgraph->palette_lookup(color); }
 
 	void set_productivity(uint16 p) { productivity=p; }
 	uint16 get_productivity() const { return productivity; }
diff --git a/src/simutrans/descriptor/goods_desc.h b/src/simutrans/descriptor/goods_desc.h
index d210c7853..a26de9c5b 100644
--- a/src/simutrans/descriptor/goods_desc.h
+++ b/src/simutrans/descriptor/goods_desc.h
@@ -112,7 +112,7 @@ public:
 	/**
 	* @return color for good table and waiting bars
 	*/
-	PIXVAL get_color() const { return color_idx_to_rgb(color); }
+	PIXVAL get_color() const { return g_simgraph->palette_lookup(color); }
 
 	void calc_checksum(checksum_t *chk) const
 	{
diff --git a/src/simutrans/descriptor/ground_desc.cc b/src/simutrans/descriptor/ground_desc.cc
index 17742eba3..a11c6b488 100644
--- a/src/simutrans/descriptor/ground_desc.cc
+++ b/src/simutrans/descriptor/ground_desc.cc
@@ -395,7 +395,7 @@ bool ground_desc_t::register_desc(const ground_desc_t *desc)
 	if(strcmp("Outside", desc->get_name())==0) {
 		image_t const* const image = desc->get_child<image_array_t>(2)->get_image(0,0);
 		dbg->message("ground_desc_t::register_desc()", "setting raster width to %i", image->get_pic()->w);
-		display_set_base_raster_width(image->get_pic()->w);
+		g_simgraph->set_base_raster_width(image->get_pic()->w);
 	}
 	// find out water animation stages
 	if(strcmp("Water", desc->get_name())==0) {
@@ -445,7 +445,7 @@ void ground_desc_t::init_ground_textures(karte_t *world)
 
 	// free old ones
 	if(image_offset!=IMG_EMPTY) {
-		display_free_all_images_above( image_offset );
+		g_simgraph->free_all_images_above(image_offset);
 	}
 #if COLOUR_DEPTH != 0
 	while (!ground_image_list.empty()) {
@@ -826,7 +826,7 @@ void ground_desc_t::init_ground_textures(karte_t *world)
 	}
 
 	// from here on the images are generated by us => deletion also by us then
-	image_offset = get_image_count();
+	image_offset = g_simgraph->get_image_count();
 	DBG_MESSAGE("ground_desc_t::init_ground_textures()","image_offset=%d", image_offset );
 
 	// water images for water and overlay
@@ -853,7 +853,7 @@ void ground_desc_t::init_ground_textures(karte_t *world)
 	// now the other transitions
 	for(  int i=0;  i < number_of_climates;  i++  ) {
 		// normal tile (no transition, not snow)
-		climate_image[i] = get_image_count();
+		climate_image[i] = g_simgraph->get_image_count();
 		for(  int dslope = 0;  dslope < totalslopes - 1;  dslope++  ) {
 			if(  doubleslope_to_imgnr[dslope] != 255  ) {
 				int slope = double_grounds ? dslope : slopetable[dslope];
diff --git a/src/simutrans/descriptor/image.h b/src/simutrans/descriptor/image.h
index 4959a642e..bea279a6d 100644
--- a/src/simutrans/descriptor/image.h
+++ b/src/simutrans/descriptor/image.h
@@ -78,7 +78,7 @@ public:
 
 	static image_t* create_single_pixel();
 
-	void register_image() { ::register_image(this); }
+	void register_image() { g_simgraph->register_image(this); }
 
 private:
 	friend class image_reader_t;
diff --git a/src/simutrans/descriptor/reader/image_reader.cc b/src/simutrans/descriptor/reader/image_reader.cc
index 5c15a6b0b..5cc6194d6 100644
--- a/src/simutrans/descriptor/reader/image_reader.cc
+++ b/src/simutrans/descriptor/reader/image_reader.cc
@@ -213,7 +213,7 @@ adjust_image:
 				images_adlers.put(adler,desc); // still with imageid == IMG_EMPTY!
 			}
 			// register image adds this image to the internal array maintained by simgraph??.cc
-			register_image(desc);
+			g_simgraph->register_image(desc);
 		}
 		else {
 			// no need to load doubles ...
diff --git a/src/simutrans/display/simgraph.cc b/src/simutrans/display/simgraph.cc
new file mode 100644
index 000000000..82b2ea8b6
--- /dev/null
+++ b/src/simutrans/display/simgraph.cc
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the Simutrans project under the Artistic License.
+ * (see LICENSE.txt)
+ */
+
+#include "simgraph.h"
+
+#include "simgraph0.h"
+#include "simgraph16.h"
+
+
+const simgraph_t *g_simgraph;
+
+scr_coord_val default_font_ascent = 0;
+
+// a font height of zero could cause division by zero errors, even though it should not be used in a server
+scr_coord_val default_font_linespace = 1;
+
+
+const simgraph_t *simgraph_select(simgraph_type_t preferred_type)
+{
+	switch (preferred_type) {
+#if COLOUR_DEPTH == 0
+		case SIMGRAPH_TYPE_NULL:     return &g_simgraph0;
+#else
+		case SIMGRAPH_TYPE_SOFTWARE: return &g_simgraph16;
+#endif
+
+		default: return NULL;
+	}
+}
diff --git a/src/simutrans/display/simgraph.h b/src/simutrans/display/simgraph.h
index cb02f2a08..840f87837 100644
--- a/src/simutrans/display/simgraph.h
+++ b/src/simutrans/display/simgraph.h
@@ -14,35 +14,6 @@
 #include "scr_coord.h"
 
 
-#if COLOUR_DEPTH != 0
-
-#ifndef ZOOM_NEUTRAL
-#define MAX_ZOOM_FACTOR (9)
-#define ZOOM_NEUTRAL (3)
-extern const sint32 zoom_num[MAX_ZOOM_FACTOR + 1];
-extern const sint32 zoom_den[MAX_ZOOM_FACTOR + 1];
-#endif
-
-extern scr_coord_val default_font_ascent;
-extern scr_coord_val default_font_linespace;
-
-#  define LINEASCENT (default_font_ascent)
-#  define LINESPACE  (default_font_linespace)
-#else
-#  define LINEASCENT 0
-// a font height of zero could cause division by zero errors, even though it should not be used in a server
-#  define LINESPACE  1
-
-#ifndef ZOOM_NEUTRAL
-#define MAX_ZOOM_FACTOR (0)
-#define ZOOM_NEUTRAL (0)
-extern const sint32 zoom_num[1];
-extern const sint32 zoom_den[1];
-#endif
-
-#endif
-
-
 /**
 * Alignment enum to align controls against each other.
 * Vertical and horizontal alignment can be masked together
@@ -76,299 +47,347 @@ struct clip_dimension {
 // save the current clipping and set a new one
 #define PUSH_CLIP(x,y,w,h) \
 	{\
-		clip_dimension const p_cr = display_get_clip_wh(); \
-		display_set_clip_wh(x, y, w, h);
+		clip_dimension const p_cr = g_simgraph->get_clip_rect(CLIP_NUM_DEFAULT_VALUE); \
+		g_simgraph->set_clip_rect(x, y, w, h CLIP_NUM_DEFAULT, false);
 
 // save the current clipping and set a new one
 // fit it to old clipping region
 #define PUSH_CLIP_FIT(x,y,w,h) \
 	{\
-		clip_dimension const p_cr = display_get_clip_wh(); \
-		display_set_clip_wh(x, y, w, h CLIP_NUM_DEFAULT, true);
+		clip_dimension const p_cr = g_simgraph->get_clip_rect(CLIP_NUM_DEFAULT_VALUE); \
+		g_simgraph->set_clip_rect(x, y, w, h CLIP_NUM_DEFAULT, true);
 
 // restore a saved clipping rect
 #define POP_CLIP() \
-		display_set_clip_wh(p_cr.x, p_cr.y, p_cr.w, p_cr.h); \
+		g_simgraph->set_clip_rect(p_cr.x, p_cr.y, p_cr.w, p_cr.h CLIP_NUM_DEFAULT, false); \
 	}
 
-/**
- *
- */
-PIXVAL color_idx_to_rgb(PIXVAL idx);
-PIXVAL color_rgb_to_idx(PIXVAL color);
 
-/*
- * Get 24bit RGB888 colour from an index of the old 8bit palette
- */
-rgb888_t get_color_rgb(uint8 idx);
+// pointer to image display procedures
+typedef void (*draw_image_proc)(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const bool daynight, const bool dirty  CLIP_NUM_DEF);
+typedef void (*draw_blend_proc)(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF);
+typedef void (*draw_alpha_proc)(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF);
 
-/*
- * Environment colours from RGB888 to system format
- */
-void env_t_rgb_to_system_colors();
 
-/**
- * Helper functions for clipping along tile borders.
- */
-void add_poly_clip(int x0_,int y0_, int x1, int y1, int ribi  CLIP_NUM_DEF);
-void clear_all_poly_clip(CLIP_NUM_DEF0);
-void activate_ribi_clip(int ribi  CLIP_NUM_DEF);
+#define ALPHA_RED 0x1
+#define ALPHA_GREEN 0x2
+#define ALPHA_BLUE 0x4
 
-/* Do no access directly, use the get_tile_raster_width()
- * function instead.
- */
-extern scr_coord_val tile_raster_width;
-inline scr_coord_val get_tile_raster_width(){return tile_raster_width;}
+/// Also known as a "9-slice"
+typedef image_id stretch_map_t[3][3];
 
+#if COLOUR_DEPTH != 0
+#  define MAX_ZOOM_FACTOR (9)
+#  define ZOOM_NEUTRAL    (3)
+#else
+#  define MAX_ZOOM_FACTOR (0)
+#  define ZOOM_NEUTRAL    (0)
+#endif
 
-extern scr_coord_val base_tile_raster_width;
-inline scr_coord_val get_base_tile_raster_width(){return base_tile_raster_width;}
 
-/* changes the raster width after loading */
-scr_coord_val display_set_base_raster_width(scr_coord_val new_raster);
+enum simgraph_type_t
+{
+	SIMGRAPH_TYPE_NULL     = 0, // Dummy renderer, used for servers
+	SIMGRAPH_TYPE_SOFTWARE = 1, // 16 bit software (CPU) renderer, default
+};
 
 
-int zoom_factor_up();
-int zoom_factor_down();
+/// Graphics renderer interface
+struct simgraph_t
+{
+	simgraph_type_t type;
 
+	/// Do no access directly, use the get_* functions below instead.
+	scr_coord_val tile_raster_width;
+	scr_coord_val base_tile_raster_width;
+	signed short current_tile_raster_width;
 
-/**
- * Initialises the graphics module
- */
-bool simgraph_init(scr_size window_size, sint16 fullscreen);
-bool is_display_init();
-void simgraph_exit();
-void simgraph_resize(scr_size new_window_size);
+	// variables for storing currently used image procedure set
+	draw_image_proc draw_normal;
+	draw_image_proc draw_color;
+	draw_blend_proc draw_blend;
+	draw_alpha_proc draw_alpha;
 
+	inline scr_coord_val get_tile_raster_width()         const { return tile_raster_width;         }
+	inline scr_coord_val get_base_tile_raster_width()    const { return base_tile_raster_width;    }
+	inline scr_coord_val get_current_tile_raster_width() const { return current_tile_raster_width; }
 
-/**
- * Loads the font, returns the number of characters in it
- * @param fname
- * @param reload if true forces reload
- */
-bool display_load_font(const char *fname, bool reload = false);
+	sint32 zoom_num[MAX_ZOOM_FACTOR+1];
+	sint32 zoom_den[MAX_ZOOM_FACTOR+1];
 
-image_id get_image_count();
-void register_image(class image_t *);
+	//
+	// Colour palette stuff
+	//
 
-// delete all images above a certain number ...
-void display_free_all_images_above( image_id above );
+	/// Looks up a colour from its palette index
+	PIXVAL (*palette_lookup)(PIXVAL idx);
 
-// unzoomed offsets
-void display_get_base_image_offset( image_id image, scr_coord_val *xoff, scr_coord_val *yoff, scr_coord_val *xw, scr_coord_val *yw );
-// zoomed offsets
-void display_get_image_offset( image_id image, scr_coord_val *xoff, scr_coord_val *yoff, scr_coord_val *xw, scr_coord_val *yw );
-void display_mark_img_dirty( image_id image, scr_coord_val x, scr_coord_val y );
+	/// Retrieves the palette index of a color, or returns 0 if the color is not in the palette.
+	PIXVAL (*palette_indexof)(PIXVAL color);
 
-void mark_rect_dirty_wc(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2); // clips to screen only
-void mark_rect_dirty_clip(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2  CLIP_NUM_DEF); // clips to clip_rect
-void mark_screen_dirty();
+	/// Get 24bit RGB888 colour from an index of the old 8bit palette
+	rgb888_t (*get_color_rgb)(uint8 idx);
 
-scr_coord_val display_get_width();
-scr_coord_val display_get_height();
-void display_set_height(scr_coord_val);
-void display_set_actual_width(scr_coord_val);
+	/// Environment colours from RGB888 to system format
+	void (*env_t_rgb_to_system_colors)();
 
-// get next smallest size when scaling to percent
-scr_size display_get_best_matching_size(const image_id n, sint16 zoom_percent);
+	/// changes the raster width after loading
+	scr_coord_val (*set_base_raster_width)(scr_coord_val new_raster);
 
-// force a certain size on a image (for rescaling tool images)
-void display_fit_img_to_width( const image_id n, sint16 new_w );
+	int (*zoom_factor_up)();
+	int (*zoom_factor_down)();
 
-void display_day_night_shift(int night);
+	/// Initialises the graphics module
+	bool (*init)(scr_size window_size, sint16 fullscreen);
 
-// scrolls horizontally, will ignore clipping etc.
-void display_scroll_band( const scr_coord_val start_y, const scr_coord_val x_offset, const scr_coord_val h );
+	bool (*is_display_init)();
 
-// set first and second company color for player
-void display_set_player_color_scheme(const int player, const uint8 col1, const uint8 col2 );
+	/// Closes the graphics module
+	void (*exit)();
 
-// only used for GUI, display image inside a rect
-void display_img_aligned( const image_id n, scr_rect area, int align, const bool dirty);
+	void (*on_window_resized)(scr_size new_window_size);
 
-// display image with day and night change
-void display_img_aux(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const bool daynight, const bool dirty  CLIP_NUM_DEF);
+	/// Loads the font, returns the number of characters in it
+	/// @param reload if true forces reload
+	bool (*load_font)(const char *fname, bool reload /*=false*/);
 
-/**
- * draws the images with alpha, either blended or as outline
- */
-void display_rezoomed_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF);
-#define display_img_blend( n, x, y, c, dn, d ) display_rezoomed_img_blend( (n), (x), (y), 0, (c), (dn), (d)  CLIP_NUM_DEFAULT)
+	image_id (*get_image_count)();
 
-#define ALPHA_RED 0x1
-#define ALPHA_GREEN 0x2
-#define ALPHA_BLUE 0x4
+	void (*register_image)(class image_t *);
 
-void display_rezoomed_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF);
-#define display_img_alpha( n, a, f, x, y, c, dn, d ) display_rezoomed_img_alpha( (n), (a), (f), (x), (y), 0, (c), (dn), (d)  CLIP_NUM_DEFAULT)
+	// delete all images above a certain number ...
+	void (*free_all_images_above)(image_id above);
 
-// display image with color (if there) and optional day and night change
-void display_color_img(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const bool daynight, const bool dirty  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
+	/// unzoomed offsets
+	scr_rect (*get_base_image_offset)(image_id image);
 
-// display unzoomed image
-void display_base_img(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const bool daynight, const bool dirty  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
+	/// zoomed offsets
+	scr_rect (*get_image_offset)(image_id image);
 
-typedef image_id stretch_map_t[3][3];
+	void (*mark_img_dirty)(image_id image, scr_coord_val x, scr_coord_val y);
 
-// this displays a 3x3 array of images to fit the scr_rect
-void display_img_stretch( const stretch_map_t &imag, scr_rect area );
+	void (*mark_rect_dirty_wc)(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2); ///< clips to screen only
 
-// this displays a 3x3 array of images to fit the scr_rect like above, but blend the color
-void display_img_stretch_blend( const stretch_map_t &imag, scr_rect area, FLAGGED_PIXVAL color );
+	void (*mark_rect_dirty_clip)(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2  CLIP_NUM_DEF); // clips to clip_rect
 
-// display unzoomed image with alpha, either blended or as outline
-void display_base_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
-void display_base_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const sint8 player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
+	void (*mark_screen_dirty)();
 
-// pointer to image display procedures
-typedef void (*display_image_proc)(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const bool daynight, const bool dirty  CLIP_NUM_DEF);
-typedef void (*display_blend_proc)(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF);
-typedef void (*display_alpha_proc)(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF);
-
-// variables for storing currently used image procedure set and tile raster width
-extern display_image_proc display_normal;
-extern display_image_proc display_color;
-extern display_blend_proc display_blend;
-extern display_alpha_proc display_alpha;
-extern signed short current_tile_raster_width;
-
-// call this instead of referring to current_tile_raster_width directly
-#define get_current_tile_raster_width() (current_tile_raster_width)
-
-// for switching between image procedure sets and setting current tile raster width
-inline void display_set_image_proc( bool is_global )
-{
-	if(  is_global  ) {
-		display_normal = display_img_aux;
-		display_color = display_color_img;
-		display_blend = display_rezoomed_img_blend;
-		display_alpha = display_rezoomed_img_alpha;
-		current_tile_raster_width = get_tile_raster_width();
-	}
-	else {
-		display_normal = display_base_img;
-		display_color = display_base_img;
-		display_blend = display_base_img_blend;
-		display_alpha = display_base_img_alpha;
-		current_tile_raster_width = get_base_tile_raster_width();
-	}
-}
+	/// Returns the size of the drawable area.
+	/// @note The size of the underlying render target texture may be larger for alignment reasons.
+	scr_size (*get_screen_size)();
 
-// Blends two colors
-PIXVAL display_blend_colors(PIXVAL background, PIXVAL foreground, int percent_blend);
+	void (*set_screen_height)      (scr_coord_val new_height);
+	void (*set_screen_actual_width)(scr_coord_val new_actual_width);
 
-// blends a rectangular region
-void display_blend_wh_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, int percent_blend );
+	// get next smallest size when scaling to percent
+	scr_size (*get_best_matching_size)(image_id n, sint16 zoom_percent);
 
-void display_fillbox_wh_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty);
+	/// force a certain size on a image (for rescaling tool images)
+	void (*fit_img_to_width)(image_id n, sint16 new_w);
 
-void display_fillbox_wh_clip_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
+	void (*set_daynight_level)(int night_level);
 
-void display_filled_roundbox_clip(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty);
+	/// scrolls horizontally @p x_offset pixels to the left, will ignore clipping etc.
+	void (*move_scroll_band)(scr_coord_val start_y, scr_coord_val x_offset, scr_coord_val h);
 
-void display_vline_wh_clip_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val h, PIXVAL c, bool dirty  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
+	/// set primary and secondary company color for player
+	void (*set_player_color_scheme)(int player_idx, uint8 col1_idx, uint8 col2_idx);
 
-void display_flush_buffer();
+	/// for switching between image procedure sets, and for setting current tile raster width
+	void (*set_image_procs)(bool is_global);
 
-void display_show_pointer(int yesno);
-void display_set_pointer(int pointer);
-void display_show_load_pointer(int loading);
+	/// Only used for GUI, display image inside a rect
+	void (*draw_img_aligned)(image_id n, scr_rect area, int align, bool dirty);
 
+	/// display image with day and night change
+	void (*draw_img_aux)(image_id n, scr_coord_val xp, scr_coord_val yp, signed char player_nr, bool daynight, bool dirty  CLIP_NUM_DEF);
 
-void display_array_wh(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, const PIXVAL *arr);
+	/// draws the images with alpha, either blended or as outline
+	void (*draw_rezoomed_img_blend)(image_id n, scr_coord_val xp, scr_coord_val yp, signed char player_nr, FLAGGED_PIXVAL color_index, bool daynight, bool dirty  CLIP_NUM_DEF);
+	#define draw_img_blend( n, x, y, c, dn, d ) draw_rezoomed_img_blend( (n), (x), (y), 0, (c), (dn), (d)  CLIP_NUM_DEFAULT)
 
-// compound painting routines
-void display_outline_proportional_rgb(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty, sint32 len=-1);
-void display_shadow_proportional_rgb(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty, sint32 len=-1);
-void display_ddd_box_rgb(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color, bool dirty);
-void display_ddd_box_clip_rgb(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color);
+	void (*draw_rezoomed_img_alpha)(image_id n, image_id alphamask_n, unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, signed char player_nr, FLAGGED_PIXVAL color_index, bool daynight, bool dirty  CLIP_NUM_DEF);
+	#define draw_img_alpha( n, a, f, x, y, c, dn, d ) draw_rezoomed_img_alpha( (n), (a), (f), (x), (y), 0, (c), (dn), (d)  CLIP_NUM_DEFAULT)
 
+	/// display image with color (if there) and optional day and night change
+	void (*draw_color_img)(image_id n, scr_coord_val xp, scr_coord_val yp, signed char player_nr, bool daynight, bool dirty  CLIP_NUM_DEF);
 
-// unicode save moving in strings
-size_t get_next_char(const char* text, size_t pos);
-sint32 get_prev_char(const char* text, sint32 pos);
+	// display unzoomed image
+	void (*draw_base_img)(image_id n, scr_coord_val xp, scr_coord_val yp, signed char player_nr, bool daynight, bool dirty  CLIP_NUM_DEF);
 
-scr_coord_val display_get_char_width(utf32 c);
-scr_coord_val display_get_number_width();
+	// display unzoomed image with alpha, either blended or as outline
+	void (*draw_base_img_blend)(image_id n, scr_coord_val xp, scr_coord_val yp, signed char player_nr, FLAGGED_PIXVAL color_index, bool daynight, bool dirty  CLIP_NUM_DEF);
+	void (*draw_base_img_alpha)(image_id n, image_id alpha_n, unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, sint8 player_nr, FLAGGED_PIXVAL color_index, bool daynight, bool dirty  CLIP_NUM_DEF);
 
-/* returns true, if this is a valid character */
-bool has_character( utf16 char_code );
+	/// this displays a 3x3 array of images to fit the scr_rect
+	void (*draw_stretch_map)(const stretch_map_t &imag, scr_rect area);
 
-/**
- * For the next logical character in the text, returns the character code
- * as well as retrieves the char byte count and the screen pixel width
- * CAUTION : The text pointer advances to point to the next logical character
- */
-utf32 get_next_char_with_metrics(const char* &text, unsigned char &byte_length, unsigned char &pixel_width);
+	/// this displays a 3x3 array of images to fit the scr_rect like above, but blend the color
+	void (*draw_stretch_map_blend)(const stretch_map_t &imag, scr_rect area, FLAGGED_PIXVAL color);
 
-/**
- * For the previous logical character in the text, returns the character code
- * as well as retrieves the char byte count and the screen pixel width
- * CAUTION : The text pointer recedes to point to the previous logical character
- */
-utf32 get_prev_char_with_metrics(const char* &text, const char *const text_start, unsigned char &byte_length, unsigned char &pixel_width);
+	/// Blends two colors
+	PIXVAL (*blend_colors)(PIXVAL background, PIXVAL foreground, int percent_blend);
 
-/*
- * returns the index of the last character that would fit within the width
- * If an ellipsis len is given, it will only return the last character up to this len if the full length cannot be fitted
- * @returns index of next character. if text[index]==0 the whole string fits
- */
-size_t display_fit_proportional( const char *text, scr_coord_val max_width);
+	/// Tints a rectangular framebuffer region with @p color, clips to active clip rect
+	/// @param opacity_percent 0=do nothing, 100=replace framebuffer completely
+	void (*tint_rect)(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, int opacity_percent);
 
-/* routines for string len (macros for compatibility with old calls) */
-#define proportional_string_width(text)          display_calc_proportional_string_len_width(text, 0x7FFF)
-#define proportional_string_len_width(text, len) display_calc_proportional_string_len_width(text, len)
+	/// Fills a rectangular framebuffer region with a solid color.
+	/// @note Ignores active clip rect
+	void (*draw_rect)(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty);
 
-// length of a string in pixel
-scr_coord_val display_calc_proportional_string_len_width(const char* text, size_t len);
+	/// Same as @ref draw_rect, but clips to active clip rect.
+	void (*draw_rect_clipped)(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty  CLIP_NUM_DEF);
 
-// box which will contain the multi (or single) line of text
-void display_calc_proportional_multiline_string_len_width( int &xw, int &yh, const char *text);
+	/// Draw rect with rounded corners.
+	void (*draw_rounded_rect_clipped)(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty);
 
-/*
- * len parameter added - use -1 for previous behaviour.
- * completely renovated for unicode and 10 bit width and variable height
- */
+	/// Draws vertical line from {xp,yp} tp {xp,yp+h-1}
+	void (*draw_vline_clipped)(scr_coord_val xp, scr_coord_val yp, scr_coord_val h, PIXVAL color, bool dirty  CLIP_NUM_DEF);
 
-// #ifdef MULTI_THREAD
-scr_coord_val display_text_proportional_len_clip_rgb(scr_coord_val x, scr_coord_val y, const char* txt, control_alignment_t flags, const PIXVAL color, bool dirty, sint32 len  CLIP_NUM_DEF  CLIP_NUM_DEFAULT_ZERO);
-/* macro are for compatibility */
-#define display_proportional_rgb(               x, y, txt, align, color, dirty)       display_text_proportional_len_clip_rgb( x, y, txt, align,           color, dirty, -1 )
-#define display_proportional_clip_rgb(          x, y, txt, align, color, dirty)       display_text_proportional_len_clip_rgb( x, y, txt, align | DT_CLIP, color, dirty, -1 )
+	/// Flushes all dirty areas to the screen.
+	void (*flush_framebuffer)();
 
+	/// Shows or hides the mouse cursor.
+	void (*set_cursor_visible)(bool visible);
 
-/// Display a string that is abbreviated by the (language specific) ellipsis character if too wide
-/// If enough space is given, it just display the full string
-void display_proportional_ellipsis_rgb( scr_rect r, const char *text, int align, const PIXVAL color, const bool dirty, bool shadowed = false, PIXVAL shadow_color = 0 );
+	void (*set_default_cursor)(int cursor_id);
 
-void display_ddd_proportional_clip(scr_coord_val xpos, scr_coord_val ypos, FLAGGED_PIXVAL ddd_farbe, FLAGGED_PIXVAL text_farbe, const char *text, int dirty  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
+	/// Changes whether the load cursor or the default cursor is shown.
+	void (*set_show_load_cursor)(bool show);
 
+	/// Copies rectangular region of pixels to the frambuffer.
+	void (*draw_array)(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, const PIXVAL *arr);
 
-scr_coord_val display_multiline_text_rgb(scr_coord_val x, scr_coord_val y, const char *inbuf, PIXVAL color);
 
-// line drawing primitives
-void display_direct_line_rgb(const scr_coord_val x, const scr_coord_val y, const scr_coord_val xx, const scr_coord_val yy, const PIXVAL color);
-void display_direct_line_dotted_rgb(const scr_coord_val x, const scr_coord_val y, const scr_coord_val xx, const scr_coord_val yy, const scr_coord_val draw, const scr_coord_val dontDraw, const PIXVAL color);
-void display_circle_rgb( scr_coord_val x0, scr_coord_val  y0, int radius, const PIXVAL color );
-void display_filled_circle_rgb( scr_coord_val x0, scr_coord_val  y0, int radius, const PIXVAL color );
-void draw_bezier_rgb(scr_coord_val Ax, scr_coord_val Ay, scr_coord_val Bx, scr_coord_val By, scr_coord_val ADx, scr_coord_val ADy, scr_coord_val BDx, scr_coord_val BDy, const PIXVAL colore, scr_coord_val draw, scr_coord_val dontDraw);
+	//
+	// Font stuff and glyph metrics
+	// TODO this should maybe be moved somewhere else
+	//
 
-void display_right_triangle_rgb(scr_coord_val x, scr_coord_val y, scr_coord_val height, const PIXVAL colval, const bool dirty);
-void display_signal_direction_rgb(scr_coord_val x, scr_coord_val y, uint8 way_dir, uint8 sig_dir, PIXVAL col1, PIXVAL col1_dark, bool is_diagonal=false, uint8 slope = 0 );
+	/// returns true if this is a valid character for the currently loaded font
+	bool (*font_has_character)( utf16 char_code );
 
-void display_set_clip_wh(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO, bool fit = false);
-clip_dimension display_get_clip_wh(CLIP_NUM_DEF0 CLIP_NUM_DEFAULT_ZERO);
+	scr_coord_val (*get_char_width)(utf32 c);
+	scr_coord_val (*get_number_width)();
 
-void display_push_clip_wh(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
-void display_swap_clip_wh(CLIP_NUM_DEF0);
-void display_pop_clip_wh(CLIP_NUM_DEF0);
+	/**
+	 * For the next logical character in the text, returns the character code
+	 * as well as retrieves the char byte count and the screen pixel width
+	 * CAUTION : The text pointer advances to point to the next logical character
+	 */
+	utf32 (*get_next_char_with_metrics)(const char* &text, unsigned char &byte_length, unsigned char &pixel_width);
 
+	/**
+	 * For the previous logical character in the text, returns the character code
+	 * as well as retrieves the char byte count and the screen pixel width
+	 * CAUTION : The text pointer recedes to point to the previous logical character
+	 */
+	utf32 (*get_prev_char_with_metrics)(const char* &text, const char *const text_start, unsigned char &byte_length, unsigned char &pixel_width);
 
-bool display_snapshot( const scr_rect &area );
 
-#if COLOUR_DEPTH != 0
-extern rgb888_t display_day_lights  [LIGHT_COUNT];
-extern rgb888_t display_night_lights[LIGHT_COUNT];
-#endif
+	//
+	// Text rendering
+	//
+
+	/// Calculates the screen width of a UTF-8 encoded string in pixels.
+	/// @param len number of bytes in @p text, or -1 if @p text is null-terminated.
+	scr_coord_val (*calc_text_width_n)(const char *text, size_t len);
+
+	inline scr_coord_val calc_text_width(const char *text) const { return calc_text_width_n(text, 0x7FFFu); }
+
+	/// @returns Size of the bounding box which contains the single- or multiline @p text
+	scr_size (*calc_multiline_text_size)(const char *text);
+
+	/// Returns the index of the last character that would fit within the width
+	/// If an ellipsis len is given, it will only return the last character up to this len if the full length cannot be fitted
+	/// @returns index of next character. if text[index]==0 the whole string fits
+	size_t (*calc_text_index_for_width)(const char *text, scr_coord_val max_width);
+
+	scr_coord_val (*draw_text_clipped_n)(scr_coord_val x, scr_coord_val y, const char* txt, control_alignment_t flags, PIXVAL color, bool dirty, sint32 len  CLIP_NUM_DEF);
+
+	inline scr_coord_val draw_text_clipped(scr_coord_val x, scr_coord_val y, const char* txt, control_alignment_t flags, PIXVAL color, bool dirty) const
+	{
+		return draw_text_clipped_n(x, y, txt, flags | DT_CLIP, color, dirty, -1 CLIP_NUM_DEFAULT);
+	}
+
+	inline scr_coord_val draw_text(scr_coord_val x, scr_coord_val y, const char *txt, control_alignment_t flags, PIXVAL color, bool dirty) const
+	{
+		return draw_text_clipped_n(x, y, txt, flags, color, dirty, -1 CLIP_NUM_DEFAULT);
+	}
+
+	scr_coord_val (*draw_multiline_text)(scr_coord_val x, scr_coord_val y, const char *text, PIXVAL color);
+
+	/// Display a string that is abbreviated by the (language specific) ellipsis character if too wide
+	/// If enough space is given, it just display the full string
+	void (*draw_text_ellipsis_shadowed)(scr_rect r, const char *text, int align, PIXVAL color, bool dirty, bool shadow, PIXVAL shadow_color);
+
+	void draw_text_ellipsis(scr_rect r, const char *text, int align, PIXVAL color, bool dirty) const
+	{
+		draw_text_ellipsis_shadowed(r, text, align, color, dirty, false, 0);
+	}
+
+	// compound painting routines
+	void (*draw_text_outlined)(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty);
+	void (*draw_text_shadowed)(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty);
+
+	void (*draw_box3d)        (scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color, bool dirty);
+	void (*draw_box3d_clipped)(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color);
+
+	void (*draw_textbox3d_clipped)(scr_coord_val xpos, scr_coord_val ypos, FLAGGED_PIXVAL ddd_farbe, FLAGGED_PIXVAL text_farbe, const char *text, int dirty  CLIP_NUM_DEF);
+
+	void (*draw_line)       (scr_coord_val x, scr_coord_val y, scr_coord_val xx, scr_coord_val yy, PIXVAL color);
+	void (*draw_line_dotted)(scr_coord_val x, scr_coord_val y, scr_coord_val xx, scr_coord_val yy, scr_coord_val draw, scr_coord_val dontDraw, PIXVAL color);
+
+	void (*draw_empty_circle) (scr_coord_val x0, scr_coord_val y0, int radius, PIXVAL color);
+	void (*draw_filled_circle)(scr_coord_val x0, scr_coord_val y0, int radius, PIXVAL color);
+
+	void (*draw_bezier)(scr_coord_val Ax, scr_coord_val Ay, scr_coord_val Bx, scr_coord_val By, scr_coord_val ADx, scr_coord_val ADy, scr_coord_val BDx, scr_coord_val BDy, PIXVAL colore, scr_coord_val draw, scr_coord_val dontDraw);
+
+	void (*draw_right_triangle)(scr_coord_val x, scr_coord_val y, scr_coord_val height, PIXVAL colval, bool dirty);
+
+	void (*draw_signal_direction)(scr_coord_val x, scr_coord_val y, uint8 way_dir, uint8 sig_dir, PIXVAL col1, PIXVAL col1_dark, bool is_diagonal, uint8 slope);
+
+	bool (*take_screenshot)(const scr_rect &screen_area);
+
+	//
+	// Clipping
+	//
+
+	void (*set_clip_rect)(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF, bool fit /*=false*/);
+
+	clip_dimension (*get_clip_rect)(CLIP_NUM_DEF0);
+
+	void (*push_clip_rect)(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF);
+
+	void (*swap_clip_rect)(CLIP_NUM_DEF0);
+
+	void (*pop_clip_rect)(CLIP_NUM_DEF0);
+
+	void (*add_poly_clip)(int x0_,int y0_, int x1, int y1, int ribi  CLIP_NUM_DEF);
+	void (*clear_all_poly_clip)(CLIP_NUM_DEF0);
+	void (*activate_ribi_clip)(int ribi  CLIP_NUM_DEF);
+
+
+	void (*set_light_color)(int color_idx, rgb888_t day_color, rgb888_t night_color);
+};
+
+
+const simgraph_t *simgraph_select(simgraph_type_t preferred_type);
+
+/// Assign to this the output of simgraph_select
+extern const simgraph_t *g_simgraph;
+
+
+//
+// Variables required for layouting
+//
+
+extern scr_coord_val default_font_ascent;
+extern scr_coord_val default_font_linespace;
+
+#define LINEASCENT (default_font_ascent)
+#define LINESPACE  (default_font_linespace)
+
 
 #endif
diff --git a/src/simutrans/display/simgraph0.cc b/src/simutrans/display/simgraph0.cc
index c48011ed3..57f8d4d91 100644
--- a/src/simutrans/display/simgraph0.cc
+++ b/src/simutrans/display/simgraph0.cc
@@ -10,32 +10,226 @@
 #include "simgraph.h"
 
 
-scr_coord_val tile_raster_width = 16; // zoomed
-scr_coord_val base_tile_raster_width = 16; // original
 extern const sint32 zoom_num[1] = { 1 };
 extern const sint32 zoom_den[1] = { 1 };
 
-PIXVAL color_idx_to_rgb(PIXVAL idx)
+static PIXVAL        simgraph0_palette_lookup            (PIXVAL idx);
+static PIXVAL        simgraph0_palette_indexof           (PIXVAL color);
+static void          simgraph0_env_t_rgb_to_system_colors();
+static rgb888_t      simgraph0_get_color_rgb          (uint8 idx);
+static scr_coord_val simgraph0_set_base_raster_width  (scr_coord_val new_raster);
+static int           simgraph0_zoom_factor_up         ();
+static int           simgraph0_zoom_factor_down       ();
+static bool          simgraph0_init                   (scr_size window_size, sint16 full_screen);
+static bool          simgraph0_is_display_init        ();
+static void          simgraph0_exit                   ();
+static void          simgraph0_on_window_resized      (scr_size new_window_size);
+static bool          simgraph0_load_font              (const char *fname, bool reload);
+static image_id      simgraph0_get_image_count        ();
+static void          simgraph0_register_image         (image_t *image_in);
+static void          simgraph0_free_all_images_above  (image_id above );
+static scr_rect      simgraph0_get_base_image_offset  (image_id image);
+static scr_rect      simgraph0_get_image_offset       (image_id image);
+static void          simgraph0_mark_img_dirty         (image_id image, scr_coord_val xp, scr_coord_val yp);
+static void          simgraph0_mark_rect_dirty_wc     (scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2);
+static void          simgraph0_mark_rect_dirty_clip   (scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2  CLIP_NUM_DEF);
+static void          simgraph0_mark_screen_dirty      ();
+static scr_size      simgraph0_get_screen_size        ();
+static void          simgraph0_set_screen_actual_width(scr_coord_val w);
+static void          simgraph0_set_screen_height      (scr_coord_val const h);
+static scr_size      simgraph0_get_best_matching_size (const image_id n, sint16 zoom_percent);
+static void          simgraph0_fit_img_to_width       (const image_id n, sint16 new_w);
+static void          simgraph0_set_daynight_level     (int night);
+static void          simgraph0_move_scroll_band       (scr_coord_val start_y, scr_coord_val x_offset, scr_coord_val h);
+static void          simgraph0_set_player_color_scheme(const int player, const uint8 col1, const uint8 col2);
+static void          simgraph0_set_image_procs        (bool is_global);
+static void          simgraph0_draw_img_aligned       (const image_id n, scr_rect area, int align, const bool dirty);
+static void          simgraph0_draw_img_aux           (const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_rezoomed_img_blend(const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_rezoomed_img_alpha(const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_color_img         (const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_base_img          (const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_base_img_blend    (const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_base_img_alpha    (const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_stretch_map       (const stretch_map_t &, scr_rect);
+static void          simgraph0_draw_stretch_map_blend (const stretch_map_t &, scr_rect, FLAGGED_PIXVAL);
+static PIXVAL        simgraph0_blend_colors           (PIXVAL, PIXVAL, int);
+static void          simgraph0_tint_rect              (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, int);
+static void          simgraph0_draw_rect              (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool);
+static void          simgraph0_draw_rect_clipped      (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_draw_rounded_rect_clipped(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool);
+static void          simgraph0_draw_vline_clipped       (scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph0_flush_framebuffer        ();
+static void          simgraph0_set_cursor_visible       (bool);
+static void          simgraph0_set_default_cursor       (int);
+static void          simgraph0_set_show_load_cursor     (bool);
+static void           simgraph0_draw_array               (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL *);
+static scr_coord_val  simgraph0_calc_text_width_n        (const char *, size_t);
+static scr_size       simgraph0_calc_multiline_text_size (const char *);
+static size_t         simgraph0_calc_text_index_for_width(const char *, scr_coord_val);
+static bool           simgraph0_font_has_character       (utf16 char_code);
+static utf32          simgraph0_get_next_char_with_metrics(const char* &text, unsigned char &byte_length, unsigned char &pixel_width);
+static utf32          simgraph0_get_prev_char_with_metrics(const char* &text, const char *const text_start, unsigned char &byte_length, unsigned char &pixel_width);
+static scr_coord_val  simgraph0_get_char_width            (utf32 c);
+static scr_coord_val  simgraph0_get_number_width          ();
+static scr_coord_val  simgraph0_draw_text_clipped_n       (scr_coord_val, scr_coord_val, const char*, control_alignment_t , const PIXVAL, bool, sint32  CLIP_NUM_DEF_NOUSE);
+static scr_coord_val  simgraph0_draw_multiline_text       (scr_coord_val, scr_coord_val, const char *, PIXVAL);
+static void           simgraph0_draw_text_ellipsis_shadowed(scr_rect, const char *, int, PIXVAL, bool, bool, PIXVAL);
+static void           simgraph0_draw_text_outlined         (scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int);
+static void           simgraph0_draw_text_shadowed         (scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int);
+static void           simgraph0_draw_box3d                 (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, bool);
+static void           simgraph0_draw_box3d_clipped         (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL);
+static void           simgraph0_draw_textbox3d_clipped     (scr_coord_val, scr_coord_val, FLAGGED_PIXVAL, FLAGGED_PIXVAL, const char *, int  CLIP_NUM_DEF_NOUSE);
+static void           simgraph0_draw_line                  (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL);
+static void           simgraph0_draw_line_dotted           (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL);
+static void           simgraph0_draw_empty_circle          (scr_coord_val, scr_coord_val, int, const PIXVAL);
+static void           simgraph0_draw_filled_circle         (scr_coord_val, scr_coord_val, int, const PIXVAL);
+static void           simgraph0_draw_bezier                (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, scr_coord_val, scr_coord_val);
+static void           simgraph0_draw_right_triangle        (scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, const bool);
+static bool           simgraph0_take_screenshot            (const scr_rect &);
+static void           simgraph0_draw_signal_direction      (scr_coord_val, scr_coord_val, uint8, uint8, PIXVAL, PIXVAL, bool, uint8);
+static void           simgraph0_set_clip_rect              (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF, bool fit);
+static clip_dimension simgraph0_get_clip_rect              (CLIP_NUM_DEF_NOUSE0);
+static void           simgraph0_push_clip_rect             (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE);
+static void           simgraph0_swap_clip_rect             (CLIP_NUM_DEF_NOUSE0);
+static void           simgraph0_pop_clip_rect              (CLIP_NUM_DEF_NOUSE0);
+
+#ifdef MULTI_THREAD
+static void           simgraph0_add_poly_clip              (int, int, int, int, int  CLIP_NUM_DEF_NOUSE);
+static void           simgraph0_clear_all_poly_clip        (const sint8);
+static void           simgraph0_activate_ribi_clip         (int  CLIP_NUM_DEF_NOUSE);
+#else
+static void           simgraph0_add_poly_clip              (int, int, int, int, int);
+static void           simgraph0_clear_all_poly_clip        ();
+static void           simgraph0_activate_ribi_clip         (int);
+#endif
+
+static void           simgraph0_set_light_color            (int light_idx, rgb888_t day_light, rgb888_t night_light);
+
+
+simgraph_t g_simgraph0 = {
+	.type = SIMGRAPH_TYPE_NULL,
+
+	.tile_raster_width         = 16, // zoomed
+	.base_tile_raster_width    = 16, // original
+	.current_tile_raster_width = 0,
+	.draw_normal               = NULL,
+	.draw_color                = NULL,
+	.draw_blend                = NULL,
+	.draw_alpha                = NULL,
+
+	.zoom_num = { 1 },
+	.zoom_den = { 0 },
+
+	.palette_lookup              = simgraph0_palette_lookup,
+	.palette_indexof             = simgraph0_palette_indexof,
+	.get_color_rgb               = simgraph0_get_color_rgb,
+	.env_t_rgb_to_system_colors  = simgraph0_env_t_rgb_to_system_colors,
+	.set_base_raster_width       = simgraph0_set_base_raster_width,
+	.zoom_factor_up              = simgraph0_zoom_factor_up,
+	.zoom_factor_down            = simgraph0_zoom_factor_down,
+	.init                        = simgraph0_init,
+	.is_display_init             = simgraph0_is_display_init,
+	.exit                        = simgraph0_exit,
+	.on_window_resized           = simgraph0_on_window_resized,
+	.load_font                   = simgraph0_load_font,
+	.get_image_count             = simgraph0_get_image_count,
+	.register_image              = simgraph0_register_image,
+	.free_all_images_above       = simgraph0_free_all_images_above,
+	.get_base_image_offset       = simgraph0_get_base_image_offset,
+	.get_image_offset            = simgraph0_get_image_offset,
+	.mark_img_dirty              = simgraph0_mark_img_dirty,
+	.mark_rect_dirty_wc          = simgraph0_mark_rect_dirty_wc,
+	.mark_rect_dirty_clip        = simgraph0_mark_rect_dirty_clip,
+	.mark_screen_dirty           = simgraph0_mark_screen_dirty,
+	.get_screen_size             = simgraph0_get_screen_size,
+	.set_screen_height           = simgraph0_set_screen_height,
+	.set_screen_actual_width     = simgraph0_set_screen_actual_width,
+	.get_best_matching_size      = simgraph0_get_best_matching_size,
+	.fit_img_to_width            = simgraph0_fit_img_to_width,
+	.set_daynight_level          = simgraph0_set_daynight_level,
+	.move_scroll_band            = simgraph0_move_scroll_band,
+	.set_player_color_scheme     = simgraph0_set_player_color_scheme,
+	.set_image_procs             = simgraph0_set_image_procs,
+	.draw_img_aligned            = simgraph0_draw_img_aligned,
+	.draw_img_aux                = simgraph0_draw_img_aux,
+	.draw_rezoomed_img_blend     = simgraph0_draw_rezoomed_img_blend,
+	.draw_rezoomed_img_alpha     = simgraph0_draw_rezoomed_img_alpha,
+	.draw_color_img              = simgraph0_draw_color_img,
+	.draw_base_img               = simgraph0_draw_base_img,
+	.draw_base_img_blend         = simgraph0_draw_base_img_blend,
+	.draw_base_img_alpha         = simgraph0_draw_base_img_alpha,
+	.draw_stretch_map            = simgraph0_draw_stretch_map,
+	.draw_stretch_map_blend      = simgraph0_draw_stretch_map_blend,
+	.blend_colors                = simgraph0_blend_colors,
+	.tint_rect                   = simgraph0_tint_rect,
+	.draw_rect                   = simgraph0_draw_rect,
+	.draw_rect_clipped           = simgraph0_draw_rect_clipped,
+	.draw_rounded_rect_clipped   = simgraph0_draw_rounded_rect_clipped,
+	.draw_vline_clipped          = simgraph0_draw_vline_clipped,
+	.flush_framebuffer           = simgraph0_flush_framebuffer,
+	.set_cursor_visible          = simgraph0_set_cursor_visible,
+	.set_default_cursor          = simgraph0_set_default_cursor,
+	.set_show_load_cursor        = simgraph0_set_show_load_cursor,
+	.draw_array                  = simgraph0_draw_array,
+	.font_has_character          = simgraph0_font_has_character,
+	.get_char_width              = simgraph0_get_char_width,
+	.get_number_width            = simgraph0_get_number_width,
+	.get_next_char_with_metrics  = simgraph0_get_next_char_with_metrics,
+	.get_prev_char_with_metrics  = simgraph0_get_prev_char_with_metrics,
+	.calc_text_width_n           = simgraph0_calc_text_width_n,
+	.calc_multiline_text_size    = simgraph0_calc_multiline_text_size,
+	.calc_text_index_for_width   = simgraph0_calc_text_index_for_width,
+	.draw_text_clipped_n         = simgraph0_draw_text_clipped_n,
+	.draw_multiline_text         = simgraph0_draw_multiline_text,
+	.draw_text_ellipsis_shadowed = simgraph0_draw_text_ellipsis_shadowed,
+	.draw_text_outlined          = simgraph0_draw_text_outlined,
+	.draw_text_shadowed          = simgraph0_draw_text_shadowed,
+	.draw_box3d                  = simgraph0_draw_box3d,
+	.draw_box3d_clipped          = simgraph0_draw_box3d_clipped,
+	.draw_textbox3d_clipped      = simgraph0_draw_textbox3d_clipped,
+	.draw_line                   = simgraph0_draw_line,
+	.draw_line_dotted            = simgraph0_draw_line_dotted,
+	.draw_empty_circle           = simgraph0_draw_empty_circle,
+	.draw_filled_circle          = simgraph0_draw_filled_circle,
+	.draw_bezier                 = simgraph0_draw_bezier,
+	.draw_right_triangle         = simgraph0_draw_right_triangle,
+	.draw_signal_direction       = simgraph0_draw_signal_direction,
+	.take_screenshot             = simgraph0_take_screenshot,
+	.set_clip_rect               = simgraph0_set_clip_rect,
+	.get_clip_rect               = simgraph0_get_clip_rect,
+	.push_clip_rect              = simgraph0_push_clip_rect,
+	.swap_clip_rect              = simgraph0_swap_clip_rect,
+	.pop_clip_rect               = simgraph0_pop_clip_rect,
+	.add_poly_clip               = simgraph0_add_poly_clip,
+	.clear_all_poly_clip         = simgraph0_clear_all_poly_clip,
+	.activate_ribi_clip          = simgraph0_activate_ribi_clip,
+
+	.set_light_color             = simgraph0_set_light_color
+};
+
+
+static PIXVAL simgraph0_palette_lookup(PIXVAL idx)
 {
 	return idx;
 }
 
-PIXVAL color_rgb_to_idx(PIXVAL color)
+static PIXVAL simgraph0_palette_indexof(PIXVAL color)
 {
 	return color;
 }
 
 
-rgb888_t get_color_rgb(uint8)
+static rgb888_t simgraph0_get_color_rgb(uint8)
 {
 	return {0,0,0};
 }
 
-void env_t_rgb_to_system_colors()
+static void simgraph0_env_t_rgb_to_system_colors()
 {
 }
 
-scr_coord_val display_set_base_raster_width(scr_coord_val)
+static scr_coord_val simgraph0_set_base_raster_width(scr_coord_val)
 {
 	return 0;
 }
@@ -44,321 +238,301 @@ void set_zoom_factor(int)
 {
 }
 
-int zoom_factor_up()
+static int simgraph0_zoom_factor_up()
 {
 	return false;
 }
 
-int zoom_factor_down()
+static int simgraph0_zoom_factor_down()
 {
 	return false;
 }
 
-void mark_rect_dirty_wc(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val)
+static void simgraph0_mark_rect_dirty_wc(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val)
 {
 }
 
-void mark_rect_dirty_clip(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_mark_rect_dirty_clip(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void mark_screen_dirty()
+static void simgraph0_mark_screen_dirty()
 {
 }
 
-void display_mark_img_dirty(image_id, scr_coord_val, scr_coord_val)
+static void simgraph0_mark_img_dirty(image_id, scr_coord_val, scr_coord_val)
 {
 }
 
-bool display_load_font(const char*, bool)
+static bool simgraph0_load_font(const char *, bool)
 {
 	return true;
 }
 
-scr_coord_val display_get_width()
+static scr_size simgraph0_get_screen_size()
 {
-	return 0;
+	return scr_size{ 0,0 };
 }
 
-scr_coord_val display_get_height()
+static void simgraph0_set_screen_height(scr_coord_val)
 {
-	return 0;
 }
 
-void display_set_height(scr_coord_val)
+static void simgraph0_set_screen_actual_width(scr_coord_val)
 {
 }
 
-void display_set_actual_width(scr_coord_val)
+static void simgraph0_set_daynight_level(int)
 {
 }
 
-void display_day_night_shift(int)
+static void simgraph0_set_player_color_scheme(const int, const uint8, const uint8)
 {
 }
 
-void display_set_player_color_scheme(const int, const uint8, const uint8)
-{
-}
 
-void register_image(image_t* image)
+static void simgraph0_register_image(image_t* image)
 {
 	image->imageid = 1;
 }
 
-bool display_snapshot(const scr_rect &)
+
+static bool simgraph0_take_screenshot(const scr_rect &)
 {
 	return false;
 }
 
-void display_get_image_offset(image_id image, scr_coord_val *xoff, scr_coord_val *yoff, scr_coord_val *xw, scr_coord_val *yw)
+
+static scr_rect simgraph0_get_image_offset(image_id)
 {
-	if(  image < 2  ) {
-		// initialize offsets with dummy values
-		*xoff = 0;
-		*yoff = 0;
-		*xw   = 0;
-		*yw   = 0;
-	}
+	return scr_rect{ 0, 0, 0, 0 };
 }
 
-void display_get_base_image_offset(image_id image, scr_coord_val *xoff, scr_coord_val *yoff, scr_coord_val *xw, scr_coord_val *yw)
+
+static scr_rect simgraph0_get_base_image_offset(image_id)
 {
-	if(  image < 2  ) {
-		// initialize offsets with dummy values
-		*xoff = 0;
-		*yoff = 0;
-		*xw   = 0;
-		*yw   = 0;
-	}
+	return scr_rect{ 0, 0, 0, 0 };
 }
 
-clip_dimension display_get_clip_wh(CLIP_NUM_DEF_NOUSE0)
+
+static clip_dimension simgraph0_get_clip_rect(CLIP_NUM_DEF_NOUSE0)
 {
 	clip_dimension clip_rect;
-	clip_rect.x = 0;
+	clip_rect.x  = 0;
 	clip_rect.xx = 0;
-	clip_rect.w = 0;
-	clip_rect.y = 0;
+	clip_rect.w  = 0;
+	clip_rect.y  = 0;
 	clip_rect.yy = 0;
-	clip_rect.h = 0;
+	clip_rect.h  = 0;
 	return clip_rect;
 }
 
-void display_set_clip_wh(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE, bool)
+static void simgraph0_set_clip_rect(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE, bool)
 {
 }
 
-void display_push_clip_wh(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_push_clip_rect(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_swap_clip_wh(CLIP_NUM_DEF_NOUSE0)
+static void simgraph0_swap_clip_rect(CLIP_NUM_DEF_NOUSE0)
 {
 }
 
-void display_pop_clip_wh(CLIP_NUM_DEF_NOUSE0)
+static void simgraph0_pop_clip_rect(CLIP_NUM_DEF_NOUSE0)
 {
 }
 
-void display_scroll_band(const scr_coord_val, const scr_coord_val, const scr_coord_val)
+static void simgraph0_move_scroll_band(scr_coord_val, scr_coord_val, scr_coord_val)
 {
 }
 
-void display_img_aux(const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_img_aux(const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_color_img(const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_color_img(const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-scr_size display_get_best_matching_size(const image_id, sint16)
+static scr_size simgraph0_get_best_matching_size(const image_id, sint16)
 {
 	return scr_size(32, 32); // default size
 }
 
 
-void display_base_img(const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_base_img(const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_fit_img_to_width( const image_id, sint16)
+static void simgraph0_fit_img_to_width( const image_id, sint16)
 {
 }
 
-void display_img_stretch( const stretch_map_t &, scr_rect)
+static void simgraph0_draw_stretch_map(const stretch_map_t &, scr_rect)
 {
 }
 
-void display_img_stretch_blend( const stretch_map_t &, scr_rect, FLAGGED_PIXVAL)
+static void simgraph0_draw_stretch_map_blend( const stretch_map_t &, scr_rect, FLAGGED_PIXVAL)
 {
 }
 
-void display_rezoomed_img_blend(const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_rezoomed_img_blend(const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_rezoomed_img_alpha(const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_rezoomed_img_alpha(const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_base_img_blend(const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_base_img_blend(const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_base_img_alpha(const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_base_img_alpha(const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-// variables for storing currently used image procedure set and tile raster width
-display_image_proc display_normal = display_base_img;
-display_image_proc display_color = display_base_img;
-display_blend_proc display_blend = display_base_img_blend;
-display_alpha_proc display_alpha = display_base_img_alpha;
-
-signed short current_tile_raster_width = 0;
-
-PIXVAL display_blend_colors(PIXVAL, PIXVAL, int)
+static PIXVAL simgraph0_blend_colors(PIXVAL, PIXVAL, int)
 {
 	return 0;
 }
 
 
-void display_blend_wh_rgb(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, int )
+static void simgraph0_tint_rect(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, int)
 {
 }
 
 
-void display_fillbox_wh_rgb(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool )
+static void simgraph0_draw_rect(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool)
 {
 }
 
 
-void display_fillbox_wh_clip_rgb(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_rect_clipped(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_vline_wh_clip_rgb(scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_vline_clipped(scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void display_filled_roundbox_clip(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool)
+static void simgraph0_draw_rounded_rect_clipped(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, bool)
 {
 }
 
-void display_array_wh(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL *)
+static void simgraph0_draw_array(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL *)
 {
 }
 
-scr_coord_val display_get_char_width(utf32)
+static scr_coord_val simgraph0_get_char_width(utf32)
 {
 	return 0;
 }
 
-scr_coord_val display_get_number_width()
+static scr_coord_val simgraph0_get_number_width()
 {
 	return 0;
 }
 
-utf32 get_next_char_with_metrics(const char* &, unsigned char &, unsigned char &)
+static utf32 simgraph0_get_next_char_with_metrics(const char* &, unsigned char &, unsigned char &)
 {
 	return 0;
 }
 
-utf32 get_prev_char_with_metrics(const char* &, const char *const, unsigned char &, unsigned char &)
+static utf32 simgraph0_get_prev_char_with_metrics(const char* &, const char *const, unsigned char &, unsigned char &)
 {
 	return 0;
 }
 
-bool has_character( utf16 )
+static bool simgraph0_font_has_character( utf16 )
 {
 	return false;
 }
 
-size_t display_fit_proportional(const char *, scr_coord_val)
+static size_t simgraph0_calc_text_index_for_width(const char *, scr_coord_val)
 {
 	return 0;
 }
 
-scr_coord_val display_calc_proportional_string_len_width(const char*, size_t)
+static scr_coord_val simgraph0_calc_text_width_n(const char*, size_t)
 {
 	return 0;
 }
 
 
-void display_calc_proportional_multiline_string_len_width( int &xw, int &yh, const char *)
+static scr_size simgraph0_calc_multiline_text_size(const char *)
 {
-	xw = yh = 0;;
+	return { 0, 0 };
 }
 
 
-scr_coord_val display_text_proportional_len_clip_rgb(scr_coord_val, scr_coord_val, const char*, control_alignment_t , const PIXVAL, bool, sint32  CLIP_NUM_DEF_NOUSE)
+static scr_coord_val simgraph0_draw_text_clipped_n(scr_coord_val, scr_coord_val, const char*, control_alignment_t , const PIXVAL, bool, sint32  CLIP_NUM_DEF_NOUSE)
 {
 	return 0;
 }
 
-void display_outline_proportional_rgb(scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int, sint32)
+static void simgraph0_draw_text_outlined(scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int)
 {
 }
 
-void display_shadow_proportional_rgb(scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int, sint32)
+static void simgraph0_draw_text_shadowed(scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int)
 {
 }
 
-void display_ddd_box_rgb(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, bool)
+static void simgraph0_draw_box3d(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, bool)
 {
 }
 
-void display_ddd_box_clip_rgb(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL)
+static void simgraph0_draw_box3d_clipped(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL)
 {
 }
 
-void display_ddd_proportional_clip(scr_coord_val, scr_coord_val, FLAGGED_PIXVAL, FLAGGED_PIXVAL, const char *, int  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_draw_textbox3d_clipped(scr_coord_val, scr_coord_val, FLAGGED_PIXVAL, FLAGGED_PIXVAL, const char *, int  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-scr_coord_val display_multiline_text_rgb(scr_coord_val, scr_coord_val, const char *, PIXVAL)
+static scr_coord_val simgraph0_draw_multiline_text(scr_coord_val, scr_coord_val, const char *, PIXVAL)
 {
 	return 0;
 }
 
-void display_flush_buffer()
+static void simgraph0_flush_framebuffer()
 {
 }
 
-void display_show_pointer(int)
+static void simgraph0_set_cursor_visible(bool)
 {
 }
 
-void display_set_pointer(int)
+static void simgraph0_set_default_cursor(int)
 {
 }
 
-void display_show_load_pointer(int)
+static void simgraph0_set_show_load_cursor(bool)
 {
 }
 
-bool simgraph_init(scr_size, sint16)
+static bool simgraph0_init(scr_size, sint16)
 {
 	return true;
 }
 
-bool is_display_init()
+static bool simgraph0_is_display_init()
 {
 	return false;
 }
 
-void display_free_all_images_above(image_id)
+static void simgraph0_free_all_images_above(image_id)
 {
 }
 
-void simgraph_exit()
+static void simgraph0_exit()
 {
 	dr_os_close();
 }
 
-void simgraph_resize(scr_size)
+static void simgraph0_on_window_resized(scr_size)
 {
 }
 
@@ -366,70 +540,94 @@ void display_snapshot()
 {
 }
 
-void display_direct_line_rgb(const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const PIXVAL)
+static void simgraph0_draw_line(const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const PIXVAL)
 {
 }
 
-void display_direct_line_dotted_rgb(const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const PIXVAL)
+static void simgraph0_draw_line_dotted(const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const scr_coord_val, const PIXVAL)
 {
 }
 
-void display_circle_rgb( scr_coord_val, scr_coord_val, int, const PIXVAL )
+static void simgraph0_draw_empty_circle(scr_coord_val, scr_coord_val, int, const PIXVAL)
 {
 }
 
-void display_filled_circle_rgb( scr_coord_val, scr_coord_val, int, const PIXVAL )
+static void simgraph0_draw_filled_circle(scr_coord_val, scr_coord_val, int, const PIXVAL)
 {
 }
 
-void draw_bezier_rgb(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, scr_coord_val, scr_coord_val )
+static void simgraph0_draw_bezier(scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, scr_coord_val, scr_coord_val)
 {
 }
 
-void display_right_triangle_rgb(scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, const bool)
+static void simgraph0_draw_right_triangle(scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, const bool)
 {
 }
 
-void display_signal_direction_rgb( scr_coord_val, scr_coord_val, uint8, uint8, PIXVAL, PIXVAL, bool, uint8 )
+static void simgraph0_draw_signal_direction( scr_coord_val, scr_coord_val, uint8, uint8, PIXVAL, PIXVAL, bool, uint8 )
 {
 }
 
 
-void display_img_aligned( const image_id, scr_rect, int, bool )
+static void simgraph0_draw_img_aligned(const image_id, scr_rect, int, bool)
 {
 }
 
-void display_proportional_ellipsis_rgb( scr_rect, const char *, int, PIXVAL, bool, bool, PIXVAL)
+static void simgraph0_draw_text_ellipsis_shadowed( scr_rect, const char *, int, PIXVAL, bool, bool, PIXVAL)
 {
 }
 
-image_id get_image_count()
+static image_id simgraph0_get_image_count()
 {
 	return 0;
 }
 
 #ifdef MULTI_THREAD
-void add_poly_clip(int, int, int, int, int  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_add_poly_clip(int, int, int, int, int  CLIP_NUM_DEF_NOUSE)
 {
 }
 
-void clear_all_poly_clip(const sint8)
+static void simgraph0_clear_all_poly_clip(const sint8)
 {
 }
 
-void activate_ribi_clip(int  CLIP_NUM_DEF_NOUSE)
+static void simgraph0_activate_ribi_clip(int  CLIP_NUM_DEF_NOUSE)
 {
 }
 #else
-void add_poly_clip(int, int, int, int, int)
+static void simgraph0_add_poly_clip(int, int, int, int, int)
 {
 }
 
-void clear_all_poly_clip()
+static void simgraph0_clear_all_poly_clip()
 {
 }
 
-void activate_ribi_clip(int)
+static void simgraph0_activate_ribi_clip(int)
 {
 }
 #endif
+
+
+static void simgraph0_set_image_procs(bool is_global)
+{
+	if(  is_global  ) {
+		g_simgraph0.draw_normal = simgraph0_draw_img_aux;
+		g_simgraph0.draw_color  = simgraph0_draw_color_img;
+		g_simgraph0.draw_blend  = simgraph0_draw_rezoomed_img_blend;
+		g_simgraph0.draw_alpha  = simgraph0_draw_rezoomed_img_alpha;
+		g_simgraph0.current_tile_raster_width = g_simgraph0.tile_raster_width;
+	}
+	else {
+		g_simgraph0.draw_normal = simgraph0_draw_base_img;
+		g_simgraph0.draw_color  = simgraph0_draw_base_img;
+		g_simgraph0.draw_blend  = simgraph0_draw_base_img_blend;
+		g_simgraph0.draw_alpha  = simgraph0_draw_base_img_alpha;
+		g_simgraph0.current_tile_raster_width = g_simgraph->get_base_tile_raster_width();
+	}
+}
+
+
+void simgraph0_set_light_color(int, rgb888_t, rgb888_t)
+{
+}
diff --git a/src/simutrans/display/simgraph0.h b/src/simutrans/display/simgraph0.h
new file mode 100644
index 000000000..140314f8a
--- /dev/null
+++ b/src/simutrans/display/simgraph0.h
@@ -0,0 +1,16 @@
+/*
+ * This file is part of the Simutrans project under the Artistic License.
+ * (see LICENSE.txt)
+ */
+
+#ifndef DISPLAY_SIMGRAPH0_H
+#define DISPLAY_SIMGRAPH0_H
+
+
+#include "simgraph.h"
+
+
+extern const simgraph_t g_simgraph0;
+
+
+#endif
diff --git a/src/simutrans/display/simgraph16.cc b/src/simutrans/display/simgraph16.cc
index f37ac6ad9..fdc2d1f90 100644
--- a/src/simutrans/display/simgraph16.cc
+++ b/src/simutrans/display/simgraph16.cc
@@ -11,15 +11,6 @@
 
 #include "../simtypes.h"
 
- /*
-  * Zoom factor (must be done before including simgraph)
-  */
-#define MAX_ZOOM_FACTOR (9)
-#define ZOOM_NEUTRAL (3)
-uint32 zoom_factor = ZOOM_NEUTRAL;
-extern const sint32 zoom_num[MAX_ZOOM_FACTOR + 1] = { 2, 3, 4, 1, 3, 5, 1, 3, 1, 1 };
-extern const sint32 zoom_den[MAX_ZOOM_FACTOR + 1] = { 1, 2, 3, 1, 4, 8, 2, 8, 4, 8 };
-
 #include "../macros.h"
 #include "font.h"
 #include "../pathes.h"
@@ -260,8 +251,6 @@ clipping_info_t clips;
 static font_t default_font;
 
 // needed for resizing gui
-int default_font_ascent = 0;
-int default_font_linespace = 0;
 static int default_font_numberwidth = 0;
 
 
@@ -431,7 +420,7 @@ static int night_shift = -1;
 /*
  * special colors during daytime
  */
-rgb888_t display_day_lights[LIGHT_COUNT] = {
+static rgb888_t display_day_lights[LIGHT_COUNT] = {
 	{ 0x57, 0x65, 0x6F }, // Dark windows, lit yellowish at night
 	{ 0x7F, 0x9B, 0xF1 }, // Lighter windows, lit blueish at night
 	{ 0xFF, 0xFF, 0x53 }, // Yellow light
@@ -453,7 +442,7 @@ rgb888_t display_day_lights[LIGHT_COUNT] = {
 /*
  * special colors during nighttime
  */
-rgb888_t display_night_lights[LIGHT_COUNT] = {
+static rgb888_t display_night_lights[LIGHT_COUNT] = {
 	{ 0xD3, 0xC3, 0x80 }, // Dark windows, lit yellowish at night
 	{ 0x80, 0xC3, 0xD3 }, // Lighter windows, lit blueish at night
 	{ 0xFF, 0xFF, 0x53 }, // Yellow light
@@ -506,19 +495,199 @@ static const rgb888_t special_pal[SPECIAL_COLOR_COUNT] =
 	{  41,  41,  54 }, {  60,  45,  70 }, {  75,  62, 108 }, {  95,  77, 136 }, { 113, 105, 150 }, { 135, 120, 176 }, { 165, 145, 218 }, { 198, 191, 232 }
 };
 
+//
+// fwd decls
+//
+
+static PIXVAL        simgraph16_palette_lookup            (PIXVAL idx);
+static PIXVAL        simgraph16_palette_indexof           (PIXVAL color);
+static void          simgraph16_env_t_rgb_to_system_colors();
+static rgb888_t      simgraph16_get_color_rgb             (uint8 idx);
+static scr_coord_val simgraph16_set_base_raster_width     (scr_coord_val new_raster);
+static int           simgraph16_zoom_factor_up            ();
+static int           simgraph16_zoom_factor_down          ();
+static bool          simgraph16_init                      (scr_size window_size, sint16 full_screen);
+static bool          simgraph16_is_display_init           ();
+static void          simgraph16_exit                      ();
+static void          simgraph16_on_window_resized         (scr_size new_window_size);
+static bool          simgraph16_load_font                 (const char *fname, bool reload);
+static image_id      simgraph16_get_image_count           ();
+static void          simgraph16_register_image            (image_t *image_in);
+static void          simgraph16_free_all_images_above     (image_id above );
+static scr_rect      simgraph16_get_base_image_offset     (image_id image);
+static scr_rect      simgraph16_get_image_offset          (image_id image);
+static void          simgraph16_mark_img_dirty            (image_id image, scr_coord_val xp, scr_coord_val yp);
+static void          simgraph16_mark_rect_dirty_wc        (scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2);
+static void          simgraph16_mark_rect_dirty_clip      (scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2  CLIP_NUM_DEF);
+static void          simgraph16_mark_screen_dirty         ();
+static scr_size      simgraph16_get_screen_size           ();
+static void          simgraph16_set_screen_actual_width   (scr_coord_val w);
+static void          simgraph16_set_screen_height         (scr_coord_val const h);
+static scr_size      simgraph16_get_best_matching_size    (const image_id n, sint16 zoom_percent);
+static void          simgraph16_fit_img_to_width          (const image_id n, sint16 new_w);
+static void          simgraph16_set_daynight_level        (int night);
+static void          simgraph16_move_scroll_band          (scr_coord_val start_y, scr_coord_val x_offset, scr_coord_val h);
+static void          simgraph16_set_player_color_scheme   (const int player, const uint8 col1, const uint8 col2);
+static void          simgraph16_draw_img_aligned          (const image_id n, scr_rect area, int align, const bool dirty);
+static void          simgraph16_set_image_procs           (bool is_global);
+static void          simgraph16_draw_img_aux              (const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_rezoomed_img_blend   (const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_rezoomed_img_alpha   (const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_color_img            (const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_base_img             (const image_id, scr_coord_val, scr_coord_val, const sint8, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_base_img_blend       (const image_id, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, const bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_base_img_alpha       (const image_id, const image_id, const unsigned, scr_coord_val, scr_coord_val, const sint8, const FLAGGED_PIXVAL, const bool, bool  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_stretch_map          (const stretch_map_t &imag, scr_rect area);
+static void          simgraph16_draw_stretch_map_blend    (const stretch_map_t &imag, scr_rect area, FLAGGED_PIXVAL color);
+static PIXVAL        simgraph16_blend_colors              (PIXVAL background, PIXVAL foreground, int percent_blend);
+static void          simgraph16_tint_rect                 (scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL colval, int opacity);
+static void          simgraph16_draw_rect                 (scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty);
+static void          simgraph16_draw_rect_clipped         (scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty  CLIP_NUM_DEF);
+static void          simgraph16_draw_rounded_rect_clipped (scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty);
+static void          simgraph16_draw_vline_clipped        (scr_coord_val xp, scr_coord_val yp, scr_coord_val h, PIXVAL color, bool dirty  CLIP_NUM_DEF);
+static void          simgraph16_flush_framebuffer         ();
+static void          simgraph16_set_cursor_visible        (bool show);
+static void          simgraph16_set_default_cursor        (int cursor_id);
+static void          simgraph16_set_show_load_cursor      (bool show);
+static void          simgraph16_draw_array                (scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, const PIXVAL *arr);
+static scr_coord_val simgraph16_calc_text_width_n         (const char *text, size_t len);
+static scr_size      simgraph16_calc_multiline_text_size  (const char *text);
+static size_t        simgraph16_calc_text_index_for_width (const char *, scr_coord_val);
+static bool          simgraph16_font_has_character        (utf16 char_code);
+static utf32         simgraph16_get_next_char_with_metrics(const char* &text, unsigned char &byte_length, unsigned char &pixel_width);
+static utf32         simgraph16_get_prev_char_with_metrics(const char* &text, const char *const text_start, unsigned char &byte_length, unsigned char &pixel_width);
+static scr_coord_val simgraph16_get_char_width            (utf32 c);
+static scr_coord_val simgraph16_get_number_width          ();
+static scr_coord_val simgraph16_draw_text_clipped_n       (scr_coord_val x, scr_coord_val y, const char* txt, control_alignment_t flags, const PIXVAL color, bool dirty, sint32 len  CLIP_NUM_DEF);
+static scr_coord_val simgraph16_draw_multiline_text       (scr_coord_val, scr_coord_val, const char *, PIXVAL);
+static void          simgraph16_draw_text_ellipsis_shadowed(scr_rect, const char *, int, PIXVAL, bool, bool, PIXVAL);
+static void          simgraph16_draw_text_outlined         (scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int);
+static void          simgraph16_draw_text_shadowed         (scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, const char *, int);
+static void          simgraph16_draw_box3d                 (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL, bool);
+static void          simgraph16_draw_box3d_clipped         (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL, PIXVAL);
+static void          simgraph16_draw_textbox3d_clipped     (scr_coord_val, scr_coord_val, FLAGGED_PIXVAL, FLAGGED_PIXVAL, const char *, int  CLIP_NUM_DEF_NOUSE);
+static void          simgraph16_draw_line                  (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL);
+static void          simgraph16_draw_line_dotted           (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, PIXVAL);
+static void          simgraph16_draw_empty_circle          (scr_coord_val, scr_coord_val, int, const PIXVAL);
+static void          simgraph16_draw_filled_circle         (scr_coord_val, scr_coord_val, int, const PIXVAL);
+static void          simgraph16_draw_bezier                (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, scr_coord_val, scr_coord_val);
+static void          simgraph16_draw_right_triangle        (scr_coord_val, scr_coord_val, scr_coord_val, const PIXVAL, const bool);
+static bool          simgraph16_take_screenshot            (const scr_rect &);
+static void          simgraph16_draw_signal_direction      (scr_coord_val, scr_coord_val, uint8, uint8, PIXVAL, PIXVAL, bool, uint8);
+static void          simgraph16_set_clip_rect              (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF, bool fit);
+static clip_dimension simgraph16_get_clip_rect              (CLIP_NUM_DEF_NOUSE0);
+static void           simgraph16_push_clip_rect             (scr_coord_val, scr_coord_val, scr_coord_val, scr_coord_val  CLIP_NUM_DEF_NOUSE);
+static void           simgraph16_swap_clip_rect             (CLIP_NUM_DEF_NOUSE0);
+static void           simgraph16_pop_clip_rect              (CLIP_NUM_DEF_NOUSE0);
+static void           simgraph16_set_light_color            (int color_idx, rgb888_t day_colour, rgb888_t night_colour);
+static void           simgraph16_add_poly_clip              (int x0,int y0, int x1, int y1, int ribi  CLIP_NUM_DEF);
+static void           simgraph16_clear_all_poly_clip        (CLIP_NUM_DEF0);
+static void           simgraph16_activate_ribi_clip         (int ribi  CLIP_NUM_DEF);
+
+
+simgraph_t g_simgraph16 = {
+	.type                      = SIMGRAPH_TYPE_SOFTWARE,
+
+
+	.tile_raster_width         = 16, // zoomed
+	.base_tile_raster_width    = 16, // original
+	.current_tile_raster_width = 0,
+	.draw_normal               = NULL,
+	.draw_color                = NULL,
+	.draw_blend                = NULL,
+	.draw_alpha                = NULL,
+
+	.zoom_num = { 2, 3, 4, 1, 3, 5, 1, 3, 1, 1 },
+	.zoom_den = { 1, 2, 3, 1, 4, 8, 2, 8, 4, 8 },
+
+	.palette_lookup             = simgraph16_palette_lookup,
+	.palette_indexof            = simgraph16_palette_indexof,
+	.get_color_rgb              = simgraph16_get_color_rgb,
+	.env_t_rgb_to_system_colors = simgraph16_env_t_rgb_to_system_colors,
+
+	.set_base_raster_width     = simgraph16_set_base_raster_width,
+	.zoom_factor_up            = simgraph16_zoom_factor_up,
+	.zoom_factor_down          = simgraph16_zoom_factor_down,
+	.init                      = simgraph16_init,
+	.is_display_init           = simgraph16_is_display_init,
+	.exit                      = simgraph16_exit,
+	.on_window_resized         = simgraph16_on_window_resized,
+	.load_font                 = simgraph16_load_font,
+	.get_image_count           = simgraph16_get_image_count,
+	.register_image            = simgraph16_register_image,
+	.free_all_images_above     = simgraph16_free_all_images_above,
+	.get_base_image_offset     = simgraph16_get_base_image_offset,
+	.get_image_offset          = simgraph16_get_image_offset,
+	.mark_img_dirty            = simgraph16_mark_img_dirty,
+	.mark_rect_dirty_wc        = simgraph16_mark_rect_dirty_wc,
+	.mark_rect_dirty_clip      = simgraph16_mark_rect_dirty_clip,
+	.mark_screen_dirty         = simgraph16_mark_screen_dirty,
+	.get_screen_size           = simgraph16_get_screen_size,
+	.set_screen_height         = simgraph16_set_screen_height,
+	.set_screen_actual_width   = simgraph16_set_screen_actual_width,
+	.get_best_matching_size    = simgraph16_get_best_matching_size,
+	.fit_img_to_width          = simgraph16_fit_img_to_width,
+	.set_daynight_level        = simgraph16_set_daynight_level,
+	.move_scroll_band          = simgraph16_move_scroll_band,
+	.set_player_color_scheme   = simgraph16_set_player_color_scheme,
+	.set_image_procs           = simgraph16_set_image_procs,
+	.draw_img_aligned          = simgraph16_draw_img_aligned,
+	.draw_img_aux              = simgraph16_draw_img_aux,
+	.draw_rezoomed_img_blend   = simgraph16_draw_rezoomed_img_blend,
+	.draw_rezoomed_img_alpha   = simgraph16_draw_rezoomed_img_alpha,
+	.draw_color_img            = simgraph16_draw_color_img,
+	.draw_base_img             = simgraph16_draw_base_img,
+	.draw_base_img_blend       = simgraph16_draw_base_img_blend,
+	.draw_base_img_alpha       = simgraph16_draw_base_img_alpha,
+	.draw_stretch_map          = simgraph16_draw_stretch_map,
+	.draw_stretch_map_blend    = simgraph16_draw_stretch_map_blend,
+	.blend_colors              = simgraph16_blend_colors,
+	.tint_rect                 = simgraph16_tint_rect,
+	.draw_rect                 = simgraph16_draw_rect,
+	.draw_rect_clipped         = simgraph16_draw_rect_clipped,
+	.draw_rounded_rect_clipped = simgraph16_draw_rounded_rect_clipped,
+	.draw_vline_clipped        = simgraph16_draw_vline_clipped,
+	.flush_framebuffer         = simgraph16_flush_framebuffer,
+	.set_cursor_visible        = simgraph16_set_cursor_visible,
+	.set_default_cursor        = simgraph16_set_default_cursor,
+	.set_show_load_cursor      = simgraph16_set_show_load_cursor,
+	.draw_array                = simgraph16_draw_array,
+	.font_has_character          = simgraph16_font_has_character,
+	.get_char_width              = simgraph16_get_char_width,
+	.get_number_width            = simgraph16_get_number_width,
+	.get_next_char_with_metrics  = simgraph16_get_next_char_with_metrics,
+	.get_prev_char_with_metrics  = simgraph16_get_prev_char_with_metrics,
+	.calc_text_width_n           = simgraph16_calc_text_width_n,
+	.calc_multiline_text_size    = simgraph16_calc_multiline_text_size,
+	.calc_text_index_for_width   = simgraph16_calc_text_index_for_width,
+	.draw_text_clipped_n         = simgraph16_draw_text_clipped_n,
+	.draw_multiline_text         = simgraph16_draw_multiline_text,
+	.draw_text_ellipsis_shadowed = simgraph16_draw_text_ellipsis_shadowed,
+	.draw_text_outlined          = simgraph16_draw_text_outlined,
+	.draw_text_shadowed          = simgraph16_draw_text_shadowed,
+	.draw_box3d                  = simgraph16_draw_box3d,
+	.draw_box3d_clipped          = simgraph16_draw_box3d_clipped,
+	.draw_textbox3d_clipped      = simgraph16_draw_textbox3d_clipped,
+	.draw_line                   = simgraph16_draw_line,
+	.draw_line_dotted            = simgraph16_draw_line_dotted,
+	.draw_empty_circle           = simgraph16_draw_empty_circle,
+	.draw_filled_circle          = simgraph16_draw_filled_circle,
+	.draw_bezier                 = simgraph16_draw_bezier,
+	.draw_right_triangle         = simgraph16_draw_right_triangle,
+	.draw_signal_direction       = simgraph16_draw_signal_direction,
+	.take_screenshot             = simgraph16_take_screenshot,
+	.set_clip_rect               = simgraph16_set_clip_rect,
+	.get_clip_rect               = simgraph16_get_clip_rect,
+	.push_clip_rect              = simgraph16_push_clip_rect,
+	.swap_clip_rect              = simgraph16_swap_clip_rect,
+	.pop_clip_rect               = simgraph16_pop_clip_rect,
+	.add_poly_clip               = simgraph16_add_poly_clip,
+	.clear_all_poly_clip         = simgraph16_clear_all_poly_clip,
+	.activate_ribi_clip          = simgraph16_activate_ribi_clip,
+	.set_light_color             = simgraph16_set_light_color,
+};
 
-/*
- * tile raster width
- */
-scr_coord_val tile_raster_width = 16;      // zoomed
-scr_coord_val base_tile_raster_width = 16; // original
-
-// variables for storing currently used image procedure set and tile raster width
-display_image_proc display_normal = NULL;
-display_image_proc display_color = NULL;
-display_blend_proc display_blend = NULL;
-display_alpha_proc display_alpha = NULL;
-signed short current_tile_raster_width = 0;
+static uint32 zoom_factor = ZOOM_NEUTRAL;
 
 
 static inline rgb888_t pixval_to_rgb888(PIXVAL colour)
@@ -557,7 +726,7 @@ static inline PIXVAL pixval_to_rgb343(PIXVAL rgb)
 /*
  * Gets a colour index and returns RGB888
  */
-rgb888_t get_color_rgb(uint8 idx)
+static rgb888_t simgraph16_get_color_rgb(uint8 idx)
 {
 	// special_pal has 224 rgb colors
 	if (idx < SPECIAL_COLOR_COUNT) {
@@ -576,12 +745,12 @@ rgb888_t get_color_rgb(uint8 idx)
 /**
  * Convert indexed colors to rgb and back
  */
-PIXVAL color_idx_to_rgb(PIXVAL idx)
+static PIXVAL simgraph16_palette_lookup(PIXVAL idx)
 {
 	return (specialcolormap_all_day[(idx)&0x00FF]);
 }
 
-PIXVAL color_rgb_to_idx(PIXVAL color)
+static PIXVAL simgraph16_palette_indexof(PIXVAL color)
 {
 	for(PIXVAL i=0; i<=0xff; i++) {
 		if (specialcolormap_all_day[i] == color) {
@@ -595,7 +764,7 @@ PIXVAL color_rgb_to_idx(PIXVAL color)
 /*
  * Convert env_t colours from RGB888 to the system format
  */
-void env_t_rgb_to_system_colors()
+static void simgraph16_env_t_rgb_to_system_colors()
 {
 	// get system colours for the default colours or settings.xml
 	env_t::default_window_title_color = get_system_color(env_t::default_window_title_color_rgb);
@@ -609,11 +778,11 @@ void env_t_rgb_to_system_colors()
 
 
 /* changes the raster width after loading */
-scr_coord_val display_set_base_raster_width(scr_coord_val new_raster)
+static scr_coord_val simgraph16_set_base_raster_width(scr_coord_val new_raster)
 {
-	scr_coord_val old = base_tile_raster_width;
-	base_tile_raster_width = new_raster;
-	tile_raster_width = (new_raster *  zoom_num[zoom_factor]) / zoom_den[zoom_factor];
+	scr_coord_val old = g_simgraph16.base_tile_raster_width;
+	g_simgraph16.base_tile_raster_width = new_raster;
+	g_simgraph16.tile_raster_width = (new_raster *  g_simgraph16.zoom_num[zoom_factor]) / g_simgraph16.zoom_den[zoom_factor];
 	return old;
 }
 
@@ -621,26 +790,20 @@ scr_coord_val display_set_base_raster_width(scr_coord_val new_raster)
 // ----------------------------------- clipping routines ------------------------------------------
 
 
-scr_coord_val display_get_width()
+static scr_size simgraph16_get_screen_size()
 {
-	return disp_actual_width;
+	return scr_size{ disp_actual_width, disp_height };
 }
 
 
 // only use, if you are really really sure!
-void display_set_actual_width(scr_coord_val w)
+static void simgraph16_set_screen_actual_width(scr_coord_val w)
 {
 	disp_actual_width = w;
 }
 
 
-scr_coord_val display_get_height()
-{
-	return disp_height;
-}
-
-
-void display_set_height(scr_coord_val const h)
+static void simgraph16_set_screen_height(scr_coord_val const h)
 {
 	disp_height = h;
 }
@@ -683,7 +846,7 @@ static bool clip_lr(scr_coord_val *x, scr_coord_val *w, const scr_coord_val left
 /**
  * Get the clipping rectangle dimensions
  */
-clip_dimension display_get_clip_wh(CLIP_NUM_DEF0)
+static clip_dimension simgraph16_get_clip_rect(CLIP_NUM_DEF0)
 {
 	return CR.clip_rect;
 }
@@ -698,7 +861,7 @@ clip_dimension display_get_clip_wh(CLIP_NUM_DEF0)
  *  clip.x < xp+w <= clip.xx
  * analogously for the y coordinate
  */
-void display_set_clip_wh(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF, bool fit)
+static void simgraph16_set_clip_rect(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF, bool fit)
 {
 	if (!fit) {
 		clip_wh( &x, &w, 0, disp_width);
@@ -717,17 +880,17 @@ void display_set_clip_wh(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_
 	CR.clip_rect.yy = y + h; // watch out, clips to scr_coord_val max
 }
 
-void display_push_clip_wh(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF)
+static void simgraph16_push_clip_rect(scr_coord_val x, scr_coord_val y, scr_coord_val w, scr_coord_val h  CLIP_NUM_DEF)
 {
 	assert(!CR.swap_active);
 	// save active clipping rectangle
 	CR.clip_rect_swap = CR.clip_rect;
 	// active rectangle provided by parameters
-	display_set_clip_wh(x, y, w, h  CLIP_NUM_PAR);
+	simgraph16_set_clip_rect(x, y, w, h  CLIP_NUM_PAR, false);
 	CR.swap_active = true;
 }
 
-void display_swap_clip_wh(CLIP_NUM_DEF0)
+static void simgraph16_swap_clip_rect(CLIP_NUM_DEF0)
 {
 	if (CR.swap_active) {
 		// swap clipping rectangles
@@ -737,7 +900,7 @@ void display_swap_clip_wh(CLIP_NUM_DEF0)
 	}
 }
 
-void display_pop_clip_wh(CLIP_NUM_DEF0)
+static void simgraph16_pop_clip_rect(CLIP_NUM_DEF0)
 {
 	if (CR.swap_active) {
 		// swap original clipping rectangle back
@@ -751,7 +914,7 @@ void display_pop_clip_wh(CLIP_NUM_DEF0)
  * with associated ribi
  * if ribi & 16 then non-convex clipping.
  */
-void add_poly_clip(int x0,int y0, int x1, int y1, int ribi  CLIP_NUM_DEF)
+static void simgraph16_add_poly_clip(int x0,int y0, int x1, int y1, int ribi  CLIP_NUM_DEF)
 {
 	if(  CR.number_of_clips < MAX_POLY_CLIPS  ) {
 		CR.poly_clips[CR.number_of_clips].clip_from_to( x0, y0, x1, y1, ribi&16 );
@@ -764,7 +927,7 @@ void add_poly_clip(int x0,int y0, int x1, int y1, int ribi  CLIP_NUM_DEF)
 /*
  * Clears all clipping lines
  */
-void clear_all_poly_clip(CLIP_NUM_DEF0)
+static void simgraph16_clear_all_poly_clip(CLIP_NUM_DEF0)
 {
 	CR.number_of_clips = 0;
 	CR.active_ribi = 15; // set all to active
@@ -775,7 +938,7 @@ void clear_all_poly_clip(CLIP_NUM_DEF0)
  * Activates clipping lines associated with ribi
  * ie if clip_ribi[i] & active_ribi
  */
-void activate_ribi_clip(int ribi  CLIP_NUM_DEF)
+static void simgraph16_activate_ribi_clip(int ribi  CLIP_NUM_DEF)
 {
 	CR.active_ribi = ribi;
 }
@@ -862,7 +1025,7 @@ static void mark_rect_dirty_nc(scr_coord_val x1, scr_coord_val y1, scr_coord_val
 /**
  * Mark tile as dirty, with clipping
  */
-void mark_rect_dirty_wc(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2)
+static void simgraph16_mark_rect_dirty_wc(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2)
 {
 	// inside display?
 	if(  x2 >= 0  &&  y2 >= 0  &&  x1 < disp_width  &&  y1 < disp_height  ) {
@@ -883,7 +1046,7 @@ void mark_rect_dirty_wc(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, sc
 }
 
 
-void mark_rect_dirty_clip(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2  CLIP_NUM_DEF)
+static void simgraph16_mark_rect_dirty_clip(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2, scr_coord_val y2  CLIP_NUM_DEF)
 {
 	// inside clip_rect?
 	if(  x2 >= CR.clip_rect.x  &&  y2 >= CR.clip_rect.y  &&  x1 < CR.clip_rect.xx  &&  y1 < CR.clip_rect.yy  ) {
@@ -908,7 +1071,7 @@ void mark_rect_dirty_clip(scr_coord_val x1, scr_coord_val y1, scr_coord_val x2,
  * Mark the whole screen as dirty.
  *
  */
-void mark_screen_dirty()
+static void simgraph16_mark_screen_dirty()
 {
 	memset( tile_dirty, 0xFFFFFFFF, sizeof(uint32) * tile_buffer_length );
 }
@@ -917,10 +1080,10 @@ void mark_screen_dirty()
 /**
  * the area of this image need update
  */
-void display_mark_img_dirty(image_id image, scr_coord_val xp, scr_coord_val yp)
+static void simgraph16_mark_img_dirty(image_id image, scr_coord_val xp, scr_coord_val yp)
 {
 	if(  image < anz_images  ) {
-		mark_rect_dirty_wc(
+		simgraph16_mark_rect_dirty_wc(
 			xp + images[image].x,
 			yp + images[image].y,
 			xp + images[image].x + images[image].w - 1,
@@ -953,16 +1116,16 @@ static void rezoom()
 void set_zoom_factor(int z)
 {
 	// do not zoom beyond 4 pixels
-	if(  (base_tile_raster_width * zoom_num[z]) / zoom_den[z] > 4  ) {
+	if(  (g_simgraph16.base_tile_raster_width * g_simgraph16.zoom_num[z]) / g_simgraph16.zoom_den[z] > 4  ) {
 		zoom_factor = z;
-		tile_raster_width = (base_tile_raster_width * zoom_num[zoom_factor]) / zoom_den[zoom_factor];
-		dbg->message("set_zoom_factor()", "Zoom level now %d (%i/%i)", zoom_factor, zoom_num[zoom_factor], zoom_den[zoom_factor] );
+		g_simgraph16.tile_raster_width = (g_simgraph16.base_tile_raster_width * g_simgraph16.zoom_num[zoom_factor]) / g_simgraph16.zoom_den[zoom_factor];
+		dbg->message("set_zoom_factor()", "Zoom level now %d (%i/%i)", zoom_factor, g_simgraph16.zoom_num[zoom_factor], g_simgraph16.zoom_den[zoom_factor] );
 		rezoom();
 	}
 }
 
 
-int zoom_factor_up()
+static int simgraph16_zoom_factor_up()
 {
 	// zoom out, if size permits
 	if(  zoom_factor > 0  ) {
@@ -973,7 +1136,7 @@ int zoom_factor_up()
 }
 
 
-int zoom_factor_down()
+static int simgraph16_zoom_factor_down()
 {
 	if(  zoom_factor < MAX_ZOOM_FACTOR  ) {
 		set_zoom_factor( zoom_factor+1 );
@@ -1066,7 +1229,7 @@ static void recode_img_src_target(scr_coord_val h, PIXVAL *src, PIXVAL *target)
 }
 
 
-image_id get_image_count()
+static image_id simgraph16_get_image_count()
 {
 	return anz_images;
 }
@@ -1218,18 +1381,18 @@ static void rezoom_img(const image_id n)
 
 		// now we want to downsize the image
 		// just divide the sizes
-		images[n].x = (images[n].base_x * zoom_num[zoom_factor]) / zoom_den[zoom_factor];
-		images[n].y = (images[n].base_y * zoom_num[zoom_factor]) / zoom_den[zoom_factor];
-		images[n].w = (images[n].base_w * zoom_num[zoom_factor]) / zoom_den[zoom_factor];
-		images[n].h = (images[n].base_h * zoom_num[zoom_factor]) / zoom_den[zoom_factor];
+		images[n].x = (images[n].base_x * g_simgraph16.zoom_num[zoom_factor]) / g_simgraph16.zoom_den[zoom_factor];
+		images[n].y = (images[n].base_y * g_simgraph16.zoom_num[zoom_factor]) / g_simgraph16.zoom_den[zoom_factor];
+		images[n].w = (images[n].base_w * g_simgraph16.zoom_num[zoom_factor]) / g_simgraph16.zoom_den[zoom_factor];
+		images[n].h = (images[n].base_h * g_simgraph16.zoom_num[zoom_factor]) / g_simgraph16.zoom_den[zoom_factor];
 
 		if(  images[n].h > 0  &&  images[n].w > 0  ) {
 			// just recalculate the image in the new size
 			PIXVAL *src = images[n].base_data;
 			PIXVAL *dest = NULL;
 			// embed the baseimage in an image with margin ~ remainder
-			const sint16 x_rem = (images[n].base_x * zoom_num[zoom_factor]) % zoom_den[zoom_factor];
-			const sint16 y_rem = (images[n].base_y * zoom_num[zoom_factor]) % zoom_den[zoom_factor];
+			const sint16 x_rem = (images[n].base_x * g_simgraph16.zoom_num[zoom_factor]) % g_simgraph16.zoom_den[zoom_factor];
+			const sint16 y_rem = (images[n].base_y * g_simgraph16.zoom_num[zoom_factor]) % g_simgraph16.zoom_den[zoom_factor];
 			const sint16 xl_margin = max( x_rem, 0);
 			const sint16 xr_margin = max(-x_rem, 0);
 			const sint16 yl_margin = max( y_rem, 0);
@@ -1237,10 +1400,10 @@ static void rezoom_img(const image_id n)
 			// baseimage top-left  corner is at (xl_margin, yl_margin)
 			// ...       low-right corner is at (xr_margin, yr_margin)
 
-			sint32 orgzoomwidth = ((images[n].base_w + zoom_den[zoom_factor] - 1 ) / zoom_den[zoom_factor]) * zoom_den[zoom_factor];
-			sint32 newzoomwidth = (orgzoomwidth*zoom_num[zoom_factor])/zoom_den[zoom_factor];
-			sint32 orgzoomheight = ((images[n].base_h + zoom_den[zoom_factor] - 1 ) / zoom_den[zoom_factor]) * zoom_den[zoom_factor];
-			sint32 newzoomheight = (orgzoomheight * zoom_num[zoom_factor]) / zoom_den[zoom_factor];
+			sint32 orgzoomwidth = ((images[n].base_w + g_simgraph16.zoom_den[zoom_factor] - 1 ) / g_simgraph16.zoom_den[zoom_factor]) * g_simgraph16.zoom_den[zoom_factor];
+			sint32 newzoomwidth = (orgzoomwidth*g_simgraph16.zoom_num[zoom_factor])/g_simgraph16.zoom_den[zoom_factor];
+			sint32 orgzoomheight = ((images[n].base_h + g_simgraph16.zoom_den[zoom_factor] - 1 ) / g_simgraph16.zoom_den[zoom_factor]) * g_simgraph16.zoom_den[zoom_factor];
+			sint32 newzoomheight = (orgzoomheight * g_simgraph16.zoom_num[zoom_factor]) / g_simgraph16.zoom_den[zoom_factor];
 
 			// we will unpack, re-sample, pack it
 
@@ -1301,9 +1464,9 @@ static void rezoom_img(const image_id n)
 
 			// now we have the image, we do a repack then
 			dest = rezoom_baseimage2[n % env_t::num_threads];
-			switch(  zoom_den[zoom_factor]  ) {
+			switch(  g_simgraph16.zoom_den[zoom_factor]  ) {
 				case 1: {
-					assert(zoom_num[zoom_factor]==2);
+					assert(g_simgraph16.zoom_num[zoom_factor]==2);
 
 					// first half row - just copy values, do not fiddle with neighbor colors
 					uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff;
@@ -1360,13 +1523,13 @@ static void rezoom_img(const image_id n)
 				}
 				case 2:
 					for(  sint16 y = 0;  y < newzoomheight;  y++  ) {
-						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 0 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 1 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 0 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 1 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
 						for(  sint16 x = 0;  x < newzoomwidth;  x++  ) {
 							uint8 valid = 0;
 							uint8 r = 0, g = 0, b = 0;
-							sint16 xreal1 = ((x * zoom_den[zoom_factor] + 0 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal2 = ((x * zoom_den[zoom_factor] + 1 - x_rem) / zoom_num[zoom_factor]) * 4;
+							sint16 xreal1 = ((x * g_simgraph16.zoom_den[zoom_factor] + 0 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal2 = ((x * g_simgraph16.zoom_den[zoom_factor] + 1 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
 							SumSubpixel( p1 + xreal1 );
 							SumSubpixel( p1 + xreal2 );
 							SumSubpixel( p2 + xreal1 );
@@ -1385,15 +1548,15 @@ static void rezoom_img(const image_id n)
 					break;
 				case 3:
 					for(  sint16 y = 0;  y < newzoomheight;  y++  ) {
-						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 0 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 1 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p3 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 2 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 0 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 1 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p3 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 2 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
 						for(  sint16 x = 0;  x < newzoomwidth;  x++  ) {
 							uint8 valid = 0;
 							uint16 r = 0, g = 0, b = 0;
-							sint16 xreal1 = ((x * zoom_den[zoom_factor] + 0 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal2 = ((x * zoom_den[zoom_factor] + 1 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal3 = ((x * zoom_den[zoom_factor] + 2 - x_rem) / zoom_num[zoom_factor]) * 4;
+							sint16 xreal1 = ((x * g_simgraph16.zoom_den[zoom_factor] + 0 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal2 = ((x * g_simgraph16.zoom_den[zoom_factor] + 1 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal3 = ((x * g_simgraph16.zoom_den[zoom_factor] + 2 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
 							SumSubpixel( p1 + xreal1 );
 							SumSubpixel( p1 + xreal2 );
 							SumSubpixel( p1 + xreal3 );
@@ -1417,17 +1580,17 @@ static void rezoom_img(const image_id n)
 					break;
 				case 4:
 					for(  sint16 y = 0;  y < newzoomheight;  y++  ) {
-						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 0 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 1 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p3 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 2 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p4 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 3 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 0 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 1 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p3 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 2 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p4 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 3 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
 						for(  sint16 x = 0;  x < newzoomwidth;  x++  ) {
 							uint8 valid = 0;
 							uint16 r = 0, g = 0, b = 0;
-							sint16 xreal1 = ((x * zoom_den[zoom_factor] + 0 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal2 = ((x * zoom_den[zoom_factor] + 1 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal3 = ((x * zoom_den[zoom_factor] + 2 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal4 = ((x * zoom_den[zoom_factor] + 3 - x_rem) / zoom_num[zoom_factor]) * 4;
+							sint16 xreal1 = ((x * g_simgraph16.zoom_den[zoom_factor] + 0 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal2 = ((x * g_simgraph16.zoom_den[zoom_factor] + 1 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal3 = ((x * g_simgraph16.zoom_den[zoom_factor] + 2 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal4 = ((x * g_simgraph16.zoom_den[zoom_factor] + 3 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
 							SumSubpixel( p1 + xreal1 );
 							SumSubpixel( p1 + xreal2 );
 							SumSubpixel( p1 + xreal3 );
@@ -1458,25 +1621,25 @@ static void rezoom_img(const image_id n)
 					break;
 				case 8:
 					for(  sint16 y = 0;  y < newzoomheight;  y++  ) {
-						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 0 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 1 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p3 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 2 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p4 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 3 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p5 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 4 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p6 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 5 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p7 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 6 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
-						uint8 *p8 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * zoom_den[zoom_factor] + 7 - y_rem) / zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p1 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 0 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p2 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 1 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p3 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 2 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p4 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 3 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p5 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 4 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p6 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 5 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p7 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 6 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
+						uint8 *p8 = rezoom_baseimage[n % env_t::num_threads] + baseoff + ((y * g_simgraph16.zoom_den[zoom_factor] + 7 - y_rem) / g_simgraph16.zoom_num[zoom_factor]) * (basewidth * 4);
 						for(  sint16 x = 0;  x < newzoomwidth;  x++  ) {
 							uint8 valid = 0;
 							uint16 r = 0, g = 0, b = 0;
-							sint16 xreal1 = ((x * zoom_den[zoom_factor] + 0 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal2 = ((x * zoom_den[zoom_factor] + 1 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal3 = ((x * zoom_den[zoom_factor] + 2 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal4 = ((x * zoom_den[zoom_factor] + 3 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal5 = ((x * zoom_den[zoom_factor] + 4 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal6 = ((x * zoom_den[zoom_factor] + 5 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal7 = ((x * zoom_den[zoom_factor] + 6 - x_rem) / zoom_num[zoom_factor]) * 4;
-							sint16 xreal8 = ((x * zoom_den[zoom_factor] + 7 - x_rem) / zoom_num[zoom_factor]) * 4;
+							sint16 xreal1 = ((x * g_simgraph16.zoom_den[zoom_factor] + 0 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal2 = ((x * g_simgraph16.zoom_den[zoom_factor] + 1 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal3 = ((x * g_simgraph16.zoom_den[zoom_factor] + 2 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal4 = ((x * g_simgraph16.zoom_den[zoom_factor] + 3 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal5 = ((x * g_simgraph16.zoom_den[zoom_factor] + 4 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal6 = ((x * g_simgraph16.zoom_den[zoom_factor] + 5 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal7 = ((x * g_simgraph16.zoom_den[zoom_factor] + 6 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
+							sint16 xreal8 = ((x * g_simgraph16.zoom_den[zoom_factor] + 7 - x_rem) / g_simgraph16.zoom_num[zoom_factor]) * 4;
 							SumSubpixel( p1 + xreal1 );
 							SumSubpixel( p1 + xreal2 );
 							SumSubpixel( p1 + xreal3 );
@@ -1642,13 +1805,13 @@ static void rezoom_img(const image_id n)
 
 
 // get next smallest size when scaling to percent
-scr_size display_get_best_matching_size(const image_id n, sint16 zoom_percent)
+static scr_size simgraph16_get_best_matching_size(const image_id n, sint16 zoom_percent)
 {
 	if (n < anz_images  &&  images[n].base_h > 0) {
 		int new_w = (images[n].base_w * zoom_percent + 1) / 100;
 		for (int i = 0; i <= MAX_ZOOM_FACTOR; i++) {
-			int zoom_w = (images[n].base_w * zoom_num[i]) / zoom_den[i];
-			int zoom_h = (images[n].base_h * zoom_num[i]) / zoom_den[i];
+			int zoom_w = (images[n].base_w * g_simgraph16.zoom_num[i]) / g_simgraph16.zoom_den[i];
+			int zoom_h = (images[n].base_h * g_simgraph16.zoom_num[i]) / g_simgraph16.zoom_den[i];
 			if (zoom_w <= new_w) {
 				// first size smaller or equal to requested
 				return scr_size(zoom_w, zoom_h);
@@ -1661,12 +1824,12 @@ scr_size display_get_best_matching_size(const image_id n, sint16 zoom_percent)
 
 
 // force a certain size on a image (for rescaling tool images)
-void display_fit_img_to_width( const image_id n, sint16 new_w )
+static void simgraph16_fit_img_to_width(const image_id n, sint16 new_w)
 {
 	if(  n < anz_images  &&  images[n].base_h > 0  &&  images[n].w != new_w  ) {
 		int old_zoom_factor = zoom_factor;
 		for(  int i=0;  i<=MAX_ZOOM_FACTOR;  i++  ) {
-			int zoom_w = (images[n].base_w * zoom_num[i]) / zoom_den[i];
+			int zoom_w = (images[n].base_w * g_simgraph16.zoom_num[i]) / g_simgraph16.zoom_den[i];
 			if(  zoom_w <= new_w  ) {
 				uint8 old_zoom_flag = images[n].recode_flags & FLAG_ZOOMABLE;
 				images[n].recode_flags |= FLAG_REZOOM | FLAG_ZOOMABLE;
@@ -1779,23 +1942,24 @@ static void calc_base_pal_from_night_shift(const int night)
 }
 
 
-void display_day_night_shift(int night)
+static void simgraph16_set_daynight_level(int night)
 {
 	if(  night != night_shift  ) {
 		night_shift = night;
 		calc_base_pal_from_night_shift(night);
-		mark_screen_dirty();
+		simgraph16_mark_screen_dirty();
 	}
 }
 
 
 // set first and second company color for player
-void display_set_player_color_scheme(const int player, const uint8 col1, const uint8 col2 )
+static void simgraph16_set_player_color_scheme(const int player, const uint8 col1, const uint8 col2)
 {
 	if(player_offsets[player][0]!=col1  ||  player_offsets[player][1]!=col2) {
 		// set new player colors
 		player_offsets[player][0] = col1;
 		player_offsets[player][1] = col2;
+
 		if(player==player_day  ||  player==player_night) {
 			// and recalculate map (and save it)
 			calc_base_pal_from_night_shift(0);
@@ -1806,14 +1970,14 @@ void display_set_player_color_scheme(const int player, const uint8 col1, const u
 			// calc_base_pal_from_night_shift resets player_night to 0
 			player_day = player_night;
 		}
+
 		recode();
-		mark_screen_dirty();
+		simgraph16_mark_screen_dirty();
 	}
 }
 
 
-
-void register_image(image_t *image_in)
+static void simgraph16_register_image(image_t *image_in)
 {
 	struct imd *image;
 
@@ -1900,7 +2064,7 @@ void register_image(image_t *image_in)
 
 // delete all images above a certain number ...
 // (mostly needed when changing climate zones)
-void display_free_all_images_above( image_id above )
+static void simgraph16_free_all_images_above( image_id above )
 {
 	while(  above < anz_images  ) {
 		anz_images--;
@@ -1917,25 +2081,35 @@ void display_free_all_images_above( image_id above )
 
 
 // query offsets
-void display_get_image_offset(image_id image, scr_coord_val *xoff, scr_coord_val *yoff, scr_coord_val *xw, scr_coord_val *yw)
+static scr_rect simgraph16_get_image_offset(image_id image)
 {
 	if(  image < anz_images  ) {
-		*xoff = images[image].x;
-		*yoff = images[image].y;
-		*xw   = images[image].w;
-		*yw   = images[image].h;
+		return scr_rect{
+			images[image].x,
+			images[image].y,
+			images[image].w,
+			images[image].h
+		};
+	}
+	else {
+		return scr_rect{ 0, 0, 0, 0 };
 	}
 }
 
 
 // query un-zoomed offsets
-void display_get_base_image_offset(image_id image, scr_coord_val *xoff, scr_coord_val *yoff, scr_coord_val *xw, scr_coord_val *yw)
+static scr_rect simgraph16_get_base_image_offset(image_id image)
 {
 	if(  image < anz_images  ) {
-		*xoff = images[image].base_x;
-		*yoff = images[image].base_y;
-		*xw   = images[image].base_w;
-		*yw   = images[image].base_h;
+		return scr_rect{
+			images[image].base_x,
+			images[image].base_y,
+			images[image].base_w,
+			images[image].base_h
+		};
+	}
+	else {
+		return scr_rect{ 0, 0, 0, 0 };
 	}
 }
 
@@ -2208,7 +2382,7 @@ static void display_img_nc(scr_coord_val h, const scr_coord_val xp, const scr_co
 
 
 // only used for GUI
-void display_img_aligned( const image_id n, scr_rect area, int align, const bool dirty)
+static void simgraph16_draw_img_aligned( const image_id n, scr_rect area, int align, const bool dirty)
 {
 	if(  n < anz_images  ) {
 		scr_coord_val x,y;
@@ -2233,7 +2407,7 @@ void display_img_aligned( const image_id n, scr_rect area, int align, const bool
 			y = area.get_bottom() - images[n].y - images[n].h;
 		}
 
-		display_color_img( n, x, y, 0, false, dirty  CLIP_NUM_DEFAULT);
+		g_simgraph->draw_color_img( n, x, y, 0, false, dirty  CLIP_NUM_DEFAULT);
 	}
 }
 
@@ -2241,7 +2415,7 @@ void display_img_aligned( const image_id n, scr_rect area, int align, const bool
 /**
  * Draw image with vertical clipping (quickly) and horizontal (slowly)
  */
-void display_img_aux(const image_id n, scr_coord_val xp, scr_coord_val yp, const sint8 player_nr_raw, const bool /*daynight*/, const bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_img_aux(const image_id n, scr_coord_val xp, scr_coord_val yp, const sint8 player_nr_raw, const bool /*daynight*/, const bool dirty  CLIP_NUM_DEF)
 {
 	if(  n < anz_images  ) {
 		// only use player images if needed
@@ -2322,7 +2496,7 @@ void display_img_aux(const image_id n, scr_coord_val xp, scr_coord_val yp, const
 					display_img_pc<plain>( h, xp, yp, sp  CLIP_NUM_PAR );
 					// since height may be reduced, start marking here
 					if(  dirty  ) {
-						mark_rect_dirty_clip( xp, yp, xp + w - 1, yp + h - 1  CLIP_NUM_PAR );
+						simgraph16_mark_rect_dirty_clip( xp, yp, xp + w - 1, yp + h - 1  CLIP_NUM_PAR );
 					}
 			}
 			else {
@@ -2338,7 +2512,7 @@ void display_img_aux(const image_id n, scr_coord_val xp, scr_coord_val yp, const
 					display_img_wc( h, xp, yp, sp  CLIP_NUM_PAR);
 					// since height may be reduced, start marking here
 					if(  dirty  ) {
-						mark_rect_dirty_clip( xp, yp, xp + w - 1, yp + h - 1  CLIP_NUM_PAR );
+						simgraph16_mark_rect_dirty_clip( xp, yp, xp + w - 1, yp + h - 1  CLIP_NUM_PAR );
 					}
 				}
 			}
@@ -2352,14 +2526,14 @@ static void display_three_image_row( image_id i1, image_id i2, image_id i3, scr_
 {
 	if(  i1!=IMG_EMPTY  ) {
 		scr_coord_val w = images[i1].w;
-		display_color_img( i1, row.x, row.y, 0, false, true  CLIP_NUM_DEFAULT);
+		g_simgraph->draw_color_img( i1, row.x, row.y, 0, false, true  CLIP_NUM_DEFAULT);
 		row.x += w;
 		row.w -= w;
 	}
 	// right
 	if(  i3!=IMG_EMPTY  ) {
 		scr_coord_val w = images[i3].w;
-		display_color_img( i3, row.get_right()-w, row.y, 0, false, true  CLIP_NUM_DEFAULT);
+		g_simgraph->draw_color_img( i3, row.get_right()-w, row.y, 0, false, true  CLIP_NUM_DEFAULT);
 		row.w -= w;
 	}
 	// middle
@@ -2367,16 +2541,16 @@ static void display_three_image_row( image_id i1, image_id i2, image_id i3, scr_
 		scr_coord_val w = images[i2].w;
 		// tile it wide
 		while(  w <= row.w  ) {
-			display_color_img( i2, row.x, row.y, 0, false, true  CLIP_NUM_DEFAULT);
+			g_simgraph->draw_color_img( i2, row.x, row.y, 0, false, true  CLIP_NUM_DEFAULT);
 			row.x += w;
 			row.w -= w;
 		}
 		// for the rest we have to clip the rectangle
 		if(  row.w > 0  ) {
-			clip_dimension const cl = display_get_clip_wh();
-			display_set_clip_wh( cl.x, cl.y, max(0,min(row.get_right(),cl.xx)-cl.x), cl.h );
-			display_color_img( i2, row.x, row.y, 0, false, true  CLIP_NUM_DEFAULT);
-			display_set_clip_wh(cl.x, cl.y, cl.w, cl.h );
+			clip_dimension const cl = simgraph16_get_clip_rect(CLIP_NUM_DEFAULT_VALUE);
+			simgraph16_set_clip_rect( cl.x, cl.y, max(0,min(row.get_right(),cl.xx)-cl.x), cl.h CLIP_NUM_DEFAULT, false);
+			g_simgraph->draw_color_img( i2, row.x, row.y, 0, false, true  CLIP_NUM_DEFAULT);
+			simgraph16_set_clip_rect(cl.x, cl.y, cl.w, cl.h CLIP_NUM_DEFAULT, false);
 		}
 	}
 }
@@ -2438,15 +2612,16 @@ static void display_img_stretch_intern( const stretch_map_t &imag, scr_rect area
 		}
 		// for the rest we have to clip the rectangle
 		if(  row.h > 0  ) {
-			clip_dimension const cl = display_get_clip_wh();
-			display_set_clip_wh( cl.x, cl.y, cl.w, max(0,min(row.get_bottom(),cl.yy)-cl.y) );
+			clip_dimension const cl = simgraph16_get_clip_rect(CLIP_NUM_DEFAULT_VALUE);
+			simgraph16_set_clip_rect( cl.x, cl.y, cl.w, max(0,min(row.get_bottom(),cl.yy)-cl.y) CLIP_NUM_DEFAULT, false);
 			display_three_image_rowf( imag[0][1], imag[1][1], imag[2][1], row, color);
-			display_set_clip_wh(cl.x, cl.y, cl.w, cl.h );
+			simgraph16_set_clip_rect(cl.x, cl.y, cl.w, cl.h CLIP_NUM_DEFAULT, false);
 		}
 	}
 }
 
-void display_img_stretch( const stretch_map_t &imag, scr_rect area)
+
+static void simgraph16_draw_stretch_map(const stretch_map_t &imag, scr_rect area)
 {
 	display_img_stretch_intern(imag, area, display_three_image_row, 0);
 }
@@ -2455,14 +2630,14 @@ static void display_three_blend_row( image_id i1, image_id i2, image_id i3, scr_
 {
 	if(  i1!=IMG_EMPTY  ) {
 		scr_coord_val w = images[i1].w;
-		display_rezoomed_img_blend( i1, row.x, row.y, 0, color, false, true CLIPNUM_IGNORE );
+		g_simgraph->draw_rezoomed_img_blend( i1, row.x, row.y, 0, color, false, true CLIPNUM_IGNORE );
 		row.x += w;
 		row.w -= w;
 	}
 	// right
 	if(  i3!=IMG_EMPTY  ) {
 		scr_coord_val w = images[i3].w;
-		display_rezoomed_img_blend( i3, row.get_right()-w, row.y, 0, color, false, true CLIPNUM_IGNORE );
+		g_simgraph->draw_rezoomed_img_blend( i3, row.get_right()-w, row.y, 0, color, false, true CLIPNUM_IGNORE );
 		row.w -= w;
 	}
 	// middle
@@ -2470,23 +2645,23 @@ static void display_three_blend_row( image_id i1, image_id i2, image_id i3, scr_
 		scr_coord_val w = images[i2].w;
 		// tile it wide
 		while(  w <= row.w  ) {
-			display_rezoomed_img_blend( i2, row.x, row.y, 0, color, false, true CLIPNUM_IGNORE );
+			g_simgraph->draw_rezoomed_img_blend( i2, row.x, row.y, 0, color, false, true CLIPNUM_IGNORE );
 			row.x += w;
 			row.w -= w;
 		}
 		// for the rest we have to clip the rectangle
 		if(  row.w > 0  ) {
-			clip_dimension const cl = display_get_clip_wh();
-			display_set_clip_wh( cl.x, cl.y, max(0,min(row.get_right(),cl.xx)-cl.x), cl.h );
-			display_rezoomed_img_blend( i2, row.x, row.y, 0, color, false, true CLIPNUM_IGNORE );
-			display_set_clip_wh(cl.x, cl.y, cl.w, cl.h );
+			clip_dimension const cl = simgraph16_get_clip_rect(CLIP_NUM_DEFAULT_VALUE);
+			simgraph16_set_clip_rect( cl.x, cl.y, max(0,min(row.get_right(),cl.xx)-cl.x), cl.h CLIP_NUM_DEFAULT, false);
+			g_simgraph->draw_rezoomed_img_blend( i2, row.x, row.y, 0, color, false, true CLIPNUM_IGNORE );
+			simgraph16_set_clip_rect(cl.x, cl.y, cl.w, cl.h CLIP_NUM_DEFAULT, false);
 		}
 	}
 }
 
 
 // this displays a 3x3 array of images to fit the scr_rect like above, but blend the color
-void display_img_stretch_blend( const stretch_map_t &imag, scr_rect area, FLAGGED_PIXVAL color )
+static void simgraph16_draw_stretch_map_blend(const stretch_map_t &imag, scr_rect area, FLAGGED_PIXVAL color)
 {
 	display_img_stretch_intern(imag, area, display_three_blend_row, color);
 }
@@ -2573,7 +2748,7 @@ static void display_color_img_wc_daytime(const PIXVAL* sp, scr_coord_val x, scr_
 /**
  * Draw Image, replaced player color
  */
-void display_color_img(const image_id n, scr_coord_val xp, scr_coord_val yp, sint8 player_nr_raw, const bool daynight, const bool dirty  CLIP_NUM_DEF)
+void simgraph16_draw_color_img(const image_id n, scr_coord_val xp, scr_coord_val yp, sint8 player_nr_raw, const bool daynight, const bool dirty  CLIP_NUM_DEF)
 {
 	if(  n < anz_images  ) {
 		// do we have to use a player nr?
@@ -2588,7 +2763,7 @@ void display_color_img(const image_id n, scr_coord_val xp, scr_coord_val yp, sin
 			if(  (images[n].player_flags & (1<<player_nr))  ) {
 				recode_img( n, player_nr );
 			}
-			display_img_aux( n, xp, yp, player_nr, true, dirty  CLIP_NUM_PAR);
+			simgraph16_draw_img_aux( n, xp, yp, player_nr, true, dirty  CLIP_NUM_PAR);
 			return;
 		}
 		else {
@@ -2605,7 +2780,7 @@ void display_color_img(const image_id n, scr_coord_val xp, scr_coord_val yp, sin
 			}
 
 			if(  dirty  ) {
-				mark_rect_dirty_wc( x, y, x + w - 1, y + h - 1 );
+				simgraph16_mark_rect_dirty_wc( x, y, x + w - 1, y + h - 1 );
 			}
 
 			activate_player_color( player_nr, daynight );
@@ -2644,11 +2819,11 @@ void display_color_img(const image_id n, scr_coord_val xp, scr_coord_val yp, sin
 /**
  * draw unscaled images, replaces base color
  */
-void display_base_img(const image_id n, scr_coord_val xp, scr_coord_val yp, const sint8 player_nr, const bool daynight, const bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_base_img(const image_id n, scr_coord_val xp, scr_coord_val yp, const sint8 player_nr, const bool daynight, const bool dirty  CLIP_NUM_DEF)
 {
-	if(  base_tile_raster_width==tile_raster_width  ) {
+	if(  g_simgraph16.tile_raster_width == g_simgraph16.base_tile_raster_width  ) {
 		// same size => use standard routine
-		display_color_img( n, xp, yp, player_nr, daynight, dirty  CLIP_NUM_PAR);
+		simgraph16_draw_color_img( n, xp, yp, player_nr, daynight, dirty  CLIP_NUM_PAR);
 	}
 	else if(  n < anz_images  ) {
 		// now test if visible and clipping needed
@@ -2664,7 +2839,7 @@ void display_base_img(const image_id n, scr_coord_val xp, scr_coord_val yp, cons
 		}
 
 		if (dirty) {
-			mark_rect_dirty_wc(x, y, x + w - 1, y + h - 1);
+			simgraph16_mark_rect_dirty_wc(x, y, x + w - 1, y + h - 1);
 		}
 
 		// colors for 2nd company color
@@ -2738,7 +2913,7 @@ PIXVAL display_blend_colors_alpha32(PIXVAL background, PIXVAL foreground, int al
 
 
 // Blends two colors
-PIXVAL display_blend_colors(PIXVAL background, PIXVAL foreground, int percent_blend)
+static PIXVAL simgraph16_blend_colors(PIXVAL background, PIXVAL foreground, int percent_blend)
 {
 	return display_blend_colors_alpha32(background, foreground, (percent_blend*32)/100);
 }
@@ -2802,13 +2977,13 @@ static blend_proc outline[3] = {
 /**
  * Blends a rectangular region with a color
  */
-void display_blend_wh_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL colval, int percent_blend )
+static void simgraph16_tint_rect(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL colval, int percent_blend)
 {
 	if(  clip_lr( &xp, &w, CR0.clip_rect.x, CR0.clip_rect.xx )  &&  clip_lr( &yp, &h, CR0.clip_rect.y, CR0.clip_rect.yy )  ) {
 		const PIXVAL alpha = (percent_blend*64)/100;
 
 		switch( alpha ) {
-			case 0: // nothing to do ...
+			case 0: // nothing to do
 				break;
 
 			case 16:
@@ -2824,9 +2999,8 @@ void display_blend_wh_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, s
 			}
 			break;
 
-			case 64:
-				// opaque ...
-				display_fillbox_wh_rgb( xp, yp, w, h, colval, false );
+			case 64: // opaque
+				simgraph16_draw_rect( xp, yp, w, h, colval, false );
 				break;
 
 			default:
@@ -3001,7 +3175,7 @@ static void display_img_alpha_wc(scr_coord_val h, const scr_coord_val xp, const
 /**
  * draws the transparent outline of an image
  */
-void display_rezoomed_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char /*player_nr*/, const FLAGGED_PIXVAL color_index, const bool /*daynight*/, const bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_rezoomed_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char /*player_nr*/, const FLAGGED_PIXVAL color_index, const bool /*daynight*/, const bool dirty  CLIP_NUM_DEF)
 {
 	if(  n < anz_images  ) {
 		// need to go to nightmode and or rezoomed?
@@ -3064,7 +3238,7 @@ void display_rezoomed_img_blend(const image_id n, scr_coord_val xp, scr_coord_va
 
 			// marking change?
 			if(  dirty  ) {
-				mark_rect_dirty_wc( xp, yp, xp + w - 1, yp + h - 1 );
+				simgraph16_mark_rect_dirty_wc( xp, yp, xp + w - 1, yp + h - 1 );
 			}
 			display_img_blend_wc( h, xp, yp, sp, color, pix_blend  CLIP_NUM_PAR );
 		}
@@ -3072,7 +3246,7 @@ void display_rezoomed_img_blend(const image_id n, scr_coord_val xp, scr_coord_va
 }
 
 
-void display_rezoomed_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const sint8 /*player_nr*/, const FLAGGED_PIXVAL color_index, const bool /*daynight*/, const bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_rezoomed_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const sint8 /*player_nr*/, const FLAGGED_PIXVAL color_index, const bool /*daynight*/, const bool dirty  CLIP_NUM_DEF)
 {
 	if(  n < anz_images  &&  alpha_n < anz_images  ) {
 		// need to go to nightmode and or rezoomed?
@@ -3143,7 +3317,7 @@ void display_rezoomed_img_alpha(const image_id n, const image_id alpha_n, const
 
 			// marking change?
 			if(  dirty  ) {
-				mark_rect_dirty_wc( xp, yp, xp + w - 1, yp + h - 1 );
+				simgraph16_mark_rect_dirty_wc( xp, yp, xp + w - 1, yp + h - 1 );
 			}
 			display_img_alpha_wc( h, xp, yp, sp, alphamap, get_alpha_mask(alpha_flags), color, alpha  CLIP_NUM_PAR );
 		}
@@ -3152,11 +3326,11 @@ void display_rezoomed_img_alpha(const image_id n, const image_id alpha_n, const
 
 
 // For blending or outlining unzoomed image. Adapted from display_base_img() and display_unzoomed_img_blend()
-void display_base_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_base_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF)
 {
-	if(  base_tile_raster_width == tile_raster_width  ) {
+	if(  g_simgraph16.tile_raster_width == g_simgraph16.base_tile_raster_width  ) {
 		// same size => use standard routine
-		display_rezoomed_img_blend( n, xp, yp, player_nr, color_index, daynight, dirty  CLIP_NUM_PAR );
+		simgraph16_draw_rezoomed_img_blend( n, xp, yp, player_nr, color_index, daynight, dirty  CLIP_NUM_PAR );
 	}
 	else if(  n < anz_images  ) {
 		// now test if visible and clipping needed
@@ -3214,7 +3388,7 @@ void display_base_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp
 			}
 
 			if(  dirty  ) {
-				mark_rect_dirty_wc( x, y, x + w - 1, y + h - 1 );
+				simgraph16_mark_rect_dirty_wc( x, y, x + w - 1, y + h - 1 );
 			}
 			display_img_blend_wc( h, x, y, sp, color, pix_blend  CLIP_NUM_PAR );
 		}
@@ -3222,11 +3396,11 @@ void display_base_img_blend(const image_id n, scr_coord_val xp, scr_coord_val yp
 }
 
 
-void display_base_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const sint8 player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_base_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, scr_coord_val xp, scr_coord_val yp, const sint8 player_nr, const FLAGGED_PIXVAL color_index, const bool daynight, const bool dirty  CLIP_NUM_DEF)
 {
-	if(  base_tile_raster_width == tile_raster_width  ) {
+	if(  g_simgraph16.tile_raster_width == g_simgraph16.base_tile_raster_width  ) {
 		// same size => use standard routine
-		display_rezoomed_img_alpha( n, alpha_n, alpha_flags, xp, yp, player_nr, color_index, daynight, dirty  CLIP_NUM_PAR );
+		simgraph16_draw_rezoomed_img_alpha( n, alpha_n, alpha_flags, xp, yp, player_nr, color_index, daynight, dirty  CLIP_NUM_PAR );
 	}
 	else if(  n < anz_images  ) {
 		// now test if visible and clipping needed
@@ -3291,7 +3465,7 @@ void display_base_img_alpha(const image_id n, const image_id alpha_n, const unsi
 			}
 
 			if(  dirty  ) {
-				mark_rect_dirty_wc( x, y, x + w - 1, y + h - 1 );
+				simgraph16_mark_rect_dirty_wc( x, y, x + w - 1, y + h - 1 );
 			}
 			display_img_alpha_wc( h, x, y, sp, alphamap, get_alpha_mask(alpha_flags), color, alpha_recode  CLIP_NUM_PAR );
 		}
@@ -3303,7 +3477,7 @@ void display_base_img_alpha(const image_id n, const image_id alpha_n, const unsi
 
 
 // scrolls horizontally, will ignore clipping etc.
-void display_scroll_band(scr_coord_val start_y, scr_coord_val x_offset, scr_coord_val h)
+static void simgraph16_move_scroll_band(scr_coord_val start_y, scr_coord_val x_offset, scr_coord_val h)
 {
 	start_y  = max(start_y,  0);
 	x_offset = min(x_offset, disp_width);
@@ -3411,25 +3585,25 @@ static void display_fb_internal(scr_coord_val xp, scr_coord_val yp, scr_coord_va
 }
 
 
-void display_fillbox_wh_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty)
+static void simgraph16_draw_rect(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty)
 {
 	display_fb_internal(xp, yp, w, h, color, dirty, 0, disp_width, 0, disp_height);
 }
 
 
-void display_fillbox_wh_clip_rgb(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_rect_clipped(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty  CLIP_NUM_DEF)
 {
 	display_fb_internal( xp, yp, w, h, color, dirty, CR.clip_rect.x, CR.clip_rect.xx, CR.clip_rect.y, CR.clip_rect.yy );
 }
 
 
-void display_filled_roundbox_clip(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty)
+static void simgraph16_draw_rounded_rect_clipped(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, PIXVAL color, bool dirty)
 {
-	display_fillbox_wh_clip_rgb(xp+2,   yp, w-4, h, color, dirty);
-	display_fillbox_wh_clip_rgb(xp,     yp+2, 1, h-4, color, dirty);
-	display_fillbox_wh_clip_rgb(xp+1,   yp+1, 1, h-2, color, dirty);
-	display_fillbox_wh_clip_rgb(xp+w-1, yp+2, 1, h-4, color, dirty);
-	display_fillbox_wh_clip_rgb(xp+w-2, yp+1, 1, h-2, color, dirty);
+	simgraph16_draw_rect_clipped(xp+2,   yp,   w-4, h,   color, dirty CLIP_NUM_DEFAULT);
+	simgraph16_draw_rect_clipped(xp,     yp+2, 1,   h-4, color, dirty CLIP_NUM_DEFAULT);
+	simgraph16_draw_rect_clipped(xp+1,   yp+1, 1,   h-2, color, dirty CLIP_NUM_DEFAULT);
+	simgraph16_draw_rect_clipped(xp+w-1, yp+2, 1,   h-4, color, dirty CLIP_NUM_DEFAULT);
+	simgraph16_draw_rect_clipped(xp+w-2, yp+1, 1,   h-2, color, dirty CLIP_NUM_DEFAULT);
 }
 
 
@@ -3457,7 +3631,7 @@ void display_vline_wh_rgb(const scr_coord_val xp, scr_coord_val yp, scr_coord_va
 }
 
 
-void display_vline_wh_clip_rgb(const scr_coord_val xp, scr_coord_val yp, scr_coord_val h, const PIXVAL color, bool dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_vline_clipped(const scr_coord_val xp, scr_coord_val yp, scr_coord_val h, const PIXVAL color, bool dirty  CLIP_NUM_DEF)
 {
 	display_vl_internal( xp, yp, h, color, dirty, CR.clip_rect.x, CR.clip_rect.xx, CR.clip_rect.y, CR.clip_rect.yy );
 }
@@ -3466,7 +3640,7 @@ void display_vline_wh_clip_rgb(const scr_coord_val xp, scr_coord_val yp, scr_coo
 /**
  * Draw raw Pixel data
  */
-void display_array_wh(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, const PIXVAL *arr)
+static void simgraph16_draw_array(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, const PIXVAL *arr)
 {
 	const int arr_w = w;
 	const scr_coord_val xoff = clip_wh( &xp, &w, CR0.clip_rect.x, CR0.clip_rect.xx );
@@ -3493,7 +3667,7 @@ void display_array_wh(scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_c
 
 // --------------------------------- text rendering stuff ------------------------------
 
-bool display_load_font(const char *fname, bool reload)
+static bool simgraph16_load_font(const char *fname, bool reload)
 {
 	font_t loaded_fnt;
 
@@ -3531,13 +3705,13 @@ bool display_load_font(const char *fname, bool reload)
 }
 
 
-scr_coord_val display_get_char_width(utf32 c)
+static scr_coord_val simgraph16_get_char_width(utf32 c)
 {
 	return default_font.get_glyph_advance(c);
 }
 
 
-scr_coord_val display_get_number_width()
+static scr_coord_val simgraph16_get_number_width()
 {
 	return default_font_numberwidth;
 }
@@ -3547,7 +3721,7 @@ scr_coord_val display_get_number_width()
  * as well as retrieves the char byte count and the screen pixel width
  * CAUTION : The text pointer advances to point to the next logical character
  */
-utf32 get_next_char_with_metrics(const char* &text, unsigned char &byte_length, unsigned char &pixel_width)
+static utf32 simgraph16_get_next_char_with_metrics(const char* &text, unsigned char &byte_length, unsigned char &pixel_width)
 {
 	size_t len = 0;
 	utf32 const char_code = utf8_decoder_t::decode((utf8 const *)text, len);
@@ -3569,7 +3743,7 @@ utf32 get_next_char_with_metrics(const char* &text, unsigned char &byte_length,
 
 
 /* returns true, if this is a valid character */
-bool has_character(utf16 char_code)
+static bool simgraph16_font_has_character(utf16 char_code)
 {
 	return default_font.is_valid_glyph(char_code);
 }
@@ -3581,7 +3755,7 @@ bool has_character(utf16 char_code)
  * If an ellipsis len is given, it will only return the last character up to this len if the full length cannot be fitted
  * @returns index of next character. if text[index]==0 the whole string fits
  */
-size_t display_fit_proportional( const char *text, scr_coord_val max_width)
+static size_t simgraph16_calc_text_index_for_width(const char *text, scr_coord_val max_width)
 {
 	size_t max_idx = 0;
 
@@ -3590,7 +3764,7 @@ size_t display_fit_proportional( const char *text, scr_coord_val max_width)
 	scr_coord_val current_offset = 0;
 
 	const char *tmp_text = text;
-	while(  get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  max_width > (current_offset+pixel_width)  ) {
+	while(  simgraph16_get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  max_width > (current_offset+pixel_width)  ) {
 		current_offset += pixel_width;
 		max_idx += byte_length;
 	}
@@ -3603,7 +3777,7 @@ size_t display_fit_proportional( const char *text, scr_coord_val max_width)
  * as well as retrieves the char byte count and the screen pixel width
  * CAUTION : The text pointer recedes to point to the previous logical character
  */
-utf32 get_prev_char_with_metrics(const char* &text, const char *const text_start, unsigned char &byte_length, unsigned char &pixel_width)
+static utf32 simgraph16_get_prev_char_with_metrics(const char* &text, const char *const text_start, unsigned char &byte_length, unsigned char &pixel_width)
 {
 	if(  text<=text_start  ) {
 		// case : start of text reached or passed -> do not move the pointer backwards
@@ -3630,14 +3804,14 @@ utf32 get_prev_char_with_metrics(const char* &text, const char *const text_start
 /* proportional_string_width with a text of a given length
 * extended for universal font routines with unicode support
 */
-scr_coord_val display_calc_proportional_string_len_width(const char *text, size_t len)
+static scr_coord_val simgraph16_calc_text_width_n(const char *text, size_t len)
 {
 	uint8 byte_length = 0;
 	uint8 pixel_width = 0;
 	size_t idx = 0;
 	scr_coord_val width = 0;
 
-	while (get_next_char_with_metrics(text, byte_length, pixel_width)  &&  idx < len) {
+	while (simgraph16_get_next_char_with_metrics(text, byte_length, pixel_width)  &&  idx < len) {
 		width += pixel_width;
 		idx += byte_length;
 	}
@@ -3648,21 +3822,21 @@ scr_coord_val display_calc_proportional_string_len_width(const char *text, size_
 /* display_calc_proportional_multiline_string_len_width
 * calculates the width and hieght of a box containing the text inside
 */
-void display_calc_proportional_multiline_string_len_width(int &xw, int &yh, const char *text)
+static scr_size simgraph16_calc_multiline_text_size(const char *text)
 {
 	const font_t* const fnt = &default_font;
 	int width = 0;
 	bool last_cr = false;
 
-	xw = yh = 0;
+	scr_size size{0,0};
 
 	const utf8 *p = reinterpret_cast<const utf8 *>(text);
 	while (const utf32 iUnicode = utf8_decoder_t::decode(p)) {
 
 		if(  iUnicode == '\n'  ) {
 			// new line: record max width
-			xw = max( xw, width );
-			yh += LINESPACE;
+			size.w = max( size.w, width );
+			size.h += LINESPACE;
 			width = 0;
 			last_cr = true;
 			continue;
@@ -3670,11 +3844,14 @@ void display_calc_proportional_multiline_string_len_width(int &xw, int &yh, cons
 		last_cr = false;
 		width += fnt->get_glyph_advance(iUnicode);
 	}
-	xw = max( xw, width );
+
+	size.w = max( size.w, width );
 	if (!last_cr) {
 		// extra CR of the last was not already a CR
-		yh += LINESPACE;
+		size.h += LINESPACE;
 	}
+
+	return size;
 }
 
 
@@ -3682,7 +3859,7 @@ void display_calc_proportional_multiline_string_len_width(int &xw, int &yh, cons
  * len parameter added - use -1 for previous behaviour.
  * completely renovated for unicode and 10 bit width and variable height
  */
-scr_coord_val display_text_proportional_len_clip_rgb(scr_coord_val x, scr_coord_val y, const char* txt, control_alignment_t flags, const PIXVAL color, bool dirty, sint32 len  CLIP_NUM_DEF)
+static scr_coord_val simgraph16_draw_text_clipped_n(scr_coord_val x, scr_coord_val y, const char* txt, control_alignment_t flags, const PIXVAL color, bool dirty, sint32 len  CLIP_NUM_DEF)
 {
 	scr_coord_val cL, cR, cT, cB;
 
@@ -3712,11 +3889,11 @@ scr_coord_val display_text_proportional_len_clip_rgb(scr_coord_val x, scr_coord_
 			break;
 
 		case ALIGN_CENTER_H:
-			x -= display_calc_proportional_string_len_width(txt, len) / 2;
+			x -= simgraph16_calc_text_width_n(txt, len) / 2;
 			break;
 
 		case ALIGN_RIGHT:
-			x -= display_calc_proportional_string_len_width(txt, len);
+			x -= simgraph16_calc_text_width_n(txt, len);
 			break;
 	}
 
@@ -3788,7 +3965,7 @@ scr_coord_val display_text_proportional_len_clip_rgb(scr_coord_val x, scr_coord_
 
 	if(  dirty  ) {
 		// here, because only now we know the length also for ALIGN_LEFT text
-		mark_rect_dirty_clip( x0, y, x - 1, y + LINESPACE - 1  CLIP_NUM_PAR);
+		simgraph16_mark_rect_dirty_clip( x0, y, x - 1, y + LINESPACE - 1  CLIP_NUM_PAR);
 	}
 
 	// warning: actual len might be longer, due to clipping!
@@ -3798,7 +3975,7 @@ scr_coord_val display_text_proportional_len_clip_rgb(scr_coord_val x, scr_coord_
 
 /// Displays a string which is abbreviated by the (language specific) ellipsis character if too wide
 /// If enough space is given then it just displays the full string
-void display_proportional_ellipsis_rgb( scr_rect r, const char *text, int align, const PIXVAL color, const bool dirty, bool shadowed, PIXVAL shadow_color)
+static void simgraph16_draw_text_ellipsis_shadowed(scr_rect r, const char *text, int align, const PIXVAL color, const bool dirty, bool shadowed, PIXVAL shadow_color)
 {
 	const scr_coord_val ellipsis_width = translator::get_lang()->ellipsis_width;
 	const scr_coord_val max_screen_width = r.w;
@@ -3814,7 +3991,7 @@ void display_proportional_ellipsis_rgb( scr_rect r, const char *text, int align,
 	}
 
 	const char *tmp_text = text;
-	while(  get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  max_screen_width >= (current_offset+ellipsis_width+pixel_width)  ) {
+	while(  simgraph16_get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  max_screen_width >= (current_offset+ellipsis_width+pixel_width)  ) {
 		current_offset += pixel_width;
 		max_idx += byte_length;
 	}
@@ -3827,7 +4004,7 @@ void display_proportional_ellipsis_rgb( scr_rect r, const char *text, int align,
 		current_offset += pixel_width;
 		max_idx += byte_length;
 		// check the rest ...
-		while(  get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  max_screen_width >= (current_offset+pixel_width)  ) {
+		while(  simgraph16_get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  max_screen_width >= (current_offset+pixel_width)  ) {
 			current_offset += pixel_width;
 			max_idx += byte_length;
 		}
@@ -3839,15 +4016,15 @@ void display_proportional_ellipsis_rgb( scr_rect r, const char *text, int align,
 				w = (max_screen_width-max_offset_before_ellipsis-ellipsis_width)/2;
 			}
 			if (shadowed) {
-				display_text_proportional_len_clip_rgb( r.x+w+1, r.y+1, text, ALIGN_LEFT | DT_CLIP, shadow_color, dirty, max_idx_before_ellipsis  CLIP_NUM_DEFAULT);
+				simgraph16_draw_text_clipped_n( r.x+w+1, r.y+1, text, ALIGN_LEFT | DT_CLIP, shadow_color, dirty, max_idx_before_ellipsis  CLIP_NUM_DEFAULT);
 			}
-			w += display_text_proportional_len_clip_rgb( r.x+w, r.y, text, ALIGN_LEFT | DT_CLIP, color, dirty, max_idx_before_ellipsis  CLIP_NUM_DEFAULT);
+			w += simgraph16_draw_text_clipped_n( r.x+w, r.y, text, ALIGN_LEFT | DT_CLIP, color, dirty, max_idx_before_ellipsis  CLIP_NUM_DEFAULT);
 
 			if (shadowed) {
-				display_text_proportional_len_clip_rgb( r.x+w+1, r.y+1, translator::translate("..."), ALIGN_LEFT | DT_CLIP, shadow_color, dirty, -1  CLIP_NUM_DEFAULT);
+				simgraph16_draw_text_clipped_n( r.x+w+1, r.y+1, translator::translate("..."), ALIGN_LEFT | DT_CLIP, shadow_color, dirty, -1  CLIP_NUM_DEFAULT);
 			}
 
-			display_text_proportional_len_clip_rgb( r.x+w, r.y, translator::translate("..."), ALIGN_LEFT | DT_CLIP, color, dirty, -1  CLIP_NUM_DEFAULT);
+			simgraph16_draw_text_clipped_n( r.x+w, r.y, translator::translate("..."), ALIGN_LEFT | DT_CLIP, color, dirty, -1  CLIP_NUM_DEFAULT);
 			return;
 		}
 		else {
@@ -3865,19 +4042,19 @@ void display_proportional_ellipsis_rgb( scr_rect r, const char *text, int align,
 		default: ;
 	}
 	if (shadowed) {
-		display_text_proportional_len_clip_rgb( r.x+1, r.y+1, text, ALIGN_LEFT | DT_CLIP, shadow_color, dirty, -1  CLIP_NUM_DEFAULT);
+		simgraph16_draw_text_clipped_n( r.x+1, r.y+1, text, ALIGN_LEFT | DT_CLIP, shadow_color, dirty, -1  CLIP_NUM_DEFAULT);
 	}
-	display_text_proportional_len_clip_rgb( r.x, r.y, text, ALIGN_LEFT | DT_CLIP, color, dirty, -1  CLIP_NUM_DEFAULT);
+	simgraph16_draw_text_clipped_n( r.x, r.y, text, ALIGN_LEFT | DT_CLIP, color, dirty, -1  CLIP_NUM_DEFAULT);
 }
 
 
 /**
  * Draw shaded rectangle using direct color values
  */
-void display_ddd_box_rgb(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color, bool dirty)
+static void simgraph16_draw_box3d(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color, bool dirty)
 {
-	display_fillbox_wh_rgb(x1, y1,         w, 1, tl_color, dirty);
-	display_fillbox_wh_rgb(x1, y1 + h - 1, w, 1, rd_color, dirty);
+	simgraph16_draw_rect(x1, y1,         w, 1, tl_color, dirty);
+	simgraph16_draw_rect(x1, y1 + h - 1, w, 1, rd_color, dirty);
 
 	h -= 2;
 
@@ -3886,67 +4063,67 @@ void display_ddd_box_rgb(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, sc
 }
 
 
-void display_outline_proportional_rgb(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty, sint32 len)
+static void simgraph16_draw_text_outlined(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty)
 {
 	const int flags = ALIGN_LEFT | DT_CLIP;
-	display_text_proportional_len_clip_rgb(xpos - 1, ypos    , text, flags, shadow_color, dirty, len  CLIP_NUM_DEFAULT);
-	display_text_proportional_len_clip_rgb(xpos + 1, ypos + 2, text, flags, shadow_color, dirty, len  CLIP_NUM_DEFAULT);
-	display_text_proportional_len_clip_rgb(xpos, ypos + 1, text, flags, text_color, dirty, len  CLIP_NUM_DEFAULT);
+	simgraph16_draw_text_clipped_n(xpos - 1, ypos    , text, flags, shadow_color, dirty, -1  CLIP_NUM_DEFAULT);
+	simgraph16_draw_text_clipped_n(xpos + 1, ypos + 2, text, flags, shadow_color, dirty, -1  CLIP_NUM_DEFAULT);
+	simgraph16_draw_text_clipped_n(xpos,     ypos + 1, text, flags, text_color,   dirty, -1  CLIP_NUM_DEFAULT);
 }
 
 
-void display_shadow_proportional_rgb(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty, sint32 len)
+static void simgraph16_draw_text_shadowed(scr_coord_val xpos, scr_coord_val ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty)
 {
 	const int flags = ALIGN_LEFT | DT_CLIP;
-	display_text_proportional_len_clip_rgb(xpos + 1, ypos + 1 + (12 - LINESPACE) / 2, text, flags, shadow_color, dirty, len  CLIP_NUM_DEFAULT);
-	display_text_proportional_len_clip_rgb(xpos, ypos + (12 - LINESPACE) / 2, text, flags, text_color, dirty, len  CLIP_NUM_DEFAULT);
+	simgraph16_draw_text_clipped_n(xpos + 1, ypos + 1 + (12 - LINESPACE) / 2, text, flags, shadow_color, dirty, -1  CLIP_NUM_DEFAULT);
+	simgraph16_draw_text_clipped_n(xpos,     ypos +     (12 - LINESPACE) / 2, text, flags, text_color,   dirty, -1  CLIP_NUM_DEFAULT);
 }
 
 
 /**
  * Draw shaded rectangle using direct color values
  */
-void display_ddd_box_clip_rgb(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color)
+static void simgraph16_draw_box3d_clipped(scr_coord_val x1, scr_coord_val y1, scr_coord_val w, scr_coord_val h, PIXVAL tl_color, PIXVAL rd_color)
 {
-	display_fillbox_wh_clip_rgb(x1, y1,         w, 1, tl_color, true);
-	display_fillbox_wh_clip_rgb(x1, y1 + h - 1, w, 1, rd_color, true);
+	simgraph16_draw_rect_clipped(x1, y1,         w, 1, tl_color, true CLIP_NUM_DEFAULT);
+	simgraph16_draw_rect_clipped(x1, y1 + h - 1, w, 1, rd_color, true CLIP_NUM_DEFAULT);
 
 	h -= 2;
 
-	display_vline_wh_clip_rgb(x1,         y1 + 1, h, tl_color, true);
-	display_vline_wh_clip_rgb(x1 + w - 1, y1 + 1, h, rd_color, true);
+	simgraph16_draw_vline_clipped(x1,         y1 + 1, h, tl_color, true CLIP_NUM_DEFAULT);
+	simgraph16_draw_vline_clipped(x1 + w - 1, y1 + 1, h, rd_color, true CLIP_NUM_DEFAULT);
 }
 
 
 /**
  * display text in 3d box with clipping
  */
-void display_ddd_proportional_clip(scr_coord_val xpos, scr_coord_val ypos, FLAGGED_PIXVAL ddd_color, FLAGGED_PIXVAL text_color, const char *text, int dirty  CLIP_NUM_DEF)
+static void simgraph16_draw_textbox3d_clipped(scr_coord_val xpos, scr_coord_val ypos, FLAGGED_PIXVAL ddd_color, FLAGGED_PIXVAL text_color, const char *text, int dirty  CLIP_NUM_DEF)
 {
 	const int vpadding = LINESPACE / 7;
 	const int hpadding = LINESPACE / 4;
 
-	scr_coord_val width = proportional_string_width(text);
+	scr_coord_val width = simgraph16_calc_text_width_n(text, 0x7FFFu);
 
-	PIXVAL lighter = display_blend_colors_alpha32(ddd_color, color_idx_to_rgb(COL_WHITE), 8 /* 25% */);
-	PIXVAL darker  = display_blend_colors_alpha32(ddd_color, color_idx_to_rgb(COL_BLACK), 8 /* 25% */);
+	PIXVAL lighter = display_blend_colors_alpha32(ddd_color, g_simgraph->palette_lookup(COL_WHITE), 8 /* 25% */);
+	PIXVAL darker  = display_blend_colors_alpha32(ddd_color, g_simgraph->palette_lookup(COL_BLACK), 8 /* 25% */);
 
-	display_fillbox_wh_clip_rgb( xpos+1, ypos - vpadding + 1, width+2*hpadding-2, LINESPACE+2*vpadding-1, ddd_color, dirty CLIP_NUM_PAR);
+	simgraph16_draw_rect_clipped( xpos+1, ypos - vpadding + 1, width+2*hpadding-2, LINESPACE+2*vpadding-1, ddd_color, dirty CLIP_NUM_PAR);
 
-	display_fillbox_wh_clip_rgb( xpos, ypos - vpadding, width + 2*hpadding - 2, 1, lighter, dirty );
-	display_fillbox_wh_clip_rgb( xpos, ypos + LINESPACE + vpadding, width + 2*hpadding - 2, 1, darker,  dirty );
+	g_simgraph->draw_rect_clipped( xpos, ypos - vpadding,             width + 2*hpadding - 2, 1, lighter, dirty CLIP_NUM_DEFAULT);
+	g_simgraph->draw_rect_clipped( xpos, ypos + LINESPACE + vpadding, width + 2*hpadding - 2, 1, darker,  dirty CLIP_NUM_DEFAULT);
 
-	display_vline_wh_clip_rgb( xpos, ypos - vpadding, LINESPACE + vpadding * 2, lighter, dirty );
-	display_vline_wh_clip_rgb( xpos + width + 2*hpadding - 2, ypos - vpadding, LINESPACE + vpadding * 2, darker,  dirty );
+	simgraph16_draw_vline_clipped( xpos,                          ypos - vpadding, LINESPACE + vpadding * 2, lighter, dirty CLIP_NUM_DEFAULT);
+	simgraph16_draw_vline_clipped( xpos + width + 2*hpadding - 2, ypos - vpadding, LINESPACE + vpadding * 2, darker,  dirty CLIP_NUM_DEFAULT);
 
-	display_text_proportional_len_clip_rgb( xpos+hpadding, ypos+1, text, ALIGN_LEFT | DT_CLIP, text_color, dirty, -1);
+	simgraph16_draw_text_clipped_n( xpos+hpadding, ypos+1, text, ALIGN_LEFT | DT_CLIP, text_color, dirty, -1 CLIP_NUM_DEFAULT);
 }
 
 
 /**
  * Draw multiline text
  */
-scr_coord_val display_multiline_text_rgb(scr_coord_val x, scr_coord_val y, const char *buf, PIXVAL color)
+static scr_coord_val simgraph16_draw_multiline_text(scr_coord_val x, scr_coord_val y, const char *buf, PIXVAL color)
 {
 	scr_coord_val max_px_len = 0;
 	if (buf != NULL && *buf != '\0') {
@@ -3954,10 +4131,11 @@ scr_coord_val display_multiline_text_rgb(scr_coord_val x, scr_coord_val y, const
 
 		do {
 			next = strchr(buf, '\n');
-			const scr_coord_val px_len = display_text_proportional_len_clip_rgb(
+			const scr_coord_val px_len = simgraph16_draw_text_clipped_n(
 				x, y, buf,
 				ALIGN_LEFT | DT_CLIP, color, true,
 				next != NULL ? (int)(size_t)(next - buf) : -1
+				CLIP_NUM_DEFAULT
 			);
 			if(  px_len>max_px_len  ) {
 				max_px_len = px_len;
@@ -3972,7 +4150,7 @@ scr_coord_val display_multiline_text_rgb(scr_coord_val x, scr_coord_val y, const
 /**
  * draw line from x,y to xx,yy
  **/
-void display_direct_line_rgb(const scr_coord_val x, const scr_coord_val y, const scr_coord_val xx, const scr_coord_val yy, const PIXVAL colval)
+static void simgraph16_draw_line(const scr_coord_val x, const scr_coord_val y, const scr_coord_val xx, const scr_coord_val yy, const PIXVAL colval)
 {
 	int i, steps;
 	sint64 xp, yp;
@@ -4004,8 +4182,8 @@ void display_direct_line_rgb(const scr_coord_val x, const scr_coord_val y, const
 }
 
 
-//taken from function display_direct_line() above, to draw a dotted line: draw=pixels drawn, dontDraw=pixels skipped
-void display_direct_line_dotted_rgb(const scr_coord_val x, const scr_coord_val y, const scr_coord_val xx, const scr_coord_val yy, const scr_coord_val draw, const scr_coord_val dontDraw, const PIXVAL colval)
+//taken from function simgraph16_draw_line() above, to draw a dotted line: draw=pixels drawn, dontDraw=pixels skipped
+static void simgraph16_draw_line_dotted(const scr_coord_val x, const scr_coord_val y, const scr_coord_val xx, const scr_coord_val yy, const scr_coord_val draw, const scr_coord_val dontDraw, const PIXVAL colval)
 {
 	int i, steps;
 	sint64 xp, yp;
@@ -4052,7 +4230,7 @@ void display_direct_line_dotted_rgb(const scr_coord_val x, const scr_coord_val y
 
 
 // bresenham circle (from wikipedia ...)
-void display_circle_rgb( scr_coord_val x0, scr_coord_val  y0, int radius, const PIXVAL colval )
+static void simgraph16_draw_empty_circle( scr_coord_val x0, scr_coord_val  y0, int radius, const PIXVAL colval )
 {
 	int f = 1 - radius;
 	int ddF_x = 1;
@@ -4092,7 +4270,7 @@ void display_circle_rgb( scr_coord_val x0, scr_coord_val  y0, int radius, const
 
 
 // bresenham circle (from wikipedia ...)
-void display_filled_circle_rgb( scr_coord_val x0, scr_coord_val  y0, int radius, const PIXVAL colval )
+static void simgraph16_draw_filled_circle(scr_coord_val x0, scr_coord_val y0, int radius, const PIXVAL colval)
 {
 	int f = 1 - radius;
 	int ddF_x = 1;
@@ -4129,22 +4307,21 @@ void display_filled_circle_rgb( scr_coord_val x0, scr_coord_val  y0, int radius,
 }
 
 
-
-void display_signal_direction_rgb(scr_coord_val x, scr_coord_val y, uint8 way_dir, uint8 sig_dir, PIXVAL col1, PIXVAL col1_dark, bool is_diagonal, uint8 slope )
+static void simgraph16_draw_signal_direction(scr_coord_val x, scr_coord_val y, uint8 way_dir, uint8 sig_dir, PIXVAL col1, PIXVAL col1_dark, bool is_diagonal, uint8 slope)
 {
-	uint8 width  = is_diagonal ? current_tile_raster_width/6*0.353 :current_tile_raster_width/6;
-	const uint8 height = is_diagonal ?current_tile_raster_width/6*0.353 :current_tile_raster_width/12;
-	const uint8 thickness = max( current_tile_raster_width/36, 2);
+	uint8 width        = is_diagonal ? g_simgraph16.current_tile_raster_width/6*0.353 : g_simgraph16.current_tile_raster_width/6;
+	const uint8 height = is_diagonal ? g_simgraph16.current_tile_raster_width/6*0.353 : g_simgraph16.current_tile_raster_width/12;
+	const uint8 thickness = max( g_simgraph16.current_tile_raster_width/36, 2);
 
-	x += current_tile_raster_width/2;
-	y += (current_tile_raster_width*9)/16;
+	x += g_simgraph16.current_tile_raster_width/2;
+	y += (g_simgraph16.current_tile_raster_width*9)/16;
 
 	if (is_diagonal) {
 
 		if (way_dir == ribi_t::northeast || way_dir == ribi_t::southwest) {
 			// vertical
-			x += (way_dir==ribi_t::northeast) ?current_tile_raster_width/4 : (-current_tile_raster_width/4);
-			y += current_tile_raster_width/16;
+			x += (way_dir==ribi_t::northeast) ? g_simgraph16.current_tile_raster_width/4 : (-g_simgraph16.current_tile_raster_width/4);
+			y += g_simgraph16.current_tile_raster_width/16;
 			width = width<<2; // 4x
 
 			// upper
@@ -4152,40 +4329,40 @@ void display_signal_direction_rgb(scr_coord_val x, scr_coord_val y, uint8 way_di
 				const uint8 yoff = (uint8)((xoff+1)/2);
 				// up
 				if (sig_dir & ribi_t::east || sig_dir & ribi_t::south) {
-					display_vline_wh_clip_rgb(x + xoff, y+yoff, width/4 - yoff, col1, true);
-					display_vline_wh_clip_rgb(x-xoff-1, y+yoff, width/4 - yoff, col1, true);
+					simgraph16_draw_vline_clipped(x + xoff, y+yoff, width/4 - yoff, col1, true CLIP_NUM_DEFAULT);
+					simgraph16_draw_vline_clipped(x-xoff-1, y+yoff, width/4 - yoff, col1, true CLIP_NUM_DEFAULT);
 				}
 				// down
 				if (sig_dir & ribi_t::west || sig_dir & ribi_t::north) {
-					display_vline_wh_clip_rgb(x + xoff, y+current_tile_raster_width/6,              width/4-yoff, col1,      true);
-					display_vline_wh_clip_rgb(x + xoff, y+current_tile_raster_width/6+width/4-yoff, thickness,    col1_dark, true);
-					display_vline_wh_clip_rgb(x-xoff-1, y+current_tile_raster_width/6,              width/4-yoff, col1,      true);
-					display_vline_wh_clip_rgb(x-xoff-1, y+current_tile_raster_width/6+width/4-yoff, thickness,    col1_dark, true);
+					simgraph16_draw_vline_clipped(x+xoff,   y+g_simgraph16.current_tile_raster_width/6,              width/4-yoff, col1,      true CLIP_NUM_DEFAULT);
+					simgraph16_draw_vline_clipped(x+xoff,   y+g_simgraph16.current_tile_raster_width/6+width/4-yoff, thickness,    col1_dark, true CLIP_NUM_DEFAULT);
+					simgraph16_draw_vline_clipped(x-xoff-1, y+g_simgraph16.current_tile_raster_width/6,              width/4-yoff, col1,      true CLIP_NUM_DEFAULT);
+					simgraph16_draw_vline_clipped(x-xoff-1, y+g_simgraph16.current_tile_raster_width/6+width/4-yoff, thickness,    col1_dark, true CLIP_NUM_DEFAULT);
 				}
 			}
 			// up
 			if (sig_dir & ribi_t::east || sig_dir & ribi_t::south) {
-				display_fillbox_wh_clip_rgb(x - width/2, y + width/4, width, thickness, col1_dark, true);
+				g_simgraph->draw_rect_clipped(x - width/2, y + width/4, width, thickness, col1_dark, true CLIP_NUM_DEFAULT);
 			}
 		}
 		else {
 			// horizontal
-			y -= current_tile_raster_width/12;
+			y -= g_simgraph16.current_tile_raster_width/12;
 			if (way_dir == ribi_t::southeast) {
-				y += current_tile_raster_width/4;
+				y += g_simgraph16.current_tile_raster_width/4;
 			}
 
 			for (uint8 xoff = 0; xoff < width*2; xoff++) {
 				const uint8 h = width*2 - (scr_coord_val)(xoff + 1);
 				// left
 				if (sig_dir & ribi_t::north || sig_dir & ribi_t::east) {
-					display_vline_wh_clip_rgb(x - xoff - width*2, y + (scr_coord_val)((xoff+1)/2),   h, col1, true);
-					display_vline_wh_clip_rgb(x - xoff - width*2, y + (scr_coord_val)((xoff+1)/2)+h, thickness, col1_dark, true);
+					simgraph16_draw_vline_clipped(x - xoff - width*2, y + (scr_coord_val)((xoff+1)/2),   h,         col1,      true CLIP_NUM_DEFAULT);
+					simgraph16_draw_vline_clipped(x - xoff - width*2, y + (scr_coord_val)((xoff+1)/2)+h, thickness, col1_dark, true CLIP_NUM_DEFAULT);
 				}
 				// right
 				if (sig_dir & ribi_t::south || sig_dir & ribi_t::west) {
-					display_vline_wh_clip_rgb(x + xoff + width*2, y + (scr_coord_val)((xoff+1)/2),   h, col1, true);
-					display_vline_wh_clip_rgb(x + xoff + width*2, y + (scr_coord_val)((xoff+1)/2)+h, thickness, col1_dark, true);
+					simgraph16_draw_vline_clipped(x + xoff + width*2, y + (scr_coord_val)((xoff+1)/2),   h,         col1,      true CLIP_NUM_DEFAULT);
+					simgraph16_draw_vline_clipped(x + xoff + width*2, y + (scr_coord_val)((xoff+1)/2)+h, thickness, col1_dark, true CLIP_NUM_DEFAULT);
 				}
 			}
 		}
@@ -4195,29 +4372,29 @@ void display_signal_direction_rgb(scr_coord_val x, scr_coord_val y, uint8 way_di
 			// upper right
 			scr_coord_val slope_offset_y = corner_se( slope )*TILE_HEIGHT_STEP;
 			for (uint8 xoff = 0; xoff < width; xoff++) {
-				display_vline_wh_clip_rgb( x + xoff, y - slope_offset_y, (scr_coord_val)(xoff/2) + 1, col1, true );
-				display_vline_wh_clip_rgb( x + xoff, y - slope_offset_y + (scr_coord_val)(xoff/2) + 1, thickness, col1_dark, true );
+				simgraph16_draw_vline_clipped( x + xoff, y - slope_offset_y, (scr_coord_val)(xoff/2) + 1, col1, true CLIP_NUM_DEFAULT);
+				simgraph16_draw_vline_clipped( x + xoff, y - slope_offset_y + (scr_coord_val)(xoff/2) + 1, thickness, col1_dark, true CLIP_NUM_DEFAULT);
 			}
 		}
 		if (sig_dir & ribi_t::east) {
 			scr_coord_val slope_offset_y = corner_se( slope )*TILE_HEIGHT_STEP;
 			for (uint8 xoff = 0; xoff < width; xoff++) {
-				display_vline_wh_clip_rgb(x - xoff - 1, y - slope_offset_y, (scr_coord_val)(xoff/2) + 1, col1, true);
-				display_vline_wh_clip_rgb(x - xoff - 1, y - slope_offset_y + (scr_coord_val)(xoff/2) + 1, thickness, col1_dark, true);
+				simgraph16_draw_vline_clipped(x - xoff - 1, y - slope_offset_y, (scr_coord_val)(xoff/2) + 1, col1, true CLIP_NUM_DEFAULT);
+				simgraph16_draw_vline_clipped(x - xoff - 1, y - slope_offset_y + (scr_coord_val)(xoff/2) + 1, thickness, col1_dark, true CLIP_NUM_DEFAULT);
 			}
 		}
 		if (sig_dir & ribi_t::west) {
 			scr_coord_val slope_offset_y = corner_nw( slope )*TILE_HEIGHT_STEP;
 			for (uint8 xoff = 0; xoff < width; xoff++) {
-				display_vline_wh_clip_rgb(x + xoff, y - slope_offset_y + height*2 - (scr_coord_val)(xoff/2) + 1, (scr_coord_val)(xoff/2) + 1, col1, true);
-				display_vline_wh_clip_rgb(x + xoff, y - slope_offset_y + height*2 + 1, thickness, col1_dark, true);
+				simgraph16_draw_vline_clipped(x + xoff, y - slope_offset_y + height*2 - (scr_coord_val)(xoff/2) + 1, (scr_coord_val)(xoff/2) + 1, col1, true CLIP_NUM_DEFAULT);
+				simgraph16_draw_vline_clipped(x + xoff, y - slope_offset_y + height*2 + 1, thickness, col1_dark, true CLIP_NUM_DEFAULT);
 			}
 		}
 		if (sig_dir & ribi_t::north) {
 			scr_coord_val slope_offset_y = corner_nw( slope )*TILE_HEIGHT_STEP;
 			for (uint8 xoff = 0; xoff < width; xoff++) {
-				display_vline_wh_clip_rgb(x - xoff - 1, y - slope_offset_y + height*2 - (scr_coord_val)(xoff/2) + 1, (scr_coord_val)(xoff/2) + 1, col1, true);
-				display_vline_wh_clip_rgb(x - xoff - 1, y - slope_offset_y + height*2 + 1, thickness, col1_dark, true);
+				simgraph16_draw_vline_clipped(x - xoff - 1, y - slope_offset_y + height*2 - (scr_coord_val)(xoff/2) + 1, (scr_coord_val)(xoff/2) + 1, col1, true CLIP_NUM_DEFAULT);
+				simgraph16_draw_vline_clipped(x - xoff - 1, y - slope_offset_y + height*2 + 1, thickness, col1_dark, true CLIP_NUM_DEFAULT);
 			}
 		}
 	}
@@ -4234,7 +4411,7 @@ void display_signal_direction_rgb(scr_coord_val x, scr_coord_val y, uint8 way_di
  * @param draw for dotted lines, how many pixels to be drawn (leave 0 for solid line)
  * @param dontDraw for dotted lines, how many pixels to not be drawn (leave 0 for solid line)
  */
-void draw_bezier_rgb(scr_coord_val Ax, scr_coord_val Ay, scr_coord_val Bx, scr_coord_val By, scr_coord_val ADx, scr_coord_val ADy, scr_coord_val BDx, scr_coord_val BDy, const PIXVAL colore, scr_coord_val draw, scr_coord_val dontDraw)
+static void simgraph16_draw_bezier(scr_coord_val Ax, scr_coord_val Ay, scr_coord_val Bx, scr_coord_val By, scr_coord_val ADx, scr_coord_val ADy, scr_coord_val BDx, scr_coord_val BDy, const PIXVAL colore, scr_coord_val draw, scr_coord_val dontDraw)
 {
 	scr_coord_val Cx,Cy,Dx,Dy;
 	Cx = Ax + ADx;
@@ -4256,7 +4433,7 @@ void draw_bezier_rgb(scr_coord_val Ax, scr_coord_val Ay, scr_coord_val Bx, scr_c
 		ry = Ay*b*b*b + 3*Cy*b*b*a + 3*Dy*b*a*a + By*a*a*a;
 		if (t>0.0)
 			if (!draw && !dontDraw)
-				display_direct_line_rgb(rx,ry,oldx,oldy,colore);
+				simgraph16_draw_line(rx,ry,oldx,oldy,colore);
 			else
 				display_direct_line_dotted_rgb(rx,ry,oldx,oldy,draw,dontDraw,colore);
 	  }
@@ -4275,10 +4452,10 @@ void draw_bezier_rgb(scr_coord_val Ax, scr_coord_val Ay, scr_coord_val Bx, scr_c
 
 		// fixed point: due to cycling between 0 and 32 (1<<5), we divide by 32^3 == 1<<15 because of cubic interpolation
 		if(  !draw  &&  !dontDraw  ) {
-			display_direct_line_rgb( rx>>15, ry>>15, oldx>>15, oldy>>15, colore );
+			g_simgraph->draw_line( rx>>15, ry>>15, oldx>>15, oldy>>15, colore );
 		}
 		else {
-			display_direct_line_dotted_rgb( rx>>15, ry>>15, oldx>>15, oldy>>15, draw, dontDraw, colore );
+			g_simgraph->draw_line_dotted( rx>>15, ry>>15, oldx>>15, oldy>>15, draw, dontDraw, colore );
 		}
 	}
 }
@@ -4286,7 +4463,7 @@ void draw_bezier_rgb(scr_coord_val Ax, scr_coord_val Ay, scr_coord_val Bx, scr_c
 
 
 // Only right facing at the moment
-void display_right_triangle_rgb(scr_coord_val x, scr_coord_val y, scr_coord_val height, const PIXVAL colval, const bool dirty)
+static void simgraph16_draw_right_triangle(scr_coord_val x, scr_coord_val y, scr_coord_val height, const PIXVAL colval, const bool dirty)
 {
 	y += (height / 2);
 	while(  height > 0  ) {
@@ -4318,7 +4495,7 @@ static inline uint32 get_lowest_set_bit(uint32 val)
  * copies only the changed areas to the screen using the "tile dirty buffer"
  * To get large changes, actually the current and the previous one is used.
  */
-void display_flush_buffer()
+static void simgraph16_flush_framebuffer()
 {
 #ifdef USE_SOFTPOINTER
 	ex_ord_update_mx_my();
@@ -4328,7 +4505,7 @@ void display_flush_buffer()
 
 	// use mouse pointer image if available
 	if (softpointer != -1 && standard_pointer >= 0) {
-		display_color_img(standard_pointer, sys_event.mx, sys_event.my, 0, false, true  CLIP_NUM_DEFAULT);
+		simgraph16_draw_color_img(standard_pointer, sys_event.mx, sys_event.my, 0, false, true  CLIP_NUM_DEFAULT);
 
 		// if software emulated mouse pointer is over the ticker, redraw it totally at next occurs
 		if (!ticker::empty() && sys_event.my+images[standard_pointer].h >= ticker_ypos_top &&
@@ -4338,10 +4515,10 @@ void display_flush_buffer()
 	}
 	// no pointer image available, draw a crosshair
 	else {
-		display_fb_internal(sys_event.mx - 1, sys_event.my - 3, 3, 7, color_idx_to_rgb(COL_WHITE), true, 0, disp_width, 0, disp_height);
-		display_fb_internal(sys_event.mx - 3, sys_event.my - 1, 7, 3, color_idx_to_rgb(COL_WHITE), true, 0, disp_width, 0, disp_height);
-		display_direct_line_rgb( sys_event.mx-2, sys_event.my, sys_event.mx+2, sys_event.my, color_idx_to_rgb(COL_BLACK) );
-		display_direct_line_rgb( sys_event.mx, sys_event.my-2, sys_event.mx, sys_event.my+2, color_idx_to_rgb(COL_BLACK) );
+		display_fb_internal(sys_event.mx - 1, sys_event.my - 3, 3, 7, g_simgraph->palette_lookup(COL_WHITE), true, 0, disp_width, 0, disp_height);
+		display_fb_internal(sys_event.mx - 3, sys_event.my - 1, 7, 3, g_simgraph->palette_lookup(COL_WHITE), true, 0, disp_width, 0, disp_height);
+		simgraph16_draw_line( sys_event.mx-2, sys_event.my, sys_event.mx+2, sys_event.my, g_simgraph->palette_lookup(COL_BLACK) );
+		display_direct_line_rgb( sys_event.mx, sys_event.my-2, sys_event.mx, sys_event.my+2, g_simgraph->palette_lookup(COL_BLACK) );
 
 		// if crosshair is over the ticker, redraw it totally at next occurs
 		if(!ticker::empty() && sys_event.my+2 >= ticker_ypos_top && sys_event.my-2 <= ticker_ypos_bottom) {
@@ -4420,12 +4597,12 @@ void display_flush_buffer()
 				}
 
 #ifdef DEBUG_FLUSH_BUFFER
-				display_vline_wh_rgb( (x1 << DIRTY_TILE_SHIFT) - 1, y1 << DIRTY_TILE_SHIFT, (y2 - y1) << DIRTY_TILE_SHIFT, color_idx_to_rgb(COL_YELLOW), false);
-				display_vline_wh_rgb( x2 << DIRTY_TILE_SHIFT,  y1 << DIRTY_TILE_SHIFT, (y2 - y1) << DIRTY_TILE_SHIFT, color_idx_to_rgb(COL_YELLOW), false);
-				display_fillbox_wh_rgb( x1 << DIRTY_TILE_SHIFT, y1 << DIRTY_TILE_SHIFT, (x2 - x1) << DIRTY_TILE_SHIFT, 1, color_idx_to_rgb(COL_YELLOW), false);
-				display_fillbox_wh_rgb( x1 << DIRTY_TILE_SHIFT, (y2 << DIRTY_TILE_SHIFT) - 1, (x2 - x1) << DIRTY_TILE_SHIFT, 1, color_idx_to_rgb(COL_YELLOW), false);
-				display_direct_line_rgb( x1 << DIRTY_TILE_SHIFT, y1 << DIRTY_TILE_SHIFT, x2 << DIRTY_TILE_SHIFT, (y2 << DIRTY_TILE_SHIFT) - 1, color_idx_to_rgb(COL_YELLOW) );
-				display_direct_line_rgb( x1 << DIRTY_TILE_SHIFT, (y2 << DIRTY_TILE_SHIFT) - 1, x2 << DIRTY_TILE_SHIFT, y1 << DIRTY_TILE_SHIFT, color_idx_to_rgb(COL_YELLOW) );
+				display_vline_wh_rgb( (x1 << DIRTY_TILE_SHIFT) - 1, y1 << DIRTY_TILE_SHIFT, (y2 - y1) << DIRTY_TILE_SHIFT, g_simgraph->palette_lookup(COL_YELLOW), false);
+				display_vline_wh_rgb( x2 << DIRTY_TILE_SHIFT,  y1 << DIRTY_TILE_SHIFT, (y2 - y1) << DIRTY_TILE_SHIFT, g_simgraph->palette_lookup(COL_YELLOW), false);
+				display_fillbox_wh_rgb( x1 << DIRTY_TILE_SHIFT, y1 << DIRTY_TILE_SHIFT, (x2 - x1) << DIRTY_TILE_SHIFT, 1, g_simgraph->palette_lookup(COL_YELLOW), false);
+				display_fillbox_wh_rgb( x1 << DIRTY_TILE_SHIFT, (y2 << DIRTY_TILE_SHIFT) - 1, (x2 - x1) << DIRTY_TILE_SHIFT, 1, g_simgraph->palette_lookup(COL_YELLOW), false);
+				simgraph16_draw_line( x1 << DIRTY_TILE_SHIFT, y1 << DIRTY_TILE_SHIFT, x2 << DIRTY_TILE_SHIFT, (y2 << DIRTY_TILE_SHIFT) - 1, g_simgraph->palette_lookup(COL_YELLOW) );
+				simgraph16_draw_line( x1 << DIRTY_TILE_SHIFT, (y2 << DIRTY_TILE_SHIFT) - 1, x2 << DIRTY_TILE_SHIFT, y1 << DIRTY_TILE_SHIFT, g_simgraph->palette_lookup(COL_YELLOW) );
 #else
 				dr_textur( x1 << DIRTY_TILE_SHIFT, y1 << DIRTY_TILE_SHIFT, (x2 - x1) << DIRTY_TILE_SHIFT, (y2 - y1) << DIRTY_TILE_SHIFT );
 #endif
@@ -4450,12 +4627,12 @@ void display_flush_buffer()
 /**
  * Turn mouse pointer visible/invisible
  */
-void display_show_pointer(int yesno)
+static void simgraph16_set_cursor_visible(bool show)
 {
 #ifdef USE_SOFTPOINTER
-	softpointer = yesno;
+	softpointer = show;
 #else
-	show_pointer(yesno);
+	show_pointer(show);
 #endif
 }
 
@@ -4463,21 +4640,21 @@ void display_show_pointer(int yesno)
 /**
  * mouse pointer image
  */
-void display_set_pointer(int pointer)
+static void simgraph16_set_default_cursor(int cursor_id)
 {
-	standard_pointer = pointer;
+	standard_pointer = cursor_id;
 }
 
 
 /**
  * mouse pointer image
  */
-void display_show_load_pointer(int loading)
+static void simgraph16_set_show_load_cursor(bool show)
 {
 #ifdef USE_SOFTPOINTER
-	softpointer = !loading;
+	softpointer = !show;
 #else
-	set_pointer(loading);
+	set_pointer(show);
 #endif
 }
 
@@ -4485,7 +4662,7 @@ void display_show_load_pointer(int loading)
 /**
  * Initialises the graphics module
  */
-bool simgraph_init(scr_size window_size, sint16 full_screen)
+static bool simgraph16_init(scr_size window_size, sint16 full_screen)
 {
 	disp_actual_width = window_size.w;
 	disp_height = window_size.h;
@@ -4514,11 +4691,11 @@ bool simgraph_init(scr_size window_size, sint16 full_screen)
 	textur = dr_textur_init();
 
 	// init, load, and check fonts
-	if (!display_load_font(env_t::fontname.c_str())) {
+	if (!g_simgraph->load_font(env_t::fontname.c_str(), false)) {
 		env_t::fontname = dr_get_system_font();
-		if (!display_load_font(env_t::fontname.c_str())) {
+		if (!g_simgraph->load_font(env_t::fontname.c_str(), false)) {
 			env_t::fontname = FONT_PATH_X "cyr.bdf";
-			if (!display_load_font(env_t::fontname.c_str())) {
+			if (!g_simgraph->load_font(env_t::fontname.c_str(), false)) {
 				dr_fatal_notify("No fonts found!");
 				return false;
 			}
@@ -4534,7 +4711,7 @@ bool simgraph_init(scr_size window_size, sint16 full_screen)
 	tile_dirty = MALLOCN( uint32, tile_buffer_length );
 	tile_dirty_old = MALLOCN( uint32, tile_buffer_length );
 
-	mark_screen_dirty();
+	simgraph16_mark_screen_dirty();
 	MEMZERON( tile_dirty_old, tile_buffer_length );
 
 	// init player colors
@@ -4543,11 +4720,11 @@ bool simgraph_init(scr_size window_size, sint16 full_screen)
 		player_offsets[i][1] = i*8+24;
 	}
 
-	display_set_clip_wh(0, 0, disp_width, disp_height);
+	simgraph16_set_clip_rect(0, 0, disp_width, disp_height CLIP_NUM_DEFAULT, false);
 
 	// Calculate daylight rgbmap and save it for unshaded tile drawing
 	player_day = 0;
-	display_day_night_shift(0);
+	simgraph16_set_daynight_level(0);
 	memcpy(specialcolormap_all_day, specialcolormap_day_night, 256 * sizeof(PIXVAL));
 	memcpy(rgbmap_all_day, rgbmap_day_night, RGBMAPSIZE * sizeof(PIXVAL));
 
@@ -4578,7 +4755,7 @@ bool simgraph_init(scr_size window_size, sint16 full_screen)
 /**
  * Check if the graphic module already was initialized.
  */
-bool is_display_init()
+static bool simgraph16_is_display_init()
 {
 	return textur != NULL  &&  default_font.is_loaded()  &&  images!=NULL;
 }
@@ -4587,13 +4764,13 @@ bool is_display_init()
 /**
  * Close the Graphic module
  */
-void simgraph_exit()
+static void simgraph16_exit()
 {
 	dr_os_close();
 
 	free( tile_dirty_old );
 	free( tile_dirty );
-	display_free_all_images_above(0);
+	g_simgraph->free_all_images_above(0);
 	free(images);
 
 	tile_dirty = tile_dirty_old = NULL;
@@ -4609,7 +4786,7 @@ void simgraph_exit()
 
 /* changes display size
  */
-void simgraph_resize(scr_size new_window_size)
+static void simgraph16_on_window_resized(scr_size new_window_size)
 {
 	disp_actual_width = max( 16, new_window_size.w );
 	if(  new_window_size.h<=0  ) {
@@ -4634,10 +4811,10 @@ void simgraph_resize(scr_size new_window_size)
 			tile_dirty = MALLOCN( uint32, tile_buffer_length );
 			tile_dirty_old = MALLOCN( uint32, tile_buffer_length );
 
-			display_set_clip_wh(0, 0, disp_actual_width, disp_height);
+			g_simgraph->set_clip_rect(0, 0, disp_actual_width, disp_height CLIP_NUM_DEFAULT, false);
 		}
 
-		mark_screen_dirty();
+		simgraph16_mark_screen_dirty();
 		MEMZERON( tile_dirty_old, tile_buffer_length );
 	}
 }
@@ -4646,7 +4823,7 @@ void simgraph_resize(scr_size new_window_size)
 /**
  * Take Screenshot
  */
-bool display_snapshot( const scr_rect &area )
+static bool simgraph16_take_screenshot(const scr_rect &area)
 {
 	if (access(SCREENSHOT_PATH_X, W_OK) == -1) {
 		return false; // directory not accessible
@@ -4680,3 +4857,29 @@ bool display_snapshot( const scr_rect &area )
 
 	return img.write_png(filename);
 }
+
+
+static void simgraph16_set_image_procs(bool is_global)
+{
+	if(  is_global  ) {
+		g_simgraph16.draw_normal = simgraph16_draw_img_aux;;
+		g_simgraph16.draw_color  = simgraph16_draw_color_img;
+		g_simgraph16.draw_blend  = simgraph16_draw_rezoomed_img_blend;
+		g_simgraph16.draw_alpha  = simgraph16_draw_rezoomed_img_alpha;
+		g_simgraph16.current_tile_raster_width = g_simgraph->get_tile_raster_width();
+	}
+	else {
+		g_simgraph16.draw_normal = simgraph16_draw_base_img;
+		g_simgraph16.draw_color  = simgraph16_draw_base_img;
+		g_simgraph16.draw_blend  = simgraph16_draw_base_img_blend;
+		g_simgraph16.draw_alpha  = simgraph16_draw_base_img_alpha;
+		g_simgraph16.current_tile_raster_width = g_simgraph->get_base_tile_raster_width();
+	}
+}
+
+
+void simgraph16_set_light_color(int light_idx, rgb888_t day_colour, rgb888_t night_colour)
+{
+	display_day_lights[light_idx]   = day_colour;
+	display_night_lights[light_idx] = night_colour;
+}
diff --git a/src/simutrans/display/simgraph16.h b/src/simutrans/display/simgraph16.h
new file mode 100644
index 000000000..d1df3e350
--- /dev/null
+++ b/src/simutrans/display/simgraph16.h
@@ -0,0 +1,16 @@
+/*
+ * This file is part of the Simutrans project under the Artistic License.
+ * (see LICENSE.txt)
+ */
+
+#ifndef DISPLAY_SIMGRAPH16_H
+#define DISPLAY_SIMGRAPH16_H
+
+
+#include "simgraph.h"
+
+
+extern const simgraph_t g_simgraph16;
+
+
+#endif
diff --git a/src/simutrans/display/simview.cc b/src/simutrans/display/simview.cc
index 1dbb06bb7..34156db6b 100644
--- a/src/simutrans/display/simview.cc
+++ b/src/simutrans/display/simview.cc
@@ -71,8 +71,8 @@ void *display_region_thread( void *ptr )
 
 	while(true) {
 		simthread_barrier_wait( &display_barrier_start ); // wait for all to start
-		clear_all_poly_clip( view->thread_num );
-		display_set_clip_wh( view->lt_cl.x, view->lt_cl.y, view->wh_cl.x, view->wh_cl.y, view->thread_num );
+		g_simgraph->clear_all_poly_clip( view->thread_num );
+		g_simgraph->set_clip_rect( view->lt_cl.x, view->lt_cl.y, view->wh_cl.x, view->wh_cl.y, view->thread_num, false);
 		view->show_routine->display_region( view->lt, view->wh, view->y_min, view->y_max, false, true, view->thread_num );
 		simthread_barrier_wait( &display_barrier_end ); // wait for all to finish
 	}
@@ -98,15 +98,14 @@ void main_view_t::display(bool force_dirty)
 
 #if COLOUR_DEPTH != 0
 	DBG_DEBUG4("main_view_t::display", "starting ...");
-	display_set_image_proc(true);
+	g_simgraph->set_image_procs(true);
 
-	const sint16 disp_width = display_get_width();
-	const sint16 disp_real_height = display_get_height();
-	const sint16 IMG_SIZE = get_tile_raster_width();
+	const scr_size screen = g_simgraph->get_screen_size();
+	const sint16 IMG_SIZE = g_simgraph->get_tile_raster_width();
 
-	const sint16 disp_height = display_get_height() - win_get_statusbar_height() - (!ticker::empty() ? TICKER_HEIGHT : 0);
+	const sint16 disp_height = screen.h - win_get_statusbar_height() - (!ticker::empty() ? TICKER_HEIGHT : 0);
 
-	scr_rect clip_rr(0, env_t::iconsize.w, disp_width, disp_height - env_t::iconsize.h);
+	scr_rect clip_rr(0, env_t::iconsize.w, screen.w, disp_height - env_t::iconsize.h);
 	switch (env_t::menupos) {
 	case MENU_TOP:
 		// rect default
@@ -115,25 +114,26 @@ void main_view_t::display(bool force_dirty)
 		clip_rr.y = win_get_statusbar_height() + (!ticker::empty() ? TICKER_HEIGHT : 0);
 		break;
 	case MENU_LEFT:
-		clip_rr = scr_rect(env_t::iconsize.w, 0, disp_width - env_t::iconsize.w, disp_height);
+		clip_rr = scr_rect(env_t::iconsize.w, 0, screen.w - env_t::iconsize.w, disp_height);
 		break;
 	case MENU_RIGHT:
-		clip_rr = scr_rect(0, 0, disp_width - env_t::iconsize.w, disp_height);
+		clip_rr = scr_rect(0, 0, screen.w - env_t::iconsize.w, disp_height);
 		break;
 	}
-	display_set_clip_wh(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h);
+
+	g_simgraph->set_clip_rect(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h CLIP_NUM_DEFAULT, false);
 
 	// redraw everything?
 	force_dirty = force_dirty || welt->is_dirty();
 	welt->unset_dirty();
 	if(  force_dirty  ) {
-		mark_screen_dirty();
+		g_simgraph->mark_screen_dirty();
 		welt->set_background_dirty();
 		force_dirty = false;
 	}
 
-	const int dpy_width = display_get_width()/IMG_SIZE + 2;
-	const int dpy_height = (disp_real_height*4)/IMG_SIZE;
+	const int dpy_width  = screen.w / IMG_SIZE + 2;
+	const int dpy_height = (screen.h*4)/IMG_SIZE;
 
 	const int i_off = viewport->get_world_position().x + viewport->get_viewport_ij_offset().x;
 	const int j_off = viewport->get_world_position().y + viewport->get_viewport_ij_offset().y;
@@ -143,10 +143,10 @@ void main_view_t::display(bool force_dirty)
 	// change to night mode?
 	// images will be recalculated only, when there has been a change, so we set always
 	if(grund_t::underground_mode == grund_t::ugm_all) {
-		display_day_night_shift(0);
+		g_simgraph->set_daynight_level(0);
 	}
 	else if(!env_t::night_shift) {
-		display_day_night_shift(env_t::daynight_level);
+		g_simgraph->set_daynight_level(env_t::daynight_level);
 	}
 	else {
 		// calculate also days if desired
@@ -161,13 +161,13 @@ void main_view_t::display(bool force_dirty)
 		else {
 			hours2 = ( (ticks_this_month * 3) >> (welt->ticks_per_world_month_shift-4) )%48;
 		}
-		display_day_night_shift(hours2night[hours2]+env_t::daynight_level);
+		g_simgraph->set_daynight_level(hours2night[hours2]+env_t::daynight_level);
 	}
 
 	// not very elegant, but works:
 	// fill everything with black for Underground mode ...
 	if( grund_t::underground_mode ) {
-		display_fillbox_wh_rgb(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h, color_idx_to_rgb(COL_BLACK), force_dirty);
+		g_simgraph->draw_rect(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h, g_simgraph->palette_lookup(COL_BLACK), force_dirty);
 	}
 	else if( welt->is_background_dirty()  &&  outside_visible  ) {
 		// we check if background will be visible, no need to clear screen if it's not.
@@ -191,7 +191,7 @@ void main_view_t::display(bool force_dirty)
 		((y_min-(clip_rr.w - const_x_off) / (IMG_SIZE/2) - 1) >> 1) + j_off);
 
 	sint16 const worst_case_mountain_extra = (welt->max_height - welt->min_height) / 2;
-	koord const estimated_max((((dpy_height+4*4)+(disp_width - const_x_off) / (IMG_SIZE/2) - 1) >> 1) + i_off + worst_case_mountain_extra,
+	koord const estimated_max((((dpy_height+4*4)+(screen.w - const_x_off) / (IMG_SIZE/2) - 1) >> 1) + i_off + worst_case_mountain_extra,
 		(((dpy_height+4*4)-(-2-(((dpy_height+4*4)+dpy_width) & 1))) >> 1) + j_off + worst_case_mountain_extra);
 
 	rect_t view_rect(estimated_min, estimated_max - estimated_min + koord(1, 1));
@@ -249,22 +249,22 @@ void main_view_t::display(bool force_dirty)
 		simthread_barrier_wait( &display_barrier_start );
 
 		// the last we can run ourselves, setting clip_wh to the screen edge instead of wh_x (in case disp_width % num_threads != 0)
-		clear_all_poly_clip( env_t::num_threads - 1 );
-		display_set_clip_wh( lt_x, clip_rr.y, clip_rr.w, clip_rr.h, env_t::num_threads - 1 );
+		g_simgraph->clear_all_poly_clip( env_t::num_threads - 1 );
+		g_simgraph->set_clip_rect( lt_x, clip_rr.y, clip_rr.w, clip_rr.h, env_t::num_threads - 1, false);
 		display_region( koord( lt_x - IMG_SIZE / 2, clip_rr.y ), koord( clip_rr.x + clip_rr.w + IMG_SIZE, clip_rr.h ), y_min, dpy_height + 4 * 4, false, true, env_t::num_threads - 1 );
 
 		simthread_barrier_wait( &display_barrier_end );
 
-		clear_all_poly_clip( 0 );
-		display_set_clip_wh(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h);
+		g_simgraph->clear_all_poly_clip( CLIP_NUM_DEFAULT_VALUE );
+		g_simgraph->set_clip_rect(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h CLIP_NUM_DEFAULT, false);
 	}
 	else {
 		// slow serial way of display
-		clear_all_poly_clip( 0 );
+		g_simgraph->clear_all_poly_clip( CLIP_NUM_DEFAULT_VALUE );
 		display_region( koord(clip_rr.x, clip_rr.y), koord(clip_rr.w, clip_rr.h), y_min, dpy_height + 4 * 4, false, false, 0 );
 	}
 #else
-	clear_all_poly_clip();
+	g_simgraph->clear_all_poly_clip();
 	display_region(koord(clip_rr.x, clip_rr.y), koord(clip_rr.w, clip_rr.h), y_min, dpy_height + 4 * 4, false );
 #endif
 
@@ -309,17 +309,17 @@ void main_view_t::display(bool force_dirty)
 				const FLAGGED_PIXVAL transparent = TRANSPARENT25_FLAG|OUTLINE_FLAG| env_t::cursor_overlay_color;
 				if(  gr->get_image()==IMG_EMPTY  ) {
 					if(  gr->hat_wege()  ) {
-						display_img_blend( gr->obj_bei(0)->get_image(), background_pos.x, background_pos.y, transparent, 0, dirty );
+						g_simgraph->draw_img_blend( gr->obj_bei(0)->get_image(), background_pos.x, background_pos.y, transparent, 0, dirty );
 					}
 					else {
-						display_img_blend( ground_desc_t::get_ground_tile(gr), background_pos.x, background_pos.y, transparent, 0, dirty );
+						g_simgraph->draw_img_blend( ground_desc_t::get_ground_tile(gr), background_pos.x, background_pos.y, transparent, 0, dirty );
 					}
 				}
 				else if(  gr->get_typ()==grund_t::wasser  ) {
-					display_img_blend( ground_desc_t::sea->get_image(gr->get_image(),wasser_t::stage), background_pos.x, background_pos.y, transparent, 0, dirty );
+					g_simgraph->draw_img_blend( ground_desc_t::sea->get_image(gr->get_image(),wasser_t::stage), background_pos.x, background_pos.y, transparent, 0, dirty );
 				}
 				else {
-					display_img_blend( gr->get_image(), background_pos.x, background_pos.y, transparent, 0, dirty );
+					g_simgraph->draw_img_blend( gr->get_image(), background_pos.x, background_pos.y, transparent, 0, dirty );
 				}
 			}
 		}
@@ -373,14 +373,15 @@ void main_view_t::display_region( koord lt, koord wh, sint16 y_min, sint16 y_max
 void main_view_t::display_region( koord lt, koord wh, sint16 y_min, sint16 y_max, bool /*force_dirty*/ )
 #endif
 {
-	const sint16 IMG_SIZE = get_tile_raster_width();
+	const sint16 IMG_SIZE = g_simgraph->get_tile_raster_width();
 
 	const int i_off = viewport->get_world_position().x + viewport->get_viewport_ij_offset().x;
 	const int j_off = viewport->get_world_position().y + viewport->get_viewport_ij_offset().y;
 	const int const_x_off = viewport->get_x_off();
 	const int const_y_off = viewport->get_y_off();
 
-	const int dpy_width = display_get_width() / IMG_SIZE + 2;
+	const scr_size screen = g_simgraph->get_screen_size();
+	const int dpy_width = screen.w / IMG_SIZE + 2;
 
 	// to save calls to grund_t::get_disp_height
 	const sint8 hmax_ground = (grund_t::underground_mode == grund_t::ugm_level) ? grund_t::underground_level : 127;
@@ -446,7 +447,7 @@ void main_view_t::display_region( koord lt, koord wh, sint16 y_min, sint16 y_max
 					outside_visible = true;
 					if(  env_t::draw_outside_tile  ) {
 						const sint16 yypos = ypos - tile_raster_scale_y( welt->min_height * TILE_HEIGHT_STEP, IMG_SIZE );
-						display_normal( ground_desc_t::outside->get_image(0), xpos, yypos, 0, true, false  CLIP_NUM_PAR);
+						g_simgraph->draw_normal( ground_desc_t::outside->get_image(0), xpos, yypos, 0, true, false  CLIP_NUM_PAR);
 					}
 				}
 			}
@@ -596,6 +597,6 @@ void main_view_t::display_region( koord lt, koord wh, sint16 y_min, sint16 y_max
 void main_view_t::display_background( scr_coord_val xp, scr_coord_val yp, scr_coord_val w, scr_coord_val h, bool dirty )
 {
 	if(  !(env_t::draw_earth_border  &&  env_t::draw_outside_tile)  ) {
-		display_fillbox_wh_rgb(xp, yp, w, h, env_t::background_color, dirty );
+		g_simgraph->draw_rect(xp, yp, w, h, env_t::background_color, dirty );
 	}
 }
diff --git a/src/simutrans/display/viewport.cc b/src/simutrans/display/viewport.cc
index 5d1b2ecc0..89a27208d 100644
--- a/src/simutrans/display/viewport.cc
+++ b/src/simutrans/display/viewport.cc
@@ -305,9 +305,10 @@ koord3d viewport_t::get_new_cursor_position( const scr_coord &screen_pos, bool g
 
 void viewport_t::metrics_updated()
 {
-	cached_disp_width = display_get_width();
-	cached_disp_height = display_get_height();
-	cached_img_size = get_tile_raster_width();
+	const scr_size screen = g_simgraph->get_screen_size();
+	cached_disp_width  = screen.w;
+	cached_disp_height = screen.h;
+	cached_img_size    = g_simgraph->get_tile_raster_width();
 
 	set_viewport_ij_offset(koord(
 		- cached_disp_width/(2*cached_img_size) - cached_disp_height/cached_img_size,
diff --git a/src/simutrans/ground/grund.cc b/src/simutrans/ground/grund.cc
index ae3535f52..6b33409db 100644
--- a/src/simutrans/ground/grund.cc
+++ b/src/simutrans/ground/grund.cc
@@ -760,9 +760,9 @@ static inline uint8 get_back_image_from_diff(sint8 h1, sint8 h2)
 void grund_t::mark_image_dirty() const
 {
 	// see obj_t::mark_image_dirty
-	if(imageid!=IMG_EMPTY) {
-		const scr_coord scr_pos = welt->get_viewport()->get_screen_coord(koord3d(pos.get_2d(),get_disp_height()));
-		display_mark_img_dirty( imageid, scr_pos.x, scr_pos.y );
+	if (imageid != IMG_EMPTY) {
+		const scr_coord scr_pos = welt->get_viewport()->get_screen_coord(koord3d(pos.get_2d(), get_disp_height()));
+		g_simgraph->mark_img_dirty(imageid, scr_pos.x, scr_pos.y);
 	}
 }
 
@@ -963,7 +963,7 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 			// fence before a drop
 			const sint16 offset = -tile_raster_scale_y( TILE_HEIGHT_STEP*corner_nw(get_grund_hang()), raster_tile_width);
 			const uint16 typ = abs_back_imageid - grund_t::BIID_ENCODE_FENCE_OFFSET - 1 + (artificial ? grund_t::FENCE_IMAGE_COUNT : 0);
-			display_normal( ground_desc_t::fences->get_image(typ), xpos, ypos + offset, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_normal( ground_desc_t::fences->get_image(typ), xpos, ypos + offset, 0, true, dirty CLIP_NUM_PAR );
 		}
 		else {
 			// artificial slope
@@ -1005,12 +1005,12 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 							if( sl_draw->get_image( img_index ) == IMG_EMPTY ) {
 								img_index = 4 + 4 * (hgt_diff>1) + grund_t::WALL_IMAGE_COUNT * (uint16)i;
 							}
-							display_normal( sl_draw->get_image( img_index ), xpos, ypos + yoff, 0, true, dirty CLIP_NUM_PAR );
+							g_simgraph->draw_normal( sl_draw->get_image( img_index ), xpos, ypos + yoff, 0, true, dirty CLIP_NUM_PAR );
 							yoff     -= tile_raster_scale_y( TILE_HEIGHT_STEP * (hgt_diff > 1 ? 2 : 1), raster_tile_width );
 							hgt_diff -= 2;
 						}
 					}
-					display_normal( sl_draw->get_image( back_image[i] + wall_image_offset[i] ), xpos, ypos + yoff, 0, true, dirty CLIP_NUM_PAR );
+					g_simgraph->draw_normal( sl_draw->get_image( back_image[i] + wall_image_offset[i] ), xpos, ypos + yoff, 0, true, dirty CLIP_NUM_PAR );
 				}
 			}
 		}
@@ -1021,17 +1021,17 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 	if(image==IMG_EMPTY) {
 		// only check for forced redraw (of marked ... )
 		if(dirty) {
-			mark_rect_dirty_clip( xpos, ypos + raster_tile_width / 2, xpos + raster_tile_width - 1, ypos + raster_tile_width - 1 CLIP_NUM_PAR );
+			g_simgraph->mark_rect_dirty_clip( xpos, ypos + raster_tile_width / 2, xpos + raster_tile_width - 1, ypos + raster_tile_width - 1 CLIP_NUM_PAR );
 		}
 	}
 	else {
 		if(get_typ()!=wasser) {
 			// show image if tile is visible
 			if (visible)  {
-				display_normal( get_image(), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+				g_simgraph->draw_normal( get_image(), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 #ifdef SHOW_FORE_GRUND
 				if (get_flag(grund_t::draw_as_obj)) {
-					display_blend( get_image(), xpos, ypos, 0, color_idx_to_rgb(COL_RED) | OUTLINE_FLAG |TRANSPARENT50_FLAG, true, dirty CLIP_NUM_PAR );
+					g_simgraph->draw_blend( get_image(), xpos, ypos, 0, g_simgraph->palette_lookup(COL_RED) | OUTLINE_FLAG |TRANSPARENT50_FLAG, true, dirty CLIP_NUM_PAR );
 				}
 #endif
 				//display climate transitions - only needed if below snowline (snow_transition>0)
@@ -1106,7 +1106,7 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 									}
 								}
 								// overlay transition climates
-								display_alpha( ground_desc_t::get_climate_tile( transition_climate, slope ), ground_desc_t::get_alpha_tile( slope, overlay_corners ), ALPHA_GREEN | ALPHA_BLUE, xpos, ypos, 0, 0, true, dirty CLIP_NUM_PAR );
+								g_simgraph->draw_alpha( ground_desc_t::get_climate_tile( transition_climate, slope ), ground_desc_t::get_alpha_tile( slope, overlay_corners ), ALPHA_GREEN | ALPHA_BLUE, xpos, ypos, 0, 0, true, dirty CLIP_NUM_PAR );
 							}
 						}
 						slope_corner /= slope_t::southeast;
@@ -1114,19 +1114,19 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 					// finally overlay any water transition
 					if(  water_corners  ) {
 						if(  slope  ) {
-							display_alpha( ground_desc_t::get_water_tile(slope, wasser_t::stage), ground_desc_t::get_beach_tile( slope, water_corners ), ALPHA_RED, xpos, ypos, 0, 0, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
+							g_simgraph->draw_alpha( ground_desc_t::get_water_tile(slope, wasser_t::stage), ground_desc_t::get_beach_tile( slope, water_corners ), ALPHA_RED, xpos, ypos, 0, 0, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
 							if(  ground_desc_t::shore  ) {
 								// additional shore image
 								image_id shore = ground_desc_t::shore->get_image(slope,snow_transition<=0);
 								if(  shore==IMG_EMPTY  &&  snow_transition<=0  ) {
 									shore = ground_desc_t::shore->get_image(slope,0);
 								}
-								display_normal( shore, xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+								g_simgraph->draw_normal( shore, xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 							}
 						}
 						else {
 							// animate
-							display_alpha( ground_desc_t::sea->get_image(0,wasser_t::stage), ground_desc_t::get_beach_tile( slope, water_corners ), ALPHA_RED, xpos, ypos, 0, 0, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
+							g_simgraph->draw_alpha( ground_desc_t::sea->get_image(0,wasser_t::stage), ground_desc_t::get_beach_tile( slope, water_corners ), ALPHA_RED, xpos, ypos, 0, 0, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
 						}
 					}
 				}
@@ -1136,12 +1136,12 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 					// the gehweg flag is used for rail switches, but a slope has no switches ...
 					switch(  snow_transition  ) {
 						case 1: {
-							display_alpha( ground_desc_t::get_snow_tile(slope), ground_desc_t::get_alpha_tile(slope), ALPHA_GREEN | ALPHA_BLUE, xpos, ypos, 0, 0, true, dirty CLIP_NUM_PAR );
+							g_simgraph->draw_alpha( ground_desc_t::get_snow_tile(slope), ground_desc_t::get_alpha_tile(slope), ALPHA_GREEN | ALPHA_BLUE, xpos, ypos, 0, 0, true, dirty CLIP_NUM_PAR );
 							break;
 						}
 						case 2: {
 							if(  slope_t::max_diff(slope) > 1  ) {
-								display_alpha( ground_desc_t::get_snow_tile(slope), ground_desc_t::get_alpha_tile(slope), ALPHA_BLUE, xpos, ypos, 0, 0, true, dirty CLIP_NUM_PAR );
+								g_simgraph->draw_alpha( ground_desc_t::get_snow_tile(slope), ground_desc_t::get_alpha_tile(slope), ALPHA_BLUE, xpos, ypos, 0, 0, true, dirty CLIP_NUM_PAR );
 							}
 							break;
 						}
@@ -1156,17 +1156,17 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 				if(  show_grid  ){
 #endif
 					const uint8 hang = get_grund_hang();
-					display_normal( ground_desc_t::get_border_image(hang), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+					g_simgraph->draw_normal( ground_desc_t::get_border_image(hang), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 				}
 			}
 		}
 		else {
 			// take animation into account
 			if(  underground_mode != ugm_all  ) {
-				display_normal( ground_desc_t::sea->get_image(get_image(),wasser_t::stage), xpos, ypos, 0, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
+				g_simgraph->draw_normal( ground_desc_t::sea->get_image(get_image(),wasser_t::stage), xpos, ypos, 0, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
 			}
 			else {
-				display_blend( ground_desc_t::sea->get_image(get_image(),wasser_t::stage), xpos, ypos, 0, TRANSPARENT50_FLAG, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
+				g_simgraph->draw_blend( ground_desc_t::sea->get_image(get_image(),wasser_t::stage), xpos, ypos, 0, TRANSPARENT50_FLAG, true, dirty|wasser_t::change_stage CLIP_NUM_PAR );
 			}
 			return;
 		}
@@ -1181,23 +1181,23 @@ void grund_t::display_boden(const sint16 xpos, const sint16 ypos, const sint16 r
 			// .. nonconvex n/w if not both n/w are active
 			if(  clip  ) {
 				const ribi_t::ribi way_ribi = (static_cast<const weg_t*>(d))->get_ribi_unmasked();
-				clear_all_poly_clip( CLIP_NUM_VAR );
+				g_simgraph->clear_all_poly_clip( CLIP_NUM_VAR );
 				const uint8 non_convex = (way_ribi & ribi_t::northwest) == ribi_t::northwest ? 0 : 16;
 				if(  way_ribi & ribi_t::west  ) {
 					const int dh = corner_nw(get_disp_way_slope()) * hgt_step;
-					add_poly_clip( xpos + raster_tile_width / 2 - 1, ypos + raster_tile_width / 2 - dh, xpos - 1, ypos + 3 * raster_tile_width / 4 - dh, ribi_t::west | non_convex CLIP_NUM_PAR );
+					g_simgraph->add_poly_clip( xpos + raster_tile_width / 2 - 1, ypos + raster_tile_width / 2 - dh, xpos - 1, ypos + 3 * raster_tile_width / 4 - dh, ribi_t::west | non_convex CLIP_NUM_PAR );
 				}
 				if(  way_ribi & ribi_t::north  ) {
 					const int dh = corner_nw(get_disp_way_slope()) * hgt_step;
-					add_poly_clip( xpos + raster_tile_width, ypos + 3 * raster_tile_width / 4 - dh, xpos + raster_tile_width / 2, ypos + raster_tile_width / 2 - dh, ribi_t::north | non_convex CLIP_NUM_PAR );
+					g_simgraph->add_poly_clip( xpos + raster_tile_width, ypos + 3 * raster_tile_width / 4 - dh, xpos + raster_tile_width / 2, ypos + raster_tile_width / 2 - dh, ribi_t::north | non_convex CLIP_NUM_PAR );
 				}
-				activate_ribi_clip( (way_ribi & ribi_t::northwest) | non_convex  CLIP_NUM_PAR );
+				g_simgraph->activate_ribi_clip( (way_ribi & ribi_t::northwest) | non_convex  CLIP_NUM_PAR );
 			}
 			d->display( xpos, ypos CLIP_NUM_PAR );
 		}
 		// end of clipping
 		if(  clip  ) {
-			clear_all_poly_clip( CLIP_NUM_VAR );
+			g_simgraph->clear_all_poly_clip( CLIP_NUM_VAR );
 		}
 	}
 }
@@ -1223,17 +1223,17 @@ void grund_t::display_border( sint16 xpos, sint16 ypos, const sint16 raster_tile
 		diff = -min(corner_sw(slope),corner_se(slope));
 		sint16 zz = pos.z-welt->get_groundwater();
 		if(  diff < zz && ((zz-diff)&1)==1  ) {
-			display_normal( ground_desc_t::slopes->get_image(15), x, y, 0, true, false CLIP_NUM_PAR );
+			g_simgraph->draw_normal( ground_desc_t::slopes->get_image(15), x, y, 0, true, false CLIP_NUM_PAR );
 			y -= hgt_step;
 			diff++;
 		}
 		// ok, now we have the height; since the slopes may end with a fence they are drawn in reverse order
 		while(  diff < zz  ) {
-			display_normal( ground_desc_t::slopes->get_image(19), x, y, 0, true, false CLIP_NUM_PAR );
+			g_simgraph->draw_normal( ground_desc_t::slopes->get_image(19), x, y, 0, true, false CLIP_NUM_PAR );
 			y -= hgt_step*2;
 			diff+=2;
 		}
-		display_normal( slope_img, x, y, 0, true, false CLIP_NUM_PAR );
+		g_simgraph->draw_normal( slope_img, x, y, 0, true, false CLIP_NUM_PAR );
 	}
 
 	if(  pos.x-welt->get_size().x+1 == 0  ) {
@@ -1246,17 +1246,17 @@ void grund_t::display_border( sint16 xpos, sint16 ypos, const sint16 raster_tile
 		diff = -min(corner_se(slope),corner_ne(slope));
 		sint16 zz = pos.z-welt->get_groundwater();
 		if(  diff < zz && ((zz-diff)&1)==1  ) {
-			display_normal( ground_desc_t::slopes->get_image(4), x, y, 0, true, false CLIP_NUM_PAR );
+			g_simgraph->draw_normal( ground_desc_t::slopes->get_image(4), x, y, 0, true, false CLIP_NUM_PAR );
 			y -= hgt_step;
 			diff++;
 		}
 		// ok, now we have the height; since the slopes may end with a fence they are drawn in reverse order
 		while(  diff < zz  ) {
-			display_normal( ground_desc_t::slopes->get_image(8), x, y, 0, true, false CLIP_NUM_PAR );
+			g_simgraph->draw_normal( ground_desc_t::slopes->get_image(8), x, y, 0, true, false CLIP_NUM_PAR );
 			y -= hgt_step*2;
 			diff+=2;
 		}
-		display_normal( slope_img, x, y, 0, true, false CLIP_NUM_PAR );
+		g_simgraph->draw_normal( slope_img, x, y, 0, true, false CLIP_NUM_PAR );
 	}
 }
 
@@ -1270,7 +1270,7 @@ void grund_t::display_if_visible(sint16 xpos, sint16 ypos, const sint16 raster_t
 	if(  !is_karten_boden_visible()  ) {
 		// only check for forced redraw (of marked ... )
 		if(  get_flag(grund_t::dirty)  ) {
-			mark_rect_dirty_clip( xpos, ypos + raster_tile_width / 2, xpos + raster_tile_width - 1, ypos + raster_tile_width - 1 CLIP_NUM_PAR );
+			g_simgraph->mark_rect_dirty_clip( xpos, ypos + raster_tile_width / 2, xpos + raster_tile_width - 1, ypos + raster_tile_width - 1 CLIP_NUM_PAR );
 		}
 		return;
 	}
@@ -1338,31 +1338,31 @@ void grund_t::display_obj_all_quick_and_dirty(const sint16 xpos, sint16 ypos, co
 	if(  visible  ) {
 		if(  is_global  &&  get_flag( grund_t::marked )  ) {
 			const uint8 hang = get_grund_hang();
-			display_img_aux( ground_desc_t::get_marker_image( hang, true ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_img_aux( ground_desc_t::get_marker_image( hang, true ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 #ifdef MULTI_THREAD
 			objlist.display_obj_quick_and_dirty( xpos, ypos, start_offset CLIP_NUM_PAR );
 #else
 			objlist.display_obj_quick_and_dirty( xpos, ypos, start_offset, is_global );
 #endif
-			display_img_aux( ground_desc_t::get_marker_image( hang, false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_img_aux( ground_desc_t::get_marker_image( hang, false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 			if(  !ist_karten_boden()  ) {
 				const grund_t *gr = welt->lookup_kartenboden(pos.get_2d());
 				if(  pos.z > gr->get_hoehe()  ) {
 					//display front part of marker for grunds in between
 					for(  sint8 z = pos.z - 1;  z > gr->get_hoehe();  z--  ) {
-						display_img_aux( ground_desc_t::get_marker_image(0, false), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+						g_simgraph->draw_img_aux( ground_desc_t::get_marker_image(0, false), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 					}
 					//display front part of marker for ground
-					display_img_aux( ground_desc_t::get_marker_image( gr->get_grund_hang(), false ), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+					g_simgraph->draw_img_aux( ground_desc_t::get_marker_image( gr->get_grund_hang(), false ), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 				}
 				else if(  pos.z < gr->get_disp_height()  ) {
 					//display back part of marker for grunds in between
 					for(  sint8 z = pos.z + 1;  z < gr->get_disp_height();  z++  ) {
-						display_img_aux( ground_desc_t::get_border_image(0), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+						g_simgraph->draw_img_aux( ground_desc_t::get_border_image(0), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 					}
 					//display back part of marker for ground
 					const uint8 kbhang = gr->get_grund_hang() | gr->get_weg_hang();
-					display_img_aux( ground_desc_t::get_border_image(kbhang), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+					g_simgraph->draw_img_aux( ground_desc_t::get_border_image(kbhang), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 				}
 			}
 		}
@@ -1377,11 +1377,12 @@ void grund_t::display_obj_all_quick_and_dirty(const sint16 xpos, sint16 ypos, co
 	else { // must be karten_boden
 		// in undergroundmode: draw ground grid
 		const uint8 hang = underground_mode==ugm_all ? get_grund_hang() : (uint8)slope_t::flat;
-		display_img_aux( ground_desc_t::get_border_image(hang), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+		g_simgraph->draw_img_aux( ground_desc_t::get_border_image(hang), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+
 		// show marker for marked but invisible tiles
 		if(  is_global  &&  get_flag(grund_t::marked)  ) {
-			display_img_aux( ground_desc_t::get_marker_image( hang, true ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
-			display_img_aux( ground_desc_t::get_marker_image( hang, false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_img_aux( ground_desc_t::get_marker_image( hang, true ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_img_aux( ground_desc_t::get_marker_image( hang, false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 		}
 	}
 }
@@ -1415,7 +1416,7 @@ void grund_t::display_obj_all(const sint16 xpos, const sint16 ypos, const sint16
 	}
 
 	// end of clipping
-	clear_all_poly_clip( CLIP_NUM_VAR );
+	g_simgraph->clear_all_poly_clip( CLIP_NUM_VAR );
 
 	// here: we are either ground(kartenboden) or visible
 	const bool visible = !ist_karten_boden()  ||  is_karten_boden_visible();
@@ -1461,34 +1462,34 @@ void grund_t::display_obj_all(const sint16 xpos, const sint16 ypos, const sint16
 	const uint8 non_convex = ((ribi & ribi_t::northwest) == ribi_t::northwest)  &&  back_imageid ? 0 : 16;
 	if(  ribi & ribi_t::west  ) {
 		const int dh = corner_nw(slope) * hgt_step;
-		add_poly_clip( xpos + raster_tile_width / 2 - 1, ypos + raster_tile_width / 2 - dh, xpos - 1, ypos + 3 * raster_tile_width / 4 - dh, ribi_t::west | non_convex CLIP_NUM_PAR );
+		g_simgraph->add_poly_clip( xpos + raster_tile_width / 2 - 1, ypos + raster_tile_width / 2 - dh, xpos - 1, ypos + 3 * raster_tile_width / 4 - dh, ribi_t::west | non_convex CLIP_NUM_PAR );
 	}
 	if(  ribi & ribi_t::north  ) {
 		const int dh = corner_nw(slope) * hgt_step;
-		add_poly_clip( xpos + raster_tile_width, ypos + 3 * raster_tile_width / 4 - dh, xpos + raster_tile_width / 2, ypos + raster_tile_width / 2 - dh, ribi_t::north | non_convex CLIP_NUM_PAR );
+		g_simgraph->add_poly_clip( xpos + raster_tile_width, ypos + 3 * raster_tile_width / 4 - dh, xpos + raster_tile_width / 2, ypos + raster_tile_width / 2 - dh, ribi_t::north | non_convex CLIP_NUM_PAR );
 	}
 	if(  ribi & ribi_t::east  ) {
 		const int dh = corner_se(slope) * hgt_step;
-		add_poly_clip( xpos + raster_tile_width / 2, ypos + raster_tile_width - dh, xpos + raster_tile_width, ypos + 3 * raster_tile_width / 4 - dh, ribi_t::east|16 CLIP_NUM_PAR );
+		g_simgraph->add_poly_clip( xpos + raster_tile_width / 2, ypos + raster_tile_width - dh, xpos + raster_tile_width, ypos + 3 * raster_tile_width / 4 - dh, ribi_t::east|16 CLIP_NUM_PAR );
 	}
 	if(  ribi & ribi_t::south  ) {
 		const int dh = corner_se(slope) * hgt_step;
-		add_poly_clip( xpos- 1, ypos + 3 * raster_tile_width / 4  - dh, xpos + raster_tile_width / 2 - 1, ypos + raster_tile_width  - dh, ribi_t::south|16  CLIP_NUM_PAR );
+		g_simgraph->add_poly_clip( xpos- 1, ypos + 3 * raster_tile_width / 4  - dh, xpos + raster_tile_width / 2 - 1, ypos + raster_tile_width  - dh, ribi_t::south|16  CLIP_NUM_PAR );
 	}
 
 	// display background
 	if (!tunnel_portal  ||  slope == slope_t::flat) {
-		activate_ribi_clip( (ribi_t::northwest & ribi) | 16 CLIP_NUM_PAR );
+		g_simgraph->activate_ribi_clip( (ribi_t::northwest & ribi) | 16 CLIP_NUM_PAR );
 	}
 	else {
 		// also clip along the upper edge of the tunnel tile
-		activate_ribi_clip( ribi | 16 CLIP_NUM_PAR );
+		g_simgraph->activate_ribi_clip( ribi | 16 CLIP_NUM_PAR );
 	}
 	// get offset of first vehicle
 	const uint8 offset_vh = display_obj_bg( xpos, ypos, is_global, false, visible CLIP_NUM_PAR );
 	if(  !visible  ) {
 		// end of clipping
-		clear_all_poly_clip( CLIP_NUM_VAR );
+		g_simgraph->clear_all_poly_clip( CLIP_NUM_VAR );
 		return;
 	}
 	// display vehicles of w/nw/n neighbors
@@ -1529,7 +1530,7 @@ void grund_t::display_obj_all(const sint16 xpos, const sint16 ypos, const sint16
 		grund_t *gr;
 		if(  get_neighbour( gr, invalid_wt, ribi_t::east )  ) {
 			const bool draw_other_ways = (flags&draw_as_obj)  ||  (gr->flags&draw_as_obj)  ||  !gr->ist_karten_boden();
-			activate_ribi_clip( ribi_t::east|16 CLIP_NUM_PAR );
+			g_simgraph->activate_ribi_clip( ribi_t::east|16 CLIP_NUM_PAR );
 			gr->display_obj_bg( xpos + raster_tile_width / 2, ypos + raster_tile_width / 4 - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), is_global, draw_other_ways, true CLIP_NUM_PAR );
 		}
 	}
@@ -1537,7 +1538,7 @@ void grund_t::display_obj_all(const sint16 xpos, const sint16 ypos, const sint16
 		grund_t *gr;
 		if(  get_neighbour( gr, invalid_wt, ribi_t::south )  ) {
 			const bool draw_other_ways = (flags&draw_as_obj)  ||  (gr->flags&draw_as_obj)  ||  !gr->ist_karten_boden();
-			activate_ribi_clip( ribi_t::south|16 CLIP_NUM_PAR );
+			g_simgraph->activate_ribi_clip( ribi_t::south|16 CLIP_NUM_PAR );
 			gr->display_obj_bg( xpos - raster_tile_width / 2, ypos + raster_tile_width / 4 - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), is_global, draw_other_ways, true CLIP_NUM_PAR );
 		}
 	}
@@ -1582,16 +1583,16 @@ void grund_t::display_obj_all(const sint16 xpos, const sint16 ypos, const sint16
 	// foreground
 	if (tunnel_portal  &&  slope != 0) {
 		// clip at the upper edge
-		activate_ribi_clip( (ribi & (corner_se(slope)>0 ?  ribi_t::southeast : ribi_t::northwest) )| 16 CLIP_NUM_PAR );
+		g_simgraph->activate_ribi_clip( (ribi & (corner_se(slope)>0 ?  ribi_t::southeast : ribi_t::northwest) )| 16 CLIP_NUM_PAR );
 	}
 	else {
-		clear_all_poly_clip( CLIP_NUM_VAR );
+		g_simgraph->clear_all_poly_clip( CLIP_NUM_VAR );
 	}
 	display_obj_fg( xpos, ypos, is_global, offset_fg CLIP_NUM_PAR );
 
 	// end of clipping
 	if (tunnel_portal) {
-		clear_all_poly_clip( CLIP_NUM_VAR );
+		g_simgraph->clear_all_poly_clip( CLIP_NUM_VAR );
 	}
 }
 
@@ -1603,17 +1604,18 @@ uint8 grund_t::display_obj_bg(const sint16 xpos, const sint16 ypos, const bool i
 	if(  visible  ) {
 		// display back part of markers
 		if(  is_global  &&  get_flag( grund_t::marked )  ) {
-			display_normal( ground_desc_t::get_marker_image( get_grund_hang(), true ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_normal( ground_desc_t::get_marker_image( get_grund_hang(), true ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 			if(  !ist_karten_boden()  ) {
 				const grund_t *gr = welt->lookup_kartenboden(pos.get_2d());
-				const sint16 raster_tile_width = get_current_tile_raster_width();
+				const sint16 raster_tile_width = g_simgraph->get_current_tile_raster_width();
+
 				if(  pos.z < gr->get_disp_height()  ) {
 					//display back part of marker for grunds in between
 					for(  sint8 z = pos.z + 1;  z < gr->get_disp_height();  z++  ) {
-						display_normal( ground_desc_t::get_marker_image(0, true), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+						g_simgraph->draw_normal( ground_desc_t::get_marker_image(0, true), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 					}
 					//display back part of marker for ground
-					display_normal( ground_desc_t::get_marker_image( gr->get_grund_hang() | gr->get_weg_hang(), true ), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+					g_simgraph->draw_normal( ground_desc_t::get_marker_image( gr->get_grund_hang() | gr->get_weg_hang(), true ), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 				}
 			}
 		}
@@ -1624,11 +1626,11 @@ uint8 grund_t::display_obj_bg(const sint16 xpos, const sint16 ypos, const bool i
 	else { // must be karten_boden
 		// in undergroundmode: draw ground grid
 		const uint8 hang = underground_mode == ugm_all ? get_grund_hang() : (slope_t::type)slope_t::flat;
-		display_normal( ground_desc_t::get_border_image(hang), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+		g_simgraph->draw_normal( ground_desc_t::get_border_image(hang), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 		// show marker for marked but invisible tiles
 		if(  is_global  &&  get_flag( grund_t::marked )  ) {
-			display_img_aux( ground_desc_t::get_marker_image( hang, true ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
-			display_img_aux( ground_desc_t::get_marker_image( hang, false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_img_aux( ground_desc_t::get_marker_image( hang, true  ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+			g_simgraph->draw_img_aux( ground_desc_t::get_marker_image( hang, false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 		}
 		return 255;
 	}
@@ -1651,17 +1653,17 @@ void grund_t::display_obj_fg(const sint16 xpos, const sint16 ypos, const bool is
 #endif
 	// display front part of markers
 	if(  is_global  &&  get_flag( grund_t::marked )  ) {
-		display_normal( ground_desc_t::get_marker_image( get_grund_hang(), false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
+		g_simgraph->draw_normal( ground_desc_t::get_marker_image( get_grund_hang(), false ), xpos, ypos, 0, true, dirty CLIP_NUM_PAR );
 		if(  !ist_karten_boden()  ) {
 			const grund_t *gr = welt->lookup_kartenboden(pos.get_2d());
-			const sint16 raster_tile_width = get_tile_raster_width();
+			const sint16 raster_tile_width = g_simgraph->get_tile_raster_width();
 			if(  pos.z > gr->get_hoehe()  ) {
 				//display front part of marker for grunds in between
 				for(  sint8 z = pos.z - 1;  z > gr->get_hoehe();  z--  ) {
-					display_normal( ground_desc_t::get_marker_image( 0, false ), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+					g_simgraph->draw_normal( ground_desc_t::get_marker_image( 0, false ), xpos, ypos - tile_raster_scale_y( (z - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 				}
 				//display front part of marker for ground
-				display_normal( ground_desc_t::get_marker_image( gr->get_grund_hang(), false ), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
+				g_simgraph->draw_normal( ground_desc_t::get_marker_image( gr->get_grund_hang(), false ), xpos, ypos - tile_raster_scale_y( (gr->get_hoehe() - pos.z) * TILE_HEIGHT_STEP, raster_tile_width ), 0, true, true CLIP_NUM_PAR );
 			}
 		}
 	}
@@ -1673,22 +1675,23 @@ void display_text_label(sint16 xpos, sint16 ypos, const char* text, const player
 {
 	switch( env_t::show_names >> 2 ) {
 		case 0: {
-			const PIXVAL bg_color = player ? color_idx_to_rgb(player->get_player_color1()+4) : SYSCOL_TEXT_HIGHLIGHT;
-			display_ddd_proportional_clip( xpos, ypos, bg_color, color_idx_to_rgb(COL_BLACK), text, dirty );
+			const PIXVAL bg_color = player ? g_simgraph->palette_lookup(player->get_player_color1()+4) : SYSCOL_TEXT_HIGHLIGHT;
+			g_simgraph->draw_textbox3d_clipped( xpos, ypos, bg_color, g_simgraph->palette_lookup(COL_BLACK), text, dirty CLIP_NUM_DEFAULT);
 			break;
 		}
 		case 1: {
-			const PIXVAL text_color = player ? color_idx_to_rgb(player->get_player_color1()+7) : SYSCOL_TEXT_HIGHLIGHT;
-			display_outline_proportional_rgb( xpos, ypos, text_color, color_idx_to_rgb(COL_BLACK), text, dirty );
+			const PIXVAL text_color = player ? g_simgraph->palette_lookup(player->get_player_color1()+7) : SYSCOL_TEXT_HIGHLIGHT;
+			g_simgraph->draw_text_outlined(xpos, ypos, text_color, g_simgraph->palette_lookup(COL_BLACK), text, dirty);
 			break;
 		}
 		case 2: {
-			const PIXVAL dark   = player ? color_idx_to_rgb(player->get_player_color1()+2) : SYSCOL_TEXT_HIGHLIGHT;
-			const PIXVAL normal = player ? color_idx_to_rgb(player->get_player_color1()+4) : SYSCOL_TEXT_HIGHLIGHT;
-			const PIXVAL bright = player ? color_idx_to_rgb(player->get_player_color1()+6) : SYSCOL_TEXT_HIGHLIGHT;
-			display_outline_proportional_rgb( xpos + LINESPACE + D_H_SPACE, ypos,   color_idx_to_rgb(COL_YELLOW), color_idx_to_rgb(COL_BLACK), text, dirty );
-			display_ddd_box_clip_rgb(         xpos,                         ypos,   LINESPACE,   LINESPACE,   dark, PLAYER_FLAG|bright );
-			display_fillbox_wh_rgb(           xpos+1,                       ypos+1, LINESPACE-2, LINESPACE-2, normal, dirty );
+			const PIXVAL dark   = player ? g_simgraph->palette_lookup(player->get_player_color1()+2) : SYSCOL_TEXT_HIGHLIGHT;
+			const PIXVAL normal = player ? g_simgraph->palette_lookup(player->get_player_color1()+4) : SYSCOL_TEXT_HIGHLIGHT;
+			const PIXVAL bright = player ? g_simgraph->palette_lookup(player->get_player_color1()+6) : SYSCOL_TEXT_HIGHLIGHT;
+
+			g_simgraph->draw_text_outlined( xpos + LINESPACE + D_H_SPACE, ypos,   g_simgraph->palette_lookup(COL_YELLOW), g_simgraph->palette_lookup(COL_BLACK), text, dirty );
+			g_simgraph->draw_box3d_clipped( xpos,                         ypos,   LINESPACE,   LINESPACE,   dark, PLAYER_FLAG|bright );
+			g_simgraph->draw_rect(          xpos+1,                       ypos+1, LINESPACE-2, LINESPACE-2, normal, dirty );
 			break;
 		}
 	}
@@ -1705,8 +1708,8 @@ void grund_t::display_overlay(const sint16 xpos, const sint16 ypos)
 	if(  get_flag(has_text)  ) {
 		if(  env_t::show_names & 1  ) {
 			const char *text = get_text();
-			const sint16 raster_tile_width = get_tile_raster_width();
-			const int width = proportional_string_width(text)+7;
+			const sint16 raster_tile_width = g_simgraph->get_tile_raster_width();
+			const int width = g_simgraph->calc_text_width(text) + 7;
 			int new_xpos = xpos - (width-raster_tile_width)/2;
 
 			const player_t* owner = get_label_owner();
@@ -1727,9 +1730,9 @@ void grund_t::display_overlay(const sint16 xpos, const sint16 ypos)
 		if( gebaeude_t *gb=find<gebaeude_t>() ) {
 			if(  fabrik_t* fab = gb->get_fabrik()  ) {
 				if( env_t::show_factory_storage_bar == 1  &&  welt->get_zeiger()->get_pos() == get_pos() ) {
-					const sint16 raster_tile_width = get_tile_raster_width();
+					const sint16 raster_tile_width = g_simgraph->get_tile_raster_width();
 					const char* text = fab->get_name();
-					const int width = proportional_string_width( text )+7;
+					const int width = g_simgraph->calc_text_width(text) + 7;
 					sint16 new_xpos = xpos - (width-raster_tile_width)/2;
 					sint16 new_ypos = ypos + 5;
 //					display_text_label( new_xpos, new_ypos, text, fab->get_owner(), dirty );
@@ -1741,8 +1744,8 @@ void grund_t::display_overlay(const sint16 xpos, const sint16 ypos)
 					if(  env_t::show_factory_storage_bar == 3  ||  (env_t::show_factory_storage_bar == 2  &&  fab->is_within_players_network( welt->get_active_player() ))  ) {
 						// name of factory
 						const char* text = fab->get_name();
-						const sint16 raster_tile_width = get_tile_raster_width();
-						const sint16 width = proportional_string_width( text )+7;
+						const sint16 raster_tile_width = g_simgraph->get_tile_raster_width();
+						const sint16 width = g_simgraph->calc_text_width(text) + 7;
 						sint16 new_xpos = xpos - (width-raster_tile_width)/2;
 						display_text_label( new_xpos, ypos, text, fab->get_owner(), dirty );
 						// ... and status
@@ -1757,8 +1760,8 @@ void grund_t::display_overlay(const sint16 xpos, const sint16 ypos)
 		if( weg_t* w = get_weg_nr( 0 ) ) {
 			if( w->has_signal() ) {
 				// display arrow here
-				PIXVAL c1 = color_idx_to_rgb( COL_GREEN+2 );
-				PIXVAL c2 = color_idx_to_rgb( COL_GREEN );
+				PIXVAL c1 = g_simgraph->palette_lookup( COL_GREEN+2 );
+				PIXVAL c2 = g_simgraph->palette_lookup( COL_GREEN );
 
 				ribi_t::ribi mask = w->get_ribi_maske();
 				if( !mask ) {
@@ -1767,17 +1770,17 @@ void grund_t::display_overlay(const sint16 xpos, const sint16 ypos)
 
 				if( signal_t* sig = find<signal_t>() ) {
 					if( sig->get_state()==roadsign_t::signalstate::STATE_RED ) {
-						c1 = color_idx_to_rgb( COL_ORANGE+2 );
-						c2 = color_idx_to_rgb( COL_ORANGE );
+						c1 = g_simgraph->palette_lookup( COL_ORANGE+2 );
+						c2 = g_simgraph->palette_lookup( COL_ORANGE );
 					}
 				}
-				display_signal_direction_rgb( xpos, ypos + tile_raster_scale_y( w->get_yoff(), get_current_tile_raster_width() ),
+				g_simgraph->draw_signal_direction( xpos, ypos + tile_raster_scale_y( w->get_yoff(), g_simgraph->get_current_tile_raster_width() ),
 					w->get_ribi_unmasked(), mask, c1, c2, w->is_diagonal(), get_weg_hang() );
 			}
 			else if( w->get_ribi_maske() ) {
-				PIXVAL c1 = color_idx_to_rgb( COL_BLUE+2 );
-				PIXVAL c2 = color_idx_to_rgb( COL_BLUE );
-				display_signal_direction_rgb( xpos, ypos + tile_raster_scale_y( w->get_yoff(), get_current_tile_raster_width() ),
+				PIXVAL c1 = g_simgraph->palette_lookup( COL_BLUE+2 );
+				PIXVAL c2 = g_simgraph->palette_lookup( COL_BLUE );
+				g_simgraph->draw_signal_direction( xpos, ypos + tile_raster_scale_y( w->get_yoff(), g_simgraph->get_current_tile_raster_width() ),
 					w->get_ribi_unmasked(), w->get_ribi_maske(), c1, c2, w->is_diagonal(), get_weg_hang() );
 			}
 		}
@@ -1818,6 +1821,7 @@ bool grund_t::weg_erweitern(waytype_t wegtyp, ribi_t::ribi ribi)
 	if(weg) {
 		weg->ribi_add(ribi);
 		weg->count_sign();
+
 		if(weg->is_electrified()) {
 			wayobj_t *wo = get_wayobj( wegtyp );
 			if( (ribi & wo->get_dir()) == 0 ) {
@@ -1837,10 +1841,12 @@ bool grund_t::weg_erweitern(waytype_t wegtyp, ribi_t::ribi ribi)
 				}
 			}
 		}
+
 		calc_image();
 		set_flag(dirty);
 		return true;
 	}
+
 	return false;
 }
 
diff --git a/src/simutrans/gui/banner.cc b/src/simutrans/gui/banner.cc
index 4cd3d9804..cd3f39872 100644
--- a/src/simutrans/gui/banner.cc
+++ b/src/simutrans/gui/banner.cc
@@ -160,7 +160,7 @@ banner_t::banner_t() : gui_frame_t("")
 
 		add_table(1,0);
 		{
-		new_component<gui_label_t>("Selling of the program is forbidden.", color_idx_to_rgb(COL_RED), gui_label_t::left)->set_shadow(SYSCOL_TEXT_SHADOW, true);
+		new_component<gui_label_t>("Selling of the program is forbidden.", g_simgraph->palette_lookup(COL_RED), gui_label_t::left)->set_shadow(SYSCOL_TEXT_SHADOW, true);
 		new_component<gui_label_t>("For questions and support please visit:", SYSCOL_TEXT_TITLE, gui_label_t::left)->set_shadow(SYSCOL_TEXT_SHADOW, true);
 		}
 		end_table();
@@ -198,7 +198,7 @@ banner_t::banner_t() : gui_frame_t("")
 
 	reset_min_windowsize();
 
-	if (get_windowsize().w > display_get_width()) {
+	if (get_windowsize().w > g_simgraph->get_screen_size().w) {
 		image1->set_visible(true);
 		image2->set_visible(false);
 		reset_min_windowsize();
@@ -291,9 +291,9 @@ void banner_text_t::draw(scr_coord offset)
 
 	PUSH_CLIP_FIT( left, cursor.y, width, height );
 
-	display_fillbox_wh_clip_rgb(left, cursor.y,          width, height, color_idx_to_rgb(COL_GREY1), true);
-	display_fillbox_wh_clip_rgb(left, cursor.y - 1,      width, 1,      color_idx_to_rgb(COL_GREY3), false);
-	display_fillbox_wh_clip_rgb(left, cursor.y + height, width, 1,      color_idx_to_rgb(COL_GREY6), false);
+	g_simgraph->draw_rect_clipped(left, cursor.y,          width, height, g_simgraph->palette_lookup(COL_GREY1), true  CLIP_NUM_DEFAULT);
+	g_simgraph->draw_rect_clipped(left, cursor.y - 1,      width, 1,      g_simgraph->palette_lookup(COL_GREY3), false CLIP_NUM_DEFAULT);
+	g_simgraph->draw_rect_clipped(left, cursor.y + height, width, 1,      g_simgraph->palette_lookup(COL_GREY6), false CLIP_NUM_DEFAULT);
 
 	cursor.y++;
 
@@ -301,14 +301,14 @@ void banner_text_t::draw(scr_coord offset)
 
 		PIXVAL color;
 		if(  row > L_BANNER_ROWS-COLOR_RAMP_SIZE+1  ) {
-			color = color_idx_to_rgb(colors[L_BANNER_ROWS-row+1]);
+			color = g_simgraph->palette_lookup(colors[L_BANNER_ROWS-row+1]);
 		}
 		else {
-			color = color_idx_to_rgb(colors[0]);
+			color = g_simgraph->palette_lookup(colors[0]);
 		}
 
-		display_proportional_clip_rgb( left + L_BANNER_TEXT_INDENT,         cursor.y - text_offset, scrolltext[text_line + row*2    ], ALIGN_LEFT,  color, false);
-		display_proportional_clip_rgb( left + width - L_BANNER_TEXT_INDENT, cursor.y - text_offset, scrolltext[text_line + row*2 + 1], ALIGN_RIGHT, color, false);
+		g_simgraph->draw_text_clipped( left +         L_BANNER_TEXT_INDENT, cursor.y - text_offset, scrolltext[text_line + row*2    ], ALIGN_LEFT,  color, false);
+		g_simgraph->draw_text_clipped( left + width - L_BANNER_TEXT_INDENT, cursor.y - text_offset, scrolltext[text_line + row*2 + 1], ALIGN_RIGHT, color, false);
 
 		cursor.y += LINESPACE;
 	}
@@ -324,5 +324,4 @@ void banner_text_t::draw(scr_coord offset)
 	if (scrolltext[text_line + (L_BANNER_ROWS+1)*2] == 0) {
 		line = 0;
 	}
-
 }
diff --git a/src/simutrans/gui/chat_frame.cc b/src/simutrans/gui/chat_frame.cc
index 14feabd65..5b4739305 100644
--- a/src/simutrans/gui/chat_frame.cc
+++ b/src/simutrans/gui/chat_frame.cc
@@ -56,7 +56,7 @@ public:
 			bt_whisper_to.add_listener(this);
 			add_component(&bt_whisper_to);
 			buf.printf("%s <%s>", sender.c_str(), p->get_name());
-			new_component<gui_label_t>(buf.get_str(), color_idx_to_rgb(p->get_player_color1() + env_t::gui_player_color_dark));
+			new_component<gui_label_t>(buf.get_str(), g_simgraph->palette_lookup(p->get_player_color1() + env_t::gui_player_color_dark));
 		}
 		else {
 			new_component_span<gui_label_t>(sender.c_str(), 2);
@@ -163,8 +163,10 @@ public:
 		const bool is_dark_theme = (env_t::gui_player_color_dark >= env_t::gui_player_color_bright);
 		const int base_blend_percent = tail_dir == tail_right ? 60 : 80;
 		player_t* player = world()->get_player(player_nr);
-		const PIXVAL base_color = color_idx_to_rgb(player ? player->get_player_color1() + env_t::gui_player_color_bright : COL_GREY4);
-		bgcolor = display_blend_colors(base_color, color_idx_to_rgb(COL_WHITE), is_dark_theme ? (95 - base_blend_percent) : base_blend_percent);
+		const PIXVAL base_color = g_simgraph->palette_lookup(player ? player->get_player_color1() + env_t::gui_player_color_bright : COL_GREY4);
+
+		bgcolor = g_simgraph->blend_colors(base_color, g_simgraph->palette_lookup(COL_WHITE), is_dark_theme ? (95 - base_blend_percent) : base_blend_percent);
+
 		if (msg_time) { // old save messages does not have date
 			update_time_diff(time(NULL));
 			char date[18];
@@ -247,20 +249,21 @@ public:
 		lb_time_diff.set_pos(message.get_pos()+scr_size(bsize.w-D_MARGIN_RIGHT-lb_time_diff.get_size().w-2, message.get_size().h));
 
 		// draw ballon
-		display_filled_roundbox_clip(offset.x + off_w + 1, offset.y + 1, bsize.w, bsize.h, display_blend_colors(bgcolor, SYSCOL_SHADOW, 75), false);
-		display_filled_roundbox_clip(offset.x + off_w, offset.y, bsize.w, bsize.h, bgcolor, false);
+		g_simgraph->draw_rounded_rect_clipped(offset.x + off_w + 1, offset.y + 1, bsize.w, bsize.h, g_simgraph->blend_colors(bgcolor, SYSCOL_SHADOW, 75), false);
+		g_simgraph->draw_rounded_rect_clipped(offset.x + off_w, offset.y, bsize.w, bsize.h, bgcolor, false);
 		if (tail_dir) {
 			scr_coord_val h = LINESPACE / 2;
 			for (scr_coord_val x = 0; x < h; x++) {
 				if (tail_dir == tail_right) {
-					display_vline_wh_clip_rgb(offset.x + off_w + bsize.w + x, offset.y + bsize.h - 10 - h + x, h - x, bgcolor, true);
+					g_simgraph->draw_vline_clipped(offset.x + off_w + bsize.w + x, offset.y + bsize.h - 10 - h + x, h - x, bgcolor, true CLIP_NUM_DEFAULT);
 				}
 				else {
-					display_vline_wh_clip_rgb(offset.x + off_w - x, offset.y + h, h - x, bgcolor, true);
+					g_simgraph->draw_vline_clipped(offset.x + off_w - x,           offset.y + h,                    h - x, bgcolor, true CLIP_NUM_DEFAULT);
 				}
 			}
+
 			if (tail_dir == tail_right) {
-				display_fillbox_wh_clip_rgb(offset.x + off_w + bsize.w, offset.y + bsize.h - 10, h, 1, display_blend_colors(bgcolor, SYSCOL_SHADOW, 75), true);
+				g_simgraph->draw_rect_clipped(offset.x + off_w + bsize.w, offset.y + bsize.h - 10, h, 1, g_simgraph->blend_colors(bgcolor, SYSCOL_SHADOW, 75), true CLIP_NUM_DEFAULT);
 			}
 		}
 		scr_coord_val old_h = message.get_size().h;
@@ -387,7 +390,7 @@ void chat_frame_t::fill_list()
 		break;
 	case CH_COMPANY:
 		lb_channel.set_text(current_player->get_name());
-		lb_channel.set_color(color_idx_to_rgb(current_player->get_player_color1() + env_t::gui_player_color_dark));
+		lb_channel.set_color(g_simgraph->palette_lookup(current_player->get_player_color1() + env_t::gui_player_color_dark));
 		env_t::chat_unread_company = 0;
 		break;
 	case CH_WHISPER:
diff --git a/src/simutrans/gui/city_info.cc b/src/simutrans/gui/city_info.cc
index ae26ff369..590bd01cc 100644
--- a/src/simutrans/gui/city_info.cc
+++ b/src/simutrans/gui/city_info.cc
@@ -141,8 +141,8 @@ public:
 		}
 		pax_destinations_last_change = current_pax_destinations;
 
-		display_array_wh(pos.x + offset.x, pos.y + offset.y, minimaps_size.w, minimaps_size.h, pax_dest_old.to_array() );
-		display_array_wh(pos.x + offset.x + minimap2_offset.x, pos.y + offset.y + minimap2_offset.y, minimaps_size.w, minimaps_size.h, pax_dest_new.to_array() );
+		g_simgraph->draw_array(pos.x + offset.x, pos.y + offset.y, minimaps_size.w, minimaps_size.h, pax_dest_old.to_array() );
+		g_simgraph->draw_array(pos.x + offset.x + minimap2_offset.x, pos.y + offset.y + minimap2_offset.y, minimaps_size.w, minimaps_size.h, pax_dest_new.to_array() );
 	}
 };
 
@@ -224,12 +224,12 @@ void city_info_t::init()
 	chart.set_seed(welt->get_last_year());
 	chart.set_background(SYSCOL_CHART_BACKGROUND);
 	for(  uint32 i = 0;  i<MAX_CITY_HISTORY-1;  i++  ) {
-		sint16 curve = chart.add_curve( color_idx_to_rgb(hist_type_color[i]), city->get_city_history_year(),
+		sint16 curve = chart.add_curve( g_simgraph->palette_lookup(hist_type_color[i]), city->get_city_history_year(),
 			MAX_CITY_HISTORY, i, 12, gui_chart_t::STANDARD, (city->stadtinfo_options & (1<<i))!=0, true, 0 );
 		// add button
 		buttons[i] = container_year.new_component<button_t>();
 		buttons[i]->init(button_t::box_state_automatic | button_t::flexible, hist_type[i]);
-		buttons[i]->background_color = color_idx_to_rgb(hist_type_color[i]);
+		buttons[i]->background_color = g_simgraph->palette_lookup(hist_type_color[i]);
 		buttons[i]->pressed = (city->stadtinfo_options & (1<<i))!=0;
 		button_to_chart.append(buttons[i], &chart, curve);
 	}
@@ -244,7 +244,7 @@ void city_info_t::init()
 	mchart.set_seed(0);
 	mchart.set_background(SYSCOL_CHART_BACKGROUND);
 	for(  uint32 i = 0;  i<MAX_CITY_HISTORY-1;  i++  ) {
-		sint16 curve = mchart.add_curve( color_idx_to_rgb(hist_type_color[i]), city->get_city_history_month(),
+		sint16 curve = mchart.add_curve( g_simgraph->palette_lookup(hist_type_color[i]), city->get_city_history_month(),
 			MAX_CITY_HISTORY, i, 12, gui_chart_t::STANDARD, (city->stadtinfo_options & (1<<i))!=0, true, 0 );
 		// add button
 		container_month.add_component(buttons[i]);
@@ -344,10 +344,10 @@ void gui_city_minimap_t::add_pax_dest( array2d_tpl<PIXVAL> &pax_dest, const spar
 	const sint16 dd_y = 1+(minimaps_size.h-1)/PAX_DESTINATIONS_SIZE;
 
 	const PIXVAL city_dest_color_lut[4] = {
-		color_idx_to_rgb(pax_dest_status_colors[0]),
-		color_idx_to_rgb(pax_dest_status_colors[1]),
-		color_idx_to_rgb(pax_dest_status_colors[2]),
-		color_idx_to_rgb(pax_dest_status_colors[3])
+		g_simgraph->palette_lookup(pax_dest_status_colors[0]),
+		g_simgraph->palette_lookup(pax_dest_status_colors[1]),
+		g_simgraph->palette_lookup(pax_dest_status_colors[2]),
+		g_simgraph->palette_lookup(pax_dest_status_colors[3])
 	};
 
 	for(  uint16 i = 0;  i < city_pax_dest.get_data_count();  i++  ) {
diff --git a/src/simutrans/gui/citybuilding_edit.cc b/src/simutrans/gui/citybuilding_edit.cc
index ec37fbbee..5a3294c42 100644
--- a/src/simutrans/gui/citybuilding_edit.cc
+++ b/src/simutrans/gui/citybuilding_edit.cc
@@ -189,9 +189,9 @@ void citybuilding_edit_frame_t::fill_list()
 		// color code for objects: BLACK: normal, YELLOW: consumer only, GREEN: source only
 		PIXVAL color;
 		switch (i->get_type()) {
-			case building_desc_t::city_res: color = color_idx_to_rgb(COL_DARK_BLUE + env_t::gui_player_color_dark); break;
-			case building_desc_t::city_com: color = color_idx_to_rgb(40 + env_t::gui_player_color_dark);            break;
-			default:                        color = SYSCOL_TEXT;                                                    break;
+			case building_desc_t::city_res: color = g_simgraph->palette_lookup(COL_DARK_BLUE + env_t::gui_player_color_dark); break;
+			case building_desc_t::city_com: color = g_simgraph->palette_lookup(40            + env_t::gui_player_color_dark); break;
+			default:                        color = SYSCOL_TEXT;                                                              break;
 		}
 		char const* const name = get_sortedby()==gui_sorting_item_t::BY_NAME_OBJECT ?  i->get_name() : translator::translate(i->get_name());
 		scl.new_component<gui_scrolled_list_t::const_text_scrollitem_t>(name, color);
diff --git a/src/simutrans/gui/citylist_frame.cc b/src/simutrans/gui/citylist_frame.cc
index e40ef6604..0b0528009 100644
--- a/src/simutrans/gui/citylist_frame.cc
+++ b/src/simutrans/gui/citylist_frame.cc
@@ -85,7 +85,10 @@ class playername_const_scroll_item_t : public gui_scrolled_list_t::const_text_sc
 public:
 	const uint8 player_nr;
 
-	playername_const_scroll_item_t( player_t *pl ) : gui_scrolled_list_t::const_text_scrollitem_t( pl->get_name(), color_idx_to_rgb(pl->get_player_color1()+env_t::gui_player_color_dark) ), player_nr(pl->get_player_nr()) { }
+	playername_const_scroll_item_t( player_t *pl )
+		: gui_scrolled_list_t::const_text_scrollitem_t( pl->get_name(), g_simgraph->palette_lookup(pl->get_player_color1()+env_t::gui_player_color_dark) )
+		, player_nr(pl->get_player_nr())
+	{ }
 };
 
 
@@ -166,11 +169,11 @@ citylist_frame_t::citylist_frame_t() :
 	chart.set_background(SYSCOL_CHART_BACKGROUND);
 	chart.set_min_size(scr_size(0, 8*LINESPACE));
 	for (int i = 0; i<karte_t::MAX_WORLD_COST; i++) {
-		sint16 curve = chart.add_curve(color_idx_to_rgb(hist_type_color[i]), welt->get_finance_history_year(), karte_t::MAX_WORLD_COST, i, MAX_WORLD_HISTORY_YEARS, hist_type_type[i], false, true, (i==1) ? 1 : 0 );
+		sint16 curve = chart.add_curve(g_simgraph->palette_lookup(hist_type_color[i]), welt->get_finance_history_year(), karte_t::MAX_WORLD_COST, i, MAX_WORLD_HISTORY_YEARS, hist_type_type[i], false, true, (i==1) ? 1 : 0 );
 		// add button
 		buttons[i] = container_year.new_component<button_t>();
 		buttons[i]->init(button_t::box_state_automatic | button_t::flexible, hist_type[i]);
-		buttons[i]->background_color = color_idx_to_rgb(hist_type_color[i]);
+		buttons[i]->background_color = g_simgraph->palette_lookup(hist_type_color[i]);
 		buttons[i]->pressed = false;
 
 		button_to_chart.append(buttons[i], &chart, curve);
@@ -183,7 +186,7 @@ citylist_frame_t::citylist_frame_t() :
 	mchart.set_background(SYSCOL_CHART_BACKGROUND);
 	mchart.set_min_size(scr_size(0, 8*LINESPACE));
 	for (int i = 0; i<karte_t::MAX_WORLD_COST; i++) {
-		sint16 curve = mchart.add_curve(color_idx_to_rgb(hist_type_color[i]), welt->get_finance_history_month(), karte_t::MAX_WORLD_COST, i, MAX_WORLD_HISTORY_MONTHS, hist_type_type[i], false, true, (i==1) ? 1 : 0 );
+		sint16 curve = mchart.add_curve(g_simgraph->palette_lookup(hist_type_color[i]), welt->get_finance_history_month(), karte_t::MAX_WORLD_COST, i, MAX_WORLD_HISTORY_MONTHS, hist_type_type[i], false, true, (i==1) ? 1 : 0 );
 		// add button
 		container_month.add_component(buttons[i]);
 		button_to_chart.append(buttons[i], &mchart, curve);
diff --git a/src/simutrans/gui/components/gui_building.cc b/src/simutrans/gui/components/gui_building.cc
index dcf472933..04a60f0ad 100644
--- a/src/simutrans/gui/components/gui_building.cc
+++ b/src/simutrans/gui/components/gui_building.cc
@@ -27,7 +27,7 @@ void gui_building_t::init(const building_desc_t* d, int r)
 		return;
 	}
 
-	scr_coord_val rw4 = get_base_tile_raster_width()/4;
+	scr_coord_val rw4 = g_simgraph->get_base_tile_raster_width()/4;
 	for(int i=0; i< desc->get_x(layout); i++) {
 		for(int j=0; j < desc->get_y(layout); j++) {
 			image_id id = desc->get_tile(layout,i,j)->get_background(0,0,0);
@@ -39,10 +39,9 @@ void gui_building_t::init(const building_desc_t* d, int r)
 				img->set_pos(scr_coord( 2*(i-j)*rw4, (i+j)*rw4 ));
 				images.append(img);
 				// compute bounding box
-				scr_coord_val x,y,w,h;
-				display_get_base_image_offset( id, &x, &y, &w, &h );
-				tl.clip_rightbottom(img->get_pos() + scr_coord(x,y));
-				br.clip_lefttop(img->get_pos() + scr_coord(x+w,y+h));
+				scr_rect r = g_simgraph->get_base_image_offset(id);
+				tl.clip_rightbottom(img->get_pos() + scr_coord(r.x, r.y));
+				br.clip_lefttop(img->get_pos() + scr_coord(r.x + r.w, r.y+r.h));
 			}
 		}
 	}
diff --git a/src/simutrans/gui/components/gui_button.cc b/src/simutrans/gui/components/gui_button.cc
index 08ccbd1f5..90ad58084 100644
--- a/src/simutrans/gui/components/gui_button.cc
+++ b/src/simutrans/gui/components/gui_button.cc
@@ -45,7 +45,7 @@ button_t::button_t() :
 	b_no_translate = false;
 	pressed = false;
 	translated_tooltip = tooltip = NULL;
-	background_color = color_idx_to_rgb(COL_WHITE);
+	background_color = 0xFFFF; // COL_WHITE; can't use simgraph here since this is called during static init (before main and simgraph_select)
 	b_enabled = true;
 
 	// By default a box button
@@ -80,7 +80,7 @@ void button_t::set_typ(enum type t)
 			text_color = SYSCOL_CHECKBOX_TEXT;
 			if(  !strempty(translated_text)  ) {
 				set_text(translated_text);
-				set_size( scr_size( gui_theme_t::gui_checkbox_size.w + D_H_SPACE + proportional_string_width( translated_text ), max(gui_theme_t::gui_checkbox_size.h,LINESPACE)) );
+				set_size( scr_size( gui_theme_t::gui_checkbox_size.w + D_H_SPACE + g_simgraph->calc_text_width(translated_text), max(gui_theme_t::gui_checkbox_size.h,LINESPACE)) );
 			}
 			else {
 				set_size( scr_size( gui_theme_t::gui_checkbox_size.w, max(gui_theme_t::gui_checkbox_size.h,LINESPACE)) );
@@ -180,23 +180,22 @@ scr_size button_t::get_min_size() const
 			return gui_theme_t::gui_arrow_down_size;
 
 		case square: {
-			scr_coord_val w = translated_text ?  D_H_SPACE + proportional_string_width( translated_text ) : 0;
+			scr_coord_val w = translated_text ?  D_H_SPACE + g_simgraph->calc_text_width( translated_text ) : 0;
 			return scr_size(w + gui_theme_t::gui_checkbox_size.w, max(gui_theme_t::gui_checkbox_size.h,LINESPACE));
 		}
 		case box:
 		case roundbox: {
-			scr_coord_val w = translated_text ?  2*D_H_SPACE + proportional_string_width( translated_text ) : 0;
+			scr_coord_val w = translated_text ?  2*D_H_SPACE + g_simgraph->calc_text_width( translated_text ) : 0;
 			scr_size size(gui_theme_t::gui_button_size.w, max(D_BUTTON_HEIGHT,LINESPACE));
 			size.w = max(size.w, w);
 			return size;
 		}
 
 		case imagebox: {
-			scr_coord_val x = 0, y = 0, w = 0, h = 0;
-			display_get_image_offset(img, &x, &y, &w, &h);
+			scr_rect r = g_simgraph->get_image_offset(img);
 			scr_size size(gui_theme_t::gui_pos_button_size);
-			size.w = max(size.w, w+2);
-			size.h = max(size.h, h+2);
+			size.w = max(size.w, r.w+2);
+			size.h = max(size.h, r.h+2);
 			return size;
 		}
 
@@ -221,7 +220,7 @@ void button_t::set_text(const char * text)
 	translated_text = b_no_translate ? text : translator::translate(text);
 
 	if(  (type & TYPE_MASK) == square  &&  !strempty(translated_text)  ) {
-		set_size( scr_size( gui_theme_t::gui_checkbox_size.w + D_H_SPACE + proportional_string_width( translated_text ), max(gui_theme_t::gui_checkbox_size.h, LINESPACE)) );
+		set_size( scr_size( gui_theme_t::gui_checkbox_size.w + D_H_SPACE + g_simgraph->calc_text_width( translated_text ), max(gui_theme_t::gui_checkbox_size.h, LINESPACE)) );
 	}
 }
 
@@ -333,10 +332,10 @@ void button_t::draw_focus_rect( scr_rect r, scr_coord_val offset) {
 
 	scr_coord_val w = ((offset-1)<<1);
 
-	display_fillbox_wh_clip_rgb(r.x-offset+1,     r.y-1-offset+1,   r.w+w, 1, color_idx_to_rgb(COL_WHITE), false);
-	display_fillbox_wh_clip_rgb(r.x-offset+1,     r.y+r.h+offset-1, r.w+w, 1, color_idx_to_rgb(COL_WHITE), false);
-	display_vline_wh_clip_rgb  (r.x-offset,       r.y-offset+1,     r.h+w,    color_idx_to_rgb(COL_WHITE), false);
-	display_vline_wh_clip_rgb  (r.x+r.w+offset-1, r.y-offset+1,     r.h+w,    color_idx_to_rgb(COL_WHITE), false);
+	g_simgraph->draw_rect_clipped (r.x    -offset+1, r.y-1  -offset+1, r.w+w, 1, g_simgraph->palette_lookup(COL_WHITE), false CLIP_NUM_DEFAULT);
+	g_simgraph->draw_rect_clipped (r.x    -offset+1, r.y+r.h+offset-1, r.w+w, 1, g_simgraph->palette_lookup(COL_WHITE), false CLIP_NUM_DEFAULT);
+	g_simgraph->draw_vline_clipped(r.x    -offset,   r.y    -offset+1, r.h+w,    g_simgraph->palette_lookup(COL_WHITE), false CLIP_NUM_DEFAULT);
+	g_simgraph->draw_vline_clipped(r.x+r.w+offset-1, r.y    -offset+1, r.h+w,    g_simgraph->palette_lookup(COL_WHITE), false CLIP_NUM_DEFAULT);
 }
 
 
@@ -355,14 +354,14 @@ void button_t::draw(scr_coord offset)
 
 		case box: // Colored background box
 			{
-				display_img_stretch( gui_theme_t::button_tiles[get_state_offset()], area );
-				display_img_stretch_blend( gui_theme_t::button_color_tiles[b_enabled && pressed], area, background_color | TRANSPARENT75_FLAG | OUTLINE_FLAG );
+				g_simgraph->draw_stretch_map( gui_theme_t::button_tiles[get_state_offset()], area );
+				g_simgraph->draw_stretch_map_blend( gui_theme_t::button_color_tiles[b_enabled && pressed], area, background_color | TRANSPARENT75_FLAG | OUTLINE_FLAG );
 				if(  text  ) {
 					text_color = pressed ? SYSCOL_COLORED_BUTTON_TEXT_SELECTED : text_color;
 					// move the text to leave evt. space for a colored box top left or bottom right of it
 					scr_rect area_text = area - gui_theme_t::gui_color_button_text_offset_right;
 					area_text.set_pos( gui_theme_t::gui_color_button_text_offset + area.get_pos() );
-					display_proportional_ellipsis_rgb( area_text, translated_text, ALIGN_CENTER_H | ALIGN_CENTER_V | DT_CLIP, text_color, true );
+					g_simgraph->draw_text_ellipsis( area_text, translated_text, ALIGN_CENTER_H | ALIGN_CENTER_V | DT_CLIP, text_color, true );
 				}
 				if(  win_get_focus()==this  ) {
 					draw_focus_rect( area );
@@ -372,12 +371,12 @@ void button_t::draw(scr_coord offset)
 
 		case roundbox: // button with inside text
 			{
-				display_img_stretch( gui_theme_t::round_button_tiles[get_state_offset()], area );
+				g_simgraph->draw_stretch_map( gui_theme_t::round_button_tiles[get_state_offset()], area );
 				if(  text  ) {
 					// move the text to leave evt. space for a colored box top left or bottom right of it
 					scr_rect area_text = area - gui_theme_t::gui_button_text_offset_right;
 					area_text.set_pos( gui_theme_t::gui_button_text_offset + area.get_pos() );
-					display_proportional_ellipsis_rgb( area_text, translated_text, ALIGN_CENTER_H | ALIGN_CENTER_V | DT_CLIP, text_color, true );
+					g_simgraph->draw_text_ellipsis( area_text, translated_text, ALIGN_CENTER_H | ALIGN_CENTER_V | DT_CLIP, text_color, true );
 				}
 				if(  win_get_focus()==this  ) {
 					draw_focus_rect( area );
@@ -386,9 +385,9 @@ void button_t::draw(scr_coord offset)
 			break;
 
 		case imagebox:
-			display_img_stretch(gui_theme_t::button_tiles[get_state_offset()], area);
-			display_img_stretch_blend(gui_theme_t::button_color_tiles[b_enabled && pressed], area, (pressed ? text_color: background_color) | TRANSPARENT75_FLAG | OUTLINE_FLAG);
-			display_img_aligned(img, area, ALIGN_CENTER_H | ALIGN_CENTER_V, true);
+			g_simgraph->draw_stretch_map(gui_theme_t::button_tiles[get_state_offset()], area);
+			g_simgraph->draw_stretch_map_blend(gui_theme_t::button_color_tiles[b_enabled && pressed], area, (pressed ? text_color: background_color) | TRANSPARENT75_FLAG | OUTLINE_FLAG);
+			g_simgraph->draw_img_aligned(img, area, ALIGN_CENTER_H | ALIGN_CENTER_V, true);
 			if (win_get_focus() == this) {
 				draw_focus_rect(area);
 			}
@@ -396,7 +395,7 @@ void button_t::draw(scr_coord offset)
 
 		case sortarrow:
 			{
-				display_img_stretch(gui_theme_t::button_tiles[0], area);
+				g_simgraph->draw_stretch_map(gui_theme_t::button_tiles[0], area);
 
 				const uint8 block_height = 2;
 				const uint8 bars_height = uint8((size.h-block_height-4)/4)*block_height*2 + block_height;
@@ -404,22 +403,22 @@ void button_t::draw(scr_coord offset)
 				area_drawing.set_pos(gui_theme_t::gui_color_button_text_offset + area.get_pos() + scr_coord(4/*left margin*/,D_GET_CENTER_ALIGN_OFFSET(bars_height,size.h)));
 
 				// draw an arrow
-				display_fillbox_wh_clip_rgb(area_drawing.x+2, area_drawing.y, 1, bars_height, SYSCOL_BUTTON_TEXT, false);
+				g_simgraph->draw_rect_clipped(area_drawing.x+2, area_drawing.y, 1, bars_height, SYSCOL_BUTTON_TEXT, false CLIP_NUM_DEFAULT);
 				if (pressed) {
 					// desc
-					display_fillbox_wh_clip_rgb(area_drawing.x+1, area_drawing.y+1, 3, 1, SYSCOL_BUTTON_TEXT, false);
-					display_fillbox_wh_clip_rgb(area_drawing.x,   area_drawing.y+2, 5, 1, SYSCOL_BUTTON_TEXT, false);
+					g_simgraph->draw_rect_clipped(area_drawing.x+1, area_drawing.y+1, 3, 1, SYSCOL_BUTTON_TEXT, false CLIP_NUM_DEFAULT);
+					g_simgraph->draw_rect_clipped(area_drawing.x,   area_drawing.y+2, 5, 1, SYSCOL_BUTTON_TEXT, false CLIP_NUM_DEFAULT);
 					for (uint8 row=0; row*4<bars_height; row++) {
-						display_fillbox_wh_clip_rgb(area_drawing.x + 6/*arrow width(5)+margin(1)*/, area_drawing.y + bars_height - block_height - row*block_height*2, block_height*(row+1), block_height, SYSCOL_BUTTON_TEXT, false);
+						g_simgraph->draw_rect_clipped(area_drawing.x + 6/*arrow width(5)+margin(1)*/, area_drawing.y + bars_height - block_height - row*block_height*2, block_height*(row+1), block_height, SYSCOL_BUTTON_TEXT, false CLIP_NUM_DEFAULT);
 					}
 					tooltip = "hl_btn_sort_desc";
 				}
 				else {
 					// asc
-					display_fillbox_wh_clip_rgb(area_drawing.x+1, area_drawing.y+bars_height-2, 3, 1, SYSCOL_BUTTON_TEXT, false);
-					display_fillbox_wh_clip_rgb(area_drawing.x,   area_drawing.y+bars_height-3, 5, 1, SYSCOL_BUTTON_TEXT, false);
+					g_simgraph->draw_rect_clipped(area_drawing.x+1, area_drawing.y+bars_height-2, 3, 1, SYSCOL_BUTTON_TEXT, false CLIP_NUM_DEFAULT);
+					g_simgraph->draw_rect_clipped(area_drawing.x,   area_drawing.y+bars_height-3, 5, 1, SYSCOL_BUTTON_TEXT, false CLIP_NUM_DEFAULT);
 					for (uint8 row=0; row*4<bars_height; row++) {
-						display_fillbox_wh_clip_rgb(area_drawing.x + 6/*arrow width(5)+margin(1)*/, area_drawing.y + row*block_height*2, block_height*(row+1), block_height, SYSCOL_BUTTON_TEXT, false);
+						g_simgraph->draw_rect_clipped(area_drawing.x + 6/*arrow width(5)+margin(1)*/, area_drawing.y + row*block_height*2, block_height*(row+1), block_height, SYSCOL_BUTTON_TEXT, false CLIP_NUM_DEFAULT);
 					}
 					tooltip = "hl_btn_sort_asc";
 				}
@@ -432,13 +431,13 @@ void button_t::draw(scr_coord offset)
 
 		case square: // checkbox with text
 			{
-				display_img_aligned( gui_theme_t::check_button_img[ get_state_offset() ], area, ALIGN_CENTER_V, true );
+				g_simgraph->draw_img_aligned( gui_theme_t::check_button_img[ get_state_offset() ], area, ALIGN_CENTER_V, true );
 				if(  text  ) {
 					text_color = b_enabled ? this->text_color : SYSCOL_CHECKBOX_TEXT_DISABLED;
 					scr_rect area_text = area;
 					area_text.x += gui_theme_t::gui_checkbox_size.w + D_H_SPACE;
 					area_text.w -= gui_theme_t::gui_checkbox_size.w + D_H_SPACE;
-					display_proportional_ellipsis_rgb( area_text, translated_text, ALIGN_LEFT | ALIGN_CENTER_V | DT_CLIP, text_color, true );
+					g_simgraph->draw_text_ellipsis( area_text, translated_text, ALIGN_LEFT | ALIGN_CENTER_V | DT_CLIP, text_color, true );
 				}
 				if(  win_get_focus() == this  ) {
 					draw_focus_rect( scr_rect( area.get_pos()+scr_coord(0,(area.get_size().h-gui_theme_t::gui_checkbox_size.w)/2), gui_theme_t::gui_checkbox_size ) );
@@ -454,26 +453,26 @@ void button_t::draw(scr_coord offset)
 						offset = welt->get_viewport()->is_on_center( gr->get_pos() );
 					}
 				}
-				display_img_aligned( gui_theme_t::pos_button_img[ offset ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
+				g_simgraph->draw_img_aligned( gui_theme_t::pos_button_img[ offset ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
 			}
 			break;
 
 		case arrowleft:
 		case repeatarrowleft:
-			display_img_aligned( gui_theme_t::arrow_button_left_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
+			g_simgraph->draw_img_aligned( gui_theme_t::arrow_button_left_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
 			break;
 
 		case arrowright:
 		case repeatarrowright:
-			display_img_aligned( gui_theme_t::arrow_button_right_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
+			g_simgraph->draw_img_aligned( gui_theme_t::arrow_button_right_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
 			break;
 
 		case arrowup:
-			display_img_aligned( gui_theme_t::arrow_button_up_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
+			g_simgraph->draw_img_aligned( gui_theme_t::arrow_button_up_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
 			break;
 
 		case arrowdown:
-			display_img_aligned( gui_theme_t::arrow_button_down_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
+			g_simgraph->draw_img_aligned( gui_theme_t::arrow_button_down_img[ get_state_offset() ], area, ALIGN_CENTER_H|ALIGN_CENTER_V, true );
 			break;
 
 		default: ;
diff --git a/src/simutrans/gui/components/gui_chart.cc b/src/simutrans/gui/components/gui_chart.cc
index dca0d2d4c..93fdf7cb4 100644
--- a/src/simutrans/gui/components/gui_chart.cc
+++ b/src/simutrans/gui/components/gui_chart.cc
@@ -124,7 +124,7 @@ void gui_chart_t::draw(scr_coord offset)
 
 	// draw background if desired
 	if(background != TRANSPARENT_FLAGS) {
-		display_fillbox_wh_clip_rgb(offset.x, offset.y, chart_size.w, chart_size.h, background, false);
+		g_simgraph->draw_rect_clipped(offset.x, offset.y, chart_size.w, chart_size.h, background, false CLIP_NUM_DEFAULT);
 	}
 	int tmpx, factor;
 	if(env_t::left_to_right_graphs) {
@@ -137,22 +137,22 @@ void gui_chart_t::draw(scr_coord offset)
 	}
 
 	// draw zero line
-	display_direct_line_rgb(offset.x+1, offset.y+(scr_coord_val)baseline, offset.x+chart_size.w-2, offset.y+(scr_coord_val)baseline, SYSCOL_CHART_LINES_ZERO);
+	g_simgraph->draw_line(offset.x+1, offset.y+(scr_coord_val)baseline, offset.x+chart_size.w-2, offset.y+(scr_coord_val)baseline, SYSCOL_CHART_LINES_ZERO);
 
 	if (show_y_axis) {
 
 		// draw zero number only, if it will not disturb any other printed values!
 		if ((baseline > 18) && (baseline < chart_size.h -18)) {
-			display_proportional_clip_rgb(offset.x - 4, offset.y+(scr_coord_val)baseline-3, "0", ALIGN_RIGHT, SYSCOL_TEXT_HIGHLIGHT, true );
+			g_simgraph->draw_text_clipped(offset.x - 4, offset.y+(scr_coord_val)baseline-3, "0", ALIGN_RIGHT, SYSCOL_TEXT_HIGHLIGHT, true );
 		}
 
 		// display min/max money values
-		display_proportional_clip_rgb(offset.x - 4, offset.y-5, cmax, ALIGN_RIGHT, SYSCOL_TEXT_HIGHLIGHT, true );
-		display_proportional_clip_rgb(offset.x - 4, offset.y+chart_size.h-5, cmin, ALIGN_RIGHT, SYSCOL_TEXT_HIGHLIGHT, true );
+		g_simgraph->draw_text_clipped(offset.x - 4, offset.y-5,              cmax, ALIGN_RIGHT, SYSCOL_TEXT_HIGHLIGHT, true );
+		g_simgraph->draw_text_clipped(offset.x - 4, offset.y+chart_size.h-5, cmin, ALIGN_RIGHT, SYSCOL_TEXT_HIGHLIGHT, true );
 	}
 
 	// draw chart frame
-	display_ddd_box_clip_rgb(offset.x, offset.y, chart_size.w, chart_size.h, SYSCOL_SHADOW, SYSCOL_HIGHLIGHT);
+	g_simgraph->draw_box3d_clipped(offset.x, offset.y, chart_size.w, chart_size.h, SYSCOL_SHADOW, SYSCOL_HIGHLIGHT);
 
 	// draw chart lines
 	scr_coord_val x_last = 0;  // remember last digit position to avoid overwriting by next label
@@ -165,11 +165,11 @@ void gui_chart_t::draw(scr_coord offset)
 			sprintf( digit, "%i", abs(seed - j) );
 			scr_coord_val x =  x0 - (seed != j ? (int)(2 * log( (double)abs(seed - j) )) : 0);
 			if(  x > x_last  ) {
-				x_last = x + display_proportional_clip_rgb( x, offset.y + chart_size.h + 4, digit, ALIGN_LEFT, line_color, true );
+				x_last = x + g_simgraph->draw_text_clipped( x, offset.y + chart_size.h + 4, digit, ALIGN_LEFT, line_color, true );
 			}
 		}
 		// year's vertical lines
-		display_vline_wh_clip_rgb( x0, offset.y + 1, chart_size.h - 2, line_color, false );
+		g_simgraph->draw_vline_clipped( x0, offset.y + 1, chart_size.h - 2, line_color, false CLIP_NUM_DEFAULT );
 	}
 
 	// display current value?
@@ -206,7 +206,7 @@ void gui_chart_t::draw(scr_coord offset)
 				}
 
 				// display marker(box) for financial value
-				display_fillbox_wh_clip_rgb(tmpx+factor*(chart_size.w / (x_elements - 1))*i-2, (scr_coord_val)(offset.y+baseline- (long)(tmp/scale)-2), 5, 5, c.color, true);
+				g_simgraph->draw_rect_clipped(tmpx+factor*(chart_size.w / (x_elements - 1))*i-2, (scr_coord_val)(offset.y+baseline- (long)(tmp/scale)-2), 5, 5, c.color, true CLIP_NUM_DEFAULT);
 
 				// display tooltip?
 				if(i==tooltip_n  &&  abs((int)(baseline-(int)(tmp/scale)-tooltipcoord.y))<10) {
@@ -219,7 +219,7 @@ void gui_chart_t::draw(scr_coord offset)
 
 				// draw line between two financial markers; this is only possible from the second value on
 				if (i>0) {
-					display_direct_line_rgb(tmpx+factor*(chart_size.w / (x_elements - 1))*(i-1),
+					g_simgraph->draw_line(tmpx+factor*(chart_size.w / (x_elements - 1))*(i-1),
 						(scr_coord_val)( offset.y+baseline-(int)(last_year/scale) ),
 						tmpx+factor*(chart_size.w / (x_elements - 1))*(i),
 						(scr_coord_val)( offset.y+baseline-(int)(tmp/scale) ),
@@ -235,10 +235,10 @@ void gui_chart_t::draw(scr_coord offset)
 						}
 
 						if(  env_t::left_to_right_graphs  ) {
-							display_ddd_proportional_clip( tmpx + 8, (scr_coord_val)(offset.y+baseline-(int)(tmp/scale)-4), color_idx_to_rgb(COL_GREY4), c.color, cmin, true);
+							g_simgraph->draw_textbox3d_clipped( tmpx + 8, (scr_coord_val)(offset.y+baseline-(int)(tmp/scale)-4), g_simgraph->palette_lookup(COL_GREY4), c.color, cmin, true CLIP_NUM_DEFAULT);
 						}
 						else if(  (baseline-tmp/scale-8) > 0  &&  (baseline-tmp/scale+8) < chart_size.h  &&  abs((int)(tmp/scale)) > 9  ) {
-							display_proportional_clip_rgb(tmpx - 4, (scr_coord_val)(offset.y+baseline-(int)(tmp/scale)-4), cmin, ALIGN_RIGHT, c.color, true );
+							g_simgraph->draw_text_clipped(tmpx - 4, (scr_coord_val)(offset.y+baseline-(int)(tmp/scale)-4), cmin, ALIGN_RIGHT, c.color, true );
 						}
 					}
 				}
diff --git a/src/simutrans/gui/components/gui_colorbox.cc b/src/simutrans/gui/components/gui_colorbox.cc
index 0c1a12519..846750ad8 100644
--- a/src/simutrans/gui/components/gui_colorbox.cc
+++ b/src/simutrans/gui/components/gui_colorbox.cc
@@ -29,6 +29,6 @@ scr_size gui_colorbox_t::get_max_size() const
 void gui_colorbox_t::draw(scr_coord offset)
 {
 	offset += pos;
-	display_ddd_box_clip_rgb(offset.x, offset.y, size.w, D_INDICATOR_HEIGHT, color_idx_to_rgb(MN_GREY0), color_idx_to_rgb(MN_GREY4));
-	display_fillbox_wh_clip_rgb(offset.x + 1, offset.y + 1, size.w - 2, D_INDICATOR_HEIGHT-2, color, true);
+	g_simgraph->draw_box3d_clipped(offset.x,     offset.y,     size.w,     D_INDICATOR_HEIGHT,   g_simgraph->palette_lookup(MN_GREY0), g_simgraph->palette_lookup(MN_GREY4));
+	g_simgraph->draw_rect_clipped (offset.x + 1, offset.y + 1, size.w - 2, D_INDICATOR_HEIGHT-2, color, true CLIP_NUM_DEFAULT);
 }
diff --git a/src/simutrans/gui/components/gui_container.cc b/src/simutrans/gui/components/gui_container.cc
index 79f7875d6..f6855a0e4 100644
--- a/src/simutrans/gui/components/gui_container.cc
+++ b/src/simutrans/gui/components/gui_container.cc
@@ -253,13 +253,13 @@ void gui_container_t::draw(scr_coord offset)
 	const scr_coord screen_pos = pos + offset;
 	bool redraw_focus = false;
 
-	clip_dimension cd = display_get_clip_wh();
+	clip_dimension cd = g_simgraph->get_clip_rect(CLIP_NUM_DEFAULT_VALUE);
 	scr_rect clip_rect(cd.x, cd.y, cd.w, cd.h);
 
 	// For debug purpose, draw the container's boundary
 #ifdef SHOW_BBOX
 #define shorten(d) clamp(d, 0, 0x4fff)
-	display_ddd_box_clip_rgb(shorten(screen_pos.x), shorten(screen_pos.y), shorten(get_size().w), shorten(get_size().h), color_idx_to_rgb(COL_RED), color_idx_to_rgb(COL_RED));
+	g_simgraph->draw_box3d_clipped(screen_pos.x), shorten(screen_pos.y), shorten(get_size().w), shorten(get_size().h), g_simgraph->palette_lookup(COL_RED), g_simgraph->palette_lookup(COL_RED));
 #endif
 	// iterate backwards
 	int checker_count = 0;
@@ -277,7 +277,7 @@ void gui_container_t::draw(scr_coord offset)
 
 			if (checkered && (checker_count&1)==0) {
 				scr_coord c_pos = screen_pos + c->get_pos();
-				display_blend_wh_rgb( c_pos.x, c_pos.y, c->get_size().w, c->get_size().h, color_idx_to_rgb(COL_WHITE), 50 );
+				g_simgraph->tint_rect( c_pos.x, c_pos.y, c->get_size().w, c->get_size().h, g_simgraph->palette_lookup(COL_WHITE), 50 );
 			}
 
 			if(  c == comp_focus  ) {
@@ -288,7 +288,7 @@ void gui_container_t::draw(scr_coord offset)
 			if (dynamic_cast<gui_container_t*>(c) == NULL) {
 				scr_coord c_pos = screen_pos + c->get_pos();
 				int color = c->is_marginless() ? COL_BLUE : COL_YELLOW;
-				display_ddd_box_clip_rgb(shorten(c_pos.x), shorten(c_pos.y), shorten(c->get_size().w), shorten(c->get_size().h), color_idx_to_rgb(color),color_idx_to_rgb(color));
+				display_ddd_box_clip_rgb(shorten(c_pos.x), shorten(c_pos.y), shorten(c->get_size().w), shorten(c->get_size().h), g_simgraph->palette_lookup(color),g_simgraph->palette_lookup(color));
 			}
 #endif
 			c->draw(screen_pos);
diff --git a/src/simutrans/gui/components/gui_convoiinfo.cc b/src/simutrans/gui/components/gui_convoiinfo.cc
index eb72b2fdc..54c61db31 100644
--- a/src/simutrans/gui/components/gui_convoiinfo.cc
+++ b/src/simutrans/gui/components/gui_convoiinfo.cc
@@ -44,14 +44,13 @@ public:
 		scr_size s(0,0);
 		unsigned count = cnv.is_bound() ? cnv->get_vehicle_count() : 0;
 		for(unsigned i=0; i<count; i++) {
-			scr_coord_val x, y, w, h;
 			const image_id image = cnv->get_vehicle(i)->get_loaded_image();
-			display_get_base_image_offset(image, &x, &y, &w, &h );
+			scr_rect r = g_simgraph->get_base_image_offset(image);
 			if (display_images) {
-				display_base_img(image, p.x + s.w - x, p.y - y - h/2, cnv->get_owner()->get_player_nr(), false, true);
+				g_simgraph->draw_base_img(image, p.x + s.w - r.x, p.y - r.y - r.h/2, cnv->get_owner()->get_player_nr(), false, true CLIP_NUM_DEFAULT);
 			}
-			s.w += (w*2)/3;
-			s.h = max(s.h, h);
+			s.w += (r.w*2)/3;
+			s.h = max(s.h, r.h);
 		}
 		return s;
 	}
@@ -81,8 +80,8 @@ gui_convoiinfo_t::gui_convoiinfo_t(convoihandle_t cnv)
 	// second row
 	new_component<gui_empty_t>();
 	add_component(&label_profit);
-	filled_bar.add_color_value(&cnv->get_loading_limit(), color_idx_to_rgb(COL_YELLOW));
-	filled_bar.add_color_value(&cnv->get_loading_level(), color_idx_to_rgb(COL_GREEN));
+	filled_bar.add_color_value(&cnv->get_loading_limit(), g_simgraph->palette_lookup(COL_YELLOW));
+	filled_bar.add_color_value(&cnv->get_loading_level(), g_simgraph->palette_lookup(COL_GREEN));
 	add_component(&filled_bar);
 
 	// third row
diff --git a/src/simutrans/gui/components/gui_divider.cc b/src/simutrans/gui/components/gui_divider.cc
index 371c72fdf..8e5a31ac3 100644
--- a/src/simutrans/gui/components/gui_divider.cc
+++ b/src/simutrans/gui/components/gui_divider.cc
@@ -10,7 +10,7 @@
 
 void gui_divider_t::draw(scr_coord offset)
 {
-	display_img_stretch( gui_theme_t::divider, scr_rect( get_pos()+offset, get_size() ) );
+	g_simgraph->draw_stretch_map( gui_theme_t::divider, scr_rect( get_pos()+offset, get_size() ) );
 }
 
 
diff --git a/src/simutrans/gui/components/gui_fixedwidth_textarea.cc b/src/simutrans/gui/components/gui_fixedwidth_textarea.cc
index 09c1f9a3a..2af024b68 100644
--- a/src/simutrans/gui/components/gui_fixedwidth_textarea.cc
+++ b/src/simutrans/gui/components/gui_fixedwidth_textarea.cc
@@ -111,7 +111,7 @@ scr_size gui_fixedwidth_textarea_t::calc_display_text(const scr_coord offset, co
 
 			const size_t len = next ? next - buf : 999;
 			// we are in the image area
-			scr_coord_val px_len = display_calc_proportional_string_len_width(buf, len);
+			scr_coord_val px_len = g_simgraph->calc_text_width_n(buf, len);
 			if (new_height <= reserved_area.h) {
 				px_len += reserved_area.w;
 			}
@@ -157,14 +157,14 @@ scr_size gui_fixedwidth_textarea_t::calc_display_text(const scr_coord offset, co
 			else if(  next_char==' '  ||  (next_char >= 0x3000  &&   next_char<0xFE70)  ) {
 				// ignore space at start of line
 				if(next_char!=' '  ||  x>0) {
-					x += (scr_coord_val)display_get_char_width( next_char );
+					x += g_simgraph->get_char_width( next_char );
 				}
 				word_start = p;
 				word_x = 0;
 			}
 			else {
 				// normal char: retrieve and calculate width
-				int ch_width = display_get_char_width( next_char );
+				const scr_coord_val ch_width = g_simgraph->get_char_width( next_char );
 				x += ch_width;
 				word_x += ch_width;
 			}
@@ -183,7 +183,7 @@ scr_size gui_fixedwidth_textarea_t::calc_display_text(const scr_coord offset, co
 
 		// start of new line or end of text
 		if(draw  &&  (line_end-line_start)!=0) {
-			display_text_proportional_len_clip_rgb( offset.x, offset.y+y, (const char *)line_start, ALIGN_LEFT | DT_CLIP, SYSCOL_TEXT, true, (size_t)(line_end - line_start) );
+			g_simgraph->draw_text_clipped_n( offset.x, offset.y+y, (const char *)line_start, ALIGN_LEFT | DT_CLIP, SYSCOL_TEXT, true, (size_t)(line_end - line_start) CLIP_NUM_DEFAULT);
 		}
 		y += LINESPACE;
 		// back to start of new line
diff --git a/src/simutrans/gui/components/gui_flowtext.cc b/src/simutrans/gui/components/gui_flowtext.cc
index ceb514a86..3f515d190 100644
--- a/src/simutrans/gui/components/gui_flowtext.cc
+++ b/src/simutrans/gui/components/gui_flowtext.cc
@@ -370,13 +370,13 @@ scr_size gui_flowtext_intern_t::output(scr_coord offset, bool doit, bool return_
 	int last_link_x     = 0;     // at this position ye need to continue underline drawing
 	int max_width    = width;
 	int text_width   = width;
-	const int space_width = proportional_string_width(" ");
+	const int space_width = g_simgraph->calc_text_width(" ");
 
 	for(node_t const& i : nodes) {
 		switch (i.att) {
 			case ATT_NONE:
 			case ATT_NO_SPACE: {
-				int nxpos = xpos + proportional_string_width(i.text.c_str());
+				int nxpos = xpos + g_simgraph->calc_text_width(i.text.c_str());
 
 				if (nxpos >= text_width) {
 					text_width = nxpos;
@@ -393,7 +393,7 @@ scr_size gui_flowtext_intern_t::output(scr_coord offset, bool doit, bool return_
 						if(  xpos!=last_link_x  &&  link_it  ) {
 							if(  doit  ) {
 								// close the link
-								display_fillbox_wh_clip_rgb( offset.x + last_link_x + D_MARGIN_LEFT, ypos + offset.y + LINESPACE-1, xpos-last_link_x, 1, color, false);
+								g_simgraph->draw_rect_clipped( offset.x + last_link_x + D_MARGIN_LEFT, ypos + offset.y + LINESPACE-1, xpos-last_link_x, 1, color, false CLIP_NUM_DEFAULT);
 							}
 							extra_pixel = 1;
 						}
@@ -410,12 +410,12 @@ scr_size gui_flowtext_intern_t::output(scr_coord offset, bool doit, bool return_
 
 				if (doit) {
 					if (double_it) {
-						display_proportional_clip_rgb(offset.x + xpos + 1 + D_MARGIN_LEFT, offset.y + ypos + 1, i.text.c_str(), 0, double_color, false);
+						g_simgraph->draw_text_clipped(offset.x + xpos + 1 + D_MARGIN_LEFT, offset.y + ypos + 1, i.text.c_str(), 0, double_color, false);
 						extra_pixel |= 1;
 					}
-					scr_coord_val width = display_proportional_clip_rgb(offset.x + xpos + D_MARGIN_LEFT, offset.y + ypos, i.text.c_str(), 0, color, false);
+					scr_coord_val width = g_simgraph->draw_text_clipped(offset.x + xpos + D_MARGIN_LEFT, offset.y + ypos, i.text.c_str(), 0, color, false);
 					if(  link_it  ) {
-						display_fillbox_wh_clip_rgb( offset.x + last_link_x + D_MARGIN_LEFT, ypos + offset.y + LINESPACE-1, (xpos+width)-last_link_x, 1, color, false);
+						g_simgraph->draw_rect_clipped( offset.x + last_link_x + D_MARGIN_LEFT, ypos + offset.y + LINESPACE-1, (xpos+width)-last_link_x, 1, color, false CLIP_NUM_DEFAULT);
 						last_link_x = xpos+width;
 					}
 				}
@@ -431,7 +431,7 @@ scr_size gui_flowtext_intern_t::output(scr_coord offset, bool doit, bool return_
 				if(  last_link_x<xpos  &&  link_it  ) {
 					if(  doit  ) {
 						// close the link
-						display_fillbox_wh_clip_rgb( offset.x + last_link_x + D_MARGIN_LEFT, ypos + offset.y + LINESPACE-1, xpos-last_link_x, 1, color, false);
+						g_simgraph->draw_rect_clipped( offset.x + last_link_x + D_MARGIN_LEFT, ypos + offset.y + LINESPACE-1, xpos-last_link_x, 1, color, false CLIP_NUM_DEFAULT);
 					}
 					extra_pixel = 1;
 				}
@@ -467,8 +467,8 @@ scr_size gui_flowtext_intern_t::output(scr_coord offset, bool doit, bool return_
 			case ATT_H1_END:
 				double_it = false;
 				if(doit) {
-					display_fillbox_wh_clip_rgb(offset.x + 1 + D_MARGIN_LEFT, offset.y + ypos + LINESPACE,   xpos, 1, color,        false);
-					display_fillbox_wh_clip_rgb(offset.x + D_MARGIN_LEFT,     offset.y + ypos + LINESPACE-1, xpos, 1, double_color, false);
+					g_simgraph->draw_rect_clipped(offset.x + 1 + D_MARGIN_LEFT, offset.y + ypos + LINESPACE,   xpos, 1, color,        false CLIP_NUM_DEFAULT);
+					g_simgraph->draw_rect_clipped(offset.x +     D_MARGIN_LEFT, offset.y + ypos + LINESPACE-1, xpos, 1, double_color, false CLIP_NUM_DEFAULT);
 				}
 				xpos = 0;
 				extra_pixel = 0;
@@ -511,7 +511,7 @@ scr_size gui_flowtext_intern_t::output(scr_coord offset, bool doit, bool return_
 	}
 	ypos += LINESPACE;
 	if(dirty) {
-		mark_rect_dirty_wc( offset.x + D_MARGIN_LEFT, offset.y, offset.x+max_width + D_MARGIN_LEFT, offset.y+ypos );
+		g_simgraph->mark_rect_dirty_wc( offset.x + D_MARGIN_LEFT, offset.y, offset.x+max_width + D_MARGIN_LEFT, offset.y+ypos );
 		dirty = false;
 	}
 	return scr_size( (return_max_width ? max_width : text_width)+D_MARGIN_LEFT+D_MARGIN_RIGHT, ypos);
diff --git a/src/simutrans/gui/components/gui_image.cc b/src/simutrans/gui/components/gui_image.cc
index d07e352ce..a64a45f25 100644
--- a/src/simutrans/gui/components/gui_image.cc
+++ b/src/simutrans/gui/components/gui_image.cc
@@ -22,16 +22,15 @@ gui_image_t::gui_image_t( const image_id i, const uint8 p, control_alignment_t a
 scr_size gui_image_t::get_min_size() const
 {
 	if( id  !=  IMG_EMPTY ) {
-		scr_coord_val x=0, y=0, w=0, h=0;
-		display_get_base_image_offset( id, &x, &y, &w, &h );
+		scr_rect r = g_simgraph->get_base_image_offset(id);
 
 		if (remove_enabled) {
-			return scr_size(w, h);
+			return scr_size(r.w, r.h);
 		}
 		else {
 			// FIXME
 			assert(0);
-			return scr_size(x+w, y+h);
+			return scr_size(r.x+r.w, r.y+r.h);
 		}
 	}
 	return gui_component_t::get_min_size();
@@ -41,14 +40,13 @@ scr_size gui_image_t::get_min_size() const
 void gui_image_t::set_size( scr_size size_par )
 {
 	if( id  !=  IMG_EMPTY ) {
-		scr_coord_val x=0, y=0, w=0, h=0;
-		display_get_base_image_offset( id, &x, &y, &w, &h );
+		scr_rect r = g_simgraph->get_base_image_offset(id);
 
 		if( remove_enabled ) {
-			remove_offset = scr_coord(-x,-y);
+			remove_offset = scr_coord(-r.x,-r.y);
 		}
 
-		size_par = scr_size( x+w+remove_offset.x, y+h+remove_offset.y );
+		size_par = scr_size( r.x+r.w+remove_offset.x, r.y+r.h+remove_offset.y );
 	}
 
 	gui_component_t::set_size(size_par);
@@ -76,33 +74,31 @@ void gui_image_t::set_image( const image_id i, bool remove_offsets ) {
 void gui_image_t::draw( scr_coord offset ) {
 
 	if(  id!=IMG_EMPTY  ) {
-		scr_coord_val x=0, y=0, w=0, h=0;
-		display_get_base_image_offset( id, &x, &y, &w, &h );
+		scr_rect r = g_simgraph->get_base_image_offset(id);
 
 		switch (alignment) {
-
 			case ALIGN_RIGHT:
-				offset.x += size.w - w + remove_offset.x;
+				offset.x += size.w - r.w + remove_offset.x;
 				break;
 
 			case ALIGN_BOTTOM:
-				offset.y += size.h - h + remove_offset.y;
+				offset.y += size.h - r.h + remove_offset.y;
 				break;
 
 			case ALIGN_CENTER_H:
-				offset.x += D_GET_CENTER_ALIGN_OFFSET(w,size.w);
+				offset.x += D_GET_CENTER_ALIGN_OFFSET(r.w, size.w);
 				break;
 
 			case ALIGN_CENTER_V:
-				offset.y += D_GET_CENTER_ALIGN_OFFSET(h,size.h);
+				offset.y += D_GET_CENTER_ALIGN_OFFSET(r.h, size.h);
 				break;
-
 		}
+
 		if (color_index) {
-			display_base_img_blend(id , pos.x+offset.x+remove_offset.x, pos.y+offset.y+remove_offset.y, player_nr, color_index, false, true);
+			g_simgraph->draw_base_img_blend(id , pos.x+offset.x+remove_offset.x, pos.y+offset.y+remove_offset.y, player_nr, color_index, false, true CLIP_NUM_DEFAULT);
 		}
 		else {
-			display_base_img( id, pos.x+offset.x+remove_offset.x, pos.y+offset.y+remove_offset.y, (sint8)player_nr, false, true );
+			g_simgraph->draw_base_img( id, pos.x+offset.x+remove_offset.x, pos.y+offset.y+remove_offset.y, (sint8)player_nr, false, true CLIP_NUM_DEFAULT);
 		}
 	}
 }
diff --git a/src/simutrans/gui/components/gui_image_list.cc b/src/simutrans/gui/components/gui_image_list.cc
index a34aa4920..3477774c3 100644
--- a/src/simutrans/gui/components/gui_image_list.cc
+++ b/src/simutrans/gui/components/gui_image_list.cc
@@ -82,24 +82,23 @@ void gui_image_list_t::draw(scr_coord parent_pos)
 
 			// display mark
 			if(idata.lcolor!=EMPTY_IMAGE_BAR) {
-				display_fillbox_wh_clip_rgb( xpos + 1, ypos + grid.y - 5, grid.x/2 - 1, 4, idata.lcolor, true);
+				g_simgraph->draw_rect_clipped(xpos + 1, ypos + grid.y - 5, grid.x/2 - 1, 4, idata.lcolor, true CLIP_NUM_DEFAULT);
 			}
 			if(idata.rcolor!=EMPTY_IMAGE_BAR) {
-				display_fillbox_wh_clip_rgb( xpos + grid.x/2, ypos + grid.y - 5, grid.x - grid.x/2 - 1, 4, idata.rcolor, true);
+				g_simgraph->draw_rect_clipped(xpos + grid.x/2, ypos + grid.y - 5, grid.x - grid.x/2 - 1, 4, idata.rcolor, true CLIP_NUM_DEFAULT);
 			}
 			if (sel_index-- == 0) {
-				display_ddd_box_clip_rgb(xpos, ypos, grid.x, grid.y, color_idx_to_rgb(MN_GREY4), color_idx_to_rgb(MN_GREY0));
+				g_simgraph->draw_box3d_clipped(xpos, ypos, grid.x, grid.y, g_simgraph->palette_lookup(MN_GREY4), g_simgraph->palette_lookup(MN_GREY0));
 			}
 
 			// Get image data
-			scr_coord_val x,y,w,h;
-			display_get_base_image_offset( idata.image, &x, &y, &w, &h );
+			scr_rect r = g_simgraph->get_base_image_offset(idata.image);
 
 			// calculate image offsets
-			y = -y + (grid.y-h) - 6; // align to bottom mark
-			x = -x + 2;              // Add 2 pixel margin
+			r.y = -r.y + (grid.y-r.h) - 6; // align to bottom mark
+			r.x = -r.x + 2;                // Add 2 pixel margin
 			//display_base_img(idata.image, xpos + placement.x, ypos + placement.y, player_nr, false, true);
-			display_base_img(idata.image, xpos + x, ypos + y, player_nr, false, true);
+			g_simgraph->draw_base_img(idata.image, xpos + r.x, ypos + r.y, player_nr, false, true CLIP_NUM_DEFAULT);
 
 			// If necessary, display a number:
 			if(idata.count > 0) {
@@ -110,11 +109,11 @@ void gui_image_list_t::draw(scr_coord parent_pos)
 				// Let's make a black background to ensure visibility
 				for(int iy = -3; iy < 0; iy++) {
 					for(int ix = 1; ix < 4; ix++) {
-						display_proportional_clip_rgb(xpos + ix, ypos + iy, text, ALIGN_LEFT, color_idx_to_rgb(COL_BLACK), true);
+						g_simgraph->draw_text_clipped(xpos + ix, ypos + iy, text, ALIGN_LEFT, g_simgraph->palette_lookup(COL_BLACK), true);
 					}
 				}
 				// Display the number white on black
-				display_proportional_clip_rgb(xpos + 2, ypos - 2, text, ALIGN_LEFT, color_idx_to_rgb(COL_WHITE), true);
+				g_simgraph->draw_text_clipped(xpos + 2, ypos - 2, text, ALIGN_LEFT, g_simgraph->palette_lookup(COL_WHITE), true);
 			}
 		}
 		// advance x, y to next position
diff --git a/src/simutrans/gui/components/gui_label.cc b/src/simutrans/gui/components/gui_label.cc
index 4f9084470..0f24262a4 100644
--- a/src/simutrans/gui/components/gui_label.cc
+++ b/src/simutrans/gui/components/gui_label.cc
@@ -19,12 +19,12 @@ static scr_coord_val large_money_width = 0;
 gui_label_t::gui_label_t(const char* text, PIXVAL color_, align_t align_) :
 	align(align_), tooltip(NULL)
 {
-	separator_width = proportional_string_width( ",00$" );
+	separator_width = g_simgraph->calc_text_width( ",00$" );
 
 	if (get_large_money_string()) {
 		cbuffer_t buf;
 		buf.printf("%s$", get_large_money_string());
-		large_money_width = proportional_string_width((const char*) buf);
+		large_money_width = g_simgraph->calc_text_width((const char*) buf);
 	}
 	else {
 		large_money_width = 0;
@@ -38,7 +38,7 @@ gui_label_t::gui_label_t(const char* text, PIXVAL color_, align_t align_) :
 
 scr_size gui_label_t::get_min_size() const
 {
-	return scr_size( text ? display_calc_proportional_string_len_width(text,strlen(text)) : D_BUTTON_WIDTH, D_LABEL_HEIGHT );
+	return scr_size( text ? g_simgraph->calc_text_width(text) : D_BUTTON_WIDTH, D_LABEL_HEIGHT );
 }
 
 scr_size gui_label_t::get_max_size() const
@@ -63,7 +63,7 @@ void gui_label_t::set_text_pointer(const char *text_par, bool autosize)
 	text = text_par;
 
 	if (autosize && text && *text != '\0') {
-		set_size( scr_size( display_calc_proportional_string_len_width(text,strlen(text)),size.h ) );
+		set_size( scr_size( g_simgraph->calc_text_width(text), size.h ) );
 	}
 }
 
@@ -98,20 +98,20 @@ void gui_label_t::draw(scr_coord offset)
 			}
 
 			if(separator) {
-				display_proportional_clip_rgb(right.x, right.y, separator, ALIGN_LEFT, color, true);
+				g_simgraph->draw_text_clipped(right.x, right.y, separator, ALIGN_LEFT, color, true);
 				if(  separator!=text  ) {
 					if (shadowed) {
-						display_text_proportional_len_clip_rgb(right.x+1, right.y+1, text, ALIGN_RIGHT | DT_CLIP, color_shadow, true, separator - text);
+						g_simgraph->draw_text_clipped_n(right.x+1, right.y+1, text, ALIGN_RIGHT | DT_CLIP, color_shadow, true, separator - text CLIP_NUM_DEFAULT);
 					}
-					display_text_proportional_len_clip_rgb(right.x, right.y, text, ALIGN_RIGHT | DT_CLIP, color, true, separator-text );
+					g_simgraph->draw_text_clipped_n(right.x, right.y, text, ALIGN_RIGHT | DT_CLIP, color, true, separator-text CLIP_NUM_DEFAULT);
 				}
 			}
 			else {
 				// integer or normal text
 				if (shadowed) {
-					display_proportional_clip_rgb(right.x + 1, right.y + 1, text, ALIGN_RIGHT | DT_CLIP, color_shadow, true);
+					g_simgraph->draw_text_clipped(right.x + 1, right.y + 1, text, ALIGN_RIGHT | DT_CLIP, color_shadow, true);
 				}
-				display_proportional_clip_rgb(right.x, right.y, text, ALIGN_RIGHT, color, true);
+				g_simgraph->draw_text_clipped(right.x, right.y, text, ALIGN_RIGHT, color, true);
 			}
 		}
 	}
@@ -119,7 +119,7 @@ void gui_label_t::draw(scr_coord offset)
 	else if(text) {
 		const scr_rect area( offset+pos, size );
 		int a = align == left ? ALIGN_LEFT : ( align == right ? ALIGN_RIGHT : ALIGN_CENTER_H);
-		display_proportional_ellipsis_rgb( area, text,  a | DT_CLIP, color, true, shadowed, color_shadow );
+		g_simgraph->draw_text_ellipsis_shadowed( area, text,  a | DT_CLIP, color, true, shadowed, color_shadow );
 	}
 
 	if ( tooltip  &&  getroffen(get_mouse_pos() - offset) ) {
diff --git a/src/simutrans/gui/components/gui_map_preview.h b/src/simutrans/gui/components/gui_map_preview.h
index c42ed9a95..e633ec93c 100644
--- a/src/simutrans/gui/components/gui_map_preview.h
+++ b/src/simutrans/gui/components/gui_map_preview.h
@@ -36,10 +36,10 @@ class gui_map_preview_t : public gui_component_t
 		 * Draws the component.
 		 */
 		void draw(scr_coord offset) OVERRIDE {
-			display_ddd_box_clip_rgb(pos.x + offset.x, pos.y + offset.y, size.w, size.h, color_idx_to_rgb(MN_GREY0), color_idx_to_rgb(MN_GREY4));
+			g_simgraph->draw_box3d_clipped(pos.x + offset.x, pos.y + offset.y, size.w, size.h, g_simgraph->palette_lookup(MN_GREY0), g_simgraph->palette_lookup(MN_GREY4));
 
 			if(map_data) {
-				display_array_wh(pos.x + offset.x + 1, pos.y + offset.y + 1, map_data->get_width(), map_data->get_height(), map_data->to_array());
+				g_simgraph->draw_array(pos.x + offset.x + 1, pos.y + offset.y + 1, map_data->get_width(), map_data->get_height(), map_data->to_array());
 			}
 		}
 
diff --git a/src/simutrans/gui/components/gui_numberinput.cc b/src/simutrans/gui/components/gui_numberinput.cc
index 9ea26e40d..0d17a7e49 100644
--- a/src/simutrans/gui/components/gui_numberinput.cc
+++ b/src/simutrans/gui/components/gui_numberinput.cc
@@ -86,7 +86,7 @@ void gui_numberinput_t::set_value(sint32 new_value)
 		sprintf(textbuffer, "%d", new_value);
 		textinp.set_text(textbuffer, 20);
 	}
-	textinp.set_color( value == new_value ? (b_enabled ? SYSCOL_EDIT_TEXT : SYSCOL_EDIT_TEXT_DISABLED) : color_idx_to_rgb(COL_RED) );
+	textinp.set_color( value == new_value ? (b_enabled ? SYSCOL_EDIT_TEXT : SYSCOL_EDIT_TEXT_DISABLED) : g_simgraph->palette_lookup(COL_RED) );
 	value = new_value;
 }
 
@@ -115,7 +115,7 @@ void gui_numberinput_t::set_limits(sint32 _min, sint32 _max)
 	max_value = _max;
 
 	// minus sign
-	max_numbertext_width = (min_value > 0) ? 0 : display_get_char_width('-');
+	max_numbertext_width = (min_value > 0) ? 0 : g_simgraph->get_char_width('-');
 	// count digits
 	uint32 max_abs = max_value > 0 ? max_value : -max_value;
 	if (min_value < 0  &&  (uint32) (-min_value) > max_abs) {
@@ -123,12 +123,12 @@ void gui_numberinput_t::set_limits(sint32 _min, sint32 _max)
 	}
 	// width of digits
 	while (max_abs) {
-		max_numbertext_width += display_get_number_width();
+		max_numbertext_width += g_simgraph->get_number_width();
 		max_abs /= 10;
 	}
 	// enforce a min width of 5 digits
-	if (max_numbertext_width < 5 * display_get_number_width()) {
-		max_numbertext_width = 5 * display_get_number_width();
+	if (max_numbertext_width < 5 * g_simgraph->get_number_width()) {
+		max_numbertext_width = 5 * g_simgraph->get_number_width();
 	}
 }
 
diff --git a/src/simutrans/gui/components/gui_schedule.cc b/src/simutrans/gui/components/gui_schedule.cc
index 60672b9f4..774031ae4 100644
--- a/src/simutrans/gui/components/gui_schedule.cc
+++ b/src/simutrans/gui/components/gui_schedule.cc
@@ -133,7 +133,7 @@ public:
 	{
 		update_label();
 		if (is_current  ||  !valid) {
-			display_fillbox_wh_clip_rgb(pos.x + offset.x, pos.y + offset.y, size.w, size.h, valid ? SYSCOL_LIST_BACKGROUND_SELECTED_F : MONEY_MINUS, false);
+			g_simgraph->draw_rect_clipped(pos.x + offset.x, pos.y + offset.y, size.w, size.h, valid ? SYSCOL_LIST_BACKGROUND_SELECTED_F : MONEY_MINUS, false CLIP_NUM_DEFAULT);
 		}
 		gui_aligned_container_t::draw(offset);
 	}
diff --git a/src/simutrans/gui/components/gui_scrollbar.cc b/src/simutrans/gui/components/gui_scrollbar.cc
index ea52a1b53..f6f228e8f 100644
--- a/src/simutrans/gui/components/gui_scrollbar.cc
+++ b/src/simutrans/gui/components/gui_scrollbar.cc
@@ -269,7 +269,7 @@ void scrollbar_t::draw(scr_coord pos_par)
 	// Draw place holder if scrollbar is full in auto mode
 	if ( visible_mode == show_auto  &&  full  ) {
 		// Draw place holder themed with scrollbar background
-		display_img_stretch( gui_theme_t::v_scroll_back_tiles, scr_rect( pos_par, size ) );
+		g_simgraph->draw_stretch_map( gui_theme_t::v_scroll_back_tiles, scr_rect( pos_par, size ) );
 		return;
 	}
 
@@ -279,11 +279,11 @@ void scrollbar_t::draw(scr_coord pos_par)
 
 	// now background and slider
 	if(  type == vertical  ) {
-		display_img_stretch( gui_theme_t::v_scroll_back_tiles, scr_rect( pos_par + sliderarea.get_pos(), sliderarea.get_size() ) );
-		display_img_stretch( gui_theme_t::v_scroll_knob_tiles, scr_rect( pos_par + knobarea.get_pos(), knobarea.get_size() ) );
+		g_simgraph->draw_stretch_map( gui_theme_t::v_scroll_back_tiles, scr_rect( pos_par + sliderarea.get_pos(), sliderarea.get_size() ) );
+		g_simgraph->draw_stretch_map( gui_theme_t::v_scroll_knob_tiles, scr_rect( pos_par + knobarea.get_pos(), knobarea.get_size() ) );
 	}
 	else {
-		display_img_stretch( gui_theme_t::h_scroll_back_tiles, scr_rect( pos_par + sliderarea.get_pos(), sliderarea.get_size() ) );
-		display_img_stretch( gui_theme_t::h_scroll_knob_tiles, scr_rect( pos_par + knobarea.get_pos(), knobarea.get_size() ) );
+		g_simgraph->draw_stretch_map( gui_theme_t::h_scroll_back_tiles, scr_rect( pos_par + sliderarea.get_pos(), sliderarea.get_size() ) );
+		g_simgraph->draw_stretch_map( gui_theme_t::h_scroll_knob_tiles, scr_rect( pos_par + knobarea.get_pos(), knobarea.get_size() ) );
 	}
 }
diff --git a/src/simutrans/gui/components/gui_scrolled_list.cc b/src/simutrans/gui/components/gui_scrolled_list.cc
index c65fbbcd9..82b988bb5 100644
--- a/src/simutrans/gui/components/gui_scrolled_list.cc
+++ b/src/simutrans/gui/components/gui_scrolled_list.cc
@@ -31,7 +31,7 @@ scr_size gui_scrolled_list_t::const_text_scrollitem_t::get_min_size() const
 {
 	if (!is_editable()) {
 		const char* text = get_text();
-		return scr_size(2*D_H_SPACE + (text ? display_calc_proportional_string_len_width(text,strlen(text)) : D_BUTTON_WIDTH), LINESPACE);
+		return scr_size(2*D_H_SPACE + (text ? g_simgraph->calc_text_width(text) : D_BUTTON_WIDTH), LINESPACE);
 	}
 	else {
 		return scr_size(D_BUTTON_WIDTH, LINESPACE);
@@ -49,12 +49,12 @@ void gui_scrolled_list_t::const_text_scrollitem_t::draw(scr_coord pos)
 	pos += get_pos();
 	if(selected) {
 		// selected element
-		display_fillbox_wh_clip_rgb( pos.x+D_H_SPACE/2, pos.y-1, get_size().w-D_H_SPACE, get_size().h + 1, (focused ? SYSCOL_LIST_BACKGROUND_SELECTED_F : SYSCOL_LIST_BACKGROUND_SELECTED_NF), true);
-		display_proportional_clip_rgb( pos.x+D_H_SPACE, pos.y, get_text(), ALIGN_LEFT, (focused ? SYSCOL_LIST_TEXT_SELECTED_FOCUS : SYSCOL_LIST_TEXT_SELECTED_NOFOCUS), true);
+		g_simgraph->draw_rect_clipped( pos.x+D_H_SPACE/2, pos.y-1, get_size().w-D_H_SPACE, get_size().h + 1, (focused ? SYSCOL_LIST_BACKGROUND_SELECTED_F : SYSCOL_LIST_BACKGROUND_SELECTED_NF), true CLIP_NUM_DEFAULT);
+		g_simgraph->draw_text_clipped( pos.x+D_H_SPACE, pos.y, get_text(), ALIGN_LEFT, (focused ? SYSCOL_LIST_TEXT_SELECTED_FOCUS : SYSCOL_LIST_TEXT_SELECTED_NOFOCUS), true);
 	}
 	else {
 		// normal text
-		display_proportional_clip_rgb( pos.x+D_H_SPACE, pos.y, get_text(), ALIGN_LEFT, get_color(), true);
+		g_simgraph->draw_text_clipped( pos.x+D_H_SPACE, pos.y, get_text(), ALIGN_LEFT, get_color(), true);
 	}
 }
 
@@ -294,10 +294,10 @@ void gui_scrolled_list_t::draw(scr_coord offset)
 		scr_rect rect(pos + offset, get_size());
 		switch(type) {
 			case windowskin:
-				display_img_stretch( gui_theme_t::windowback, rect);
+				g_simgraph->draw_stretch_map( gui_theme_t::windowback, rect);
 				break;
 			case listskin:
-				display_img_stretch( gui_theme_t::listbox, rect);
+				g_simgraph->draw_stretch_map( gui_theme_t::listbox, rect);
 				break;
 			case transparent:
 				break;
diff --git a/src/simutrans/gui/components/gui_speedbar.cc b/src/simutrans/gui/components/gui_speedbar.cc
index b63b4eea2..facda6475 100644
--- a/src/simutrans/gui/components/gui_speedbar.cc
+++ b/src/simutrans/gui/components/gui_speedbar.cc
@@ -44,12 +44,12 @@ void gui_speedbar_t::draw(scr_coord offset)
 		for(info_t const& i : values) {
 			sint32 const to = size.h - min(*i.value, base) * size.h / base;
 			if(to < from) {
-				display_fillbox_wh_clip_rgb(offset.x, offset.y + to, size.w, from - to, i.color, true);
+				g_simgraph->draw_rect_clipped(offset.x, offset.y + to, size.w, from - to, i.color, true CLIP_NUM_DEFAULT);
 				from = to - 1;
 			}
 		}
 		if(from > 0) {
-			display_fillbox_wh_clip_rgb( offset.x, offset.y, size.w, from, color_idx_to_rgb(MN_GREY0), true);
+			g_simgraph->draw_rect_clipped( offset.x, offset.y, size.w, from, g_simgraph->palette_lookup(MN_GREY0), true CLIP_NUM_DEFAULT);
 		}
 	}
 	else {
@@ -57,12 +57,12 @@ void gui_speedbar_t::draw(scr_coord offset)
 		for(info_t const& i : values) {
 			sint32 const to = min(*i.value, base) * size.w / base;
 			if(to > from) {
-				display_fillbox_wh_clip_rgb(offset.x + from, offset.y, to - from, size.h, i.color, true);
+				g_simgraph->draw_rect_clipped(offset.x + from, offset.y, to - from, size.h, i.color, true CLIP_NUM_DEFAULT);
 				from = to + 1;
 			}
 		}
 		if(from < size.w) {
-			display_fillbox_wh_clip_rgb(offset.x + from, offset.y, size.w - from, size.h, color_idx_to_rgb(MN_GREY0), true);
+			g_simgraph->draw_rect_clipped(offset.x + from, offset.y, size.w - from, size.h, g_simgraph->palette_lookup(MN_GREY0), true CLIP_NUM_DEFAULT);
 		}
 	}
 }
@@ -75,7 +75,7 @@ void gui_speedbar_fixed_length_t::draw(scr_coord offset)
 	for (info_t const& i : values) {
 		sint32 const to = min(*i.value, base) * fixed_width / base;
 		if (to > from) {
-			display_fillbox_wh_clip_rgb(offset.x + from, offset.y, to - from, size.h, i.color, true);
+			g_simgraph->draw_rect_clipped(offset.x + from, offset.y, to - from, size.h, i.color, true CLIP_NUM_DEFAULT);
 			from = to + 1;
 		}
 		if (from > size.w) {
@@ -84,7 +84,7 @@ void gui_speedbar_fixed_length_t::draw(scr_coord offset)
 		}
 	}
 	if (from < size.w) {
-		display_fillbox_wh_clip_rgb(offset.x + from, offset.y, size.w - from, size.h, color_idx_to_rgb(MN_GREY0), true);
+		g_simgraph->draw_rect_clipped(offset.x + from, offset.y, size.w - from, size.h, g_simgraph->palette_lookup(MN_GREY0), true CLIP_NUM_DEFAULT);
 	}
 }
 
@@ -118,35 +118,35 @@ void gui_routebar_t::draw(scr_coord offset)
 	const uint16 w = size.w - h/2;
 
 	offset += pos;
-	display_fillbox_wh_clip_rgb(offset.x, offset.y+h/2-1, w, 3, color_idx_to_rgb(MN_GREY1), true);
+	g_simgraph->draw_rect_clipped(offset.x, offset.y+h/2-1, w, 3, g_simgraph->palette_lookup(MN_GREY1), true CLIP_NUM_DEFAULT);
 
 	PIXVAL col;
 	for (uint8 i = 0; i<5; i++) {
 		col = i % 2 ? COL_GREY4-1 : MN_GREY0;
-		display_vline_wh_clip_rgb(offset.x + h/2 + w*i/4, offset.y+i%2, h-(i%2)*2, color_idx_to_rgb(col), true);
+		g_simgraph->draw_vline_clipped(offset.x + h/2 + w*i/4, offset.y+i%2, h-(i%2)*2, g_simgraph->palette_lookup(col), true CLIP_NUM_DEFAULT);
 	}
 	sint32 const to = min(*value, base) * w / base;
 	if (reserve_value  &&  *reserve_value) {
 		sint32 const reserved_to = min(*reserve_value, base) * w / base;
-		display_fillbox_wh_clip_rgb(offset.x + h / 2, offset.y + h / 2 - 1, reserved_to, 3, reserved_color, true);
+		g_simgraph->draw_rect_clipped(offset.x + h / 2, offset.y + h / 2 - 1, reserved_to, 3, reserved_color, true CLIP_NUM_DEFAULT);
 	}
-	display_fillbox_wh_clip_rgb(offset.x+h/2, offset.y+h/2-1, to, 3, color_idx_to_rgb(43), true);
+	g_simgraph->draw_rect_clipped(offset.x+h/2, offset.y+h/2-1, to, 3, g_simgraph->palette_lookup(43), true CLIP_NUM_DEFAULT);
 
 	switch (state)
 	{
 		case 1:
-			display_fillbox_wh_clip_rgb(offset.x + to + 1, offset.y + 1, h - 2, h - 2, color_idx_to_rgb(COL_YELLOW), true);
+			g_simgraph->draw_rect_clipped(offset.x + to + 1, offset.y + 1, h - 2, h - 2, g_simgraph->palette_lookup(COL_YELLOW), true CLIP_NUM_DEFAULT);
 			break;
 		case 2:
-			display_fillbox_wh_clip_rgb(offset.x + to + 1, offset.y + 1, h - 2, h - 2, color_idx_to_rgb(COL_ORANGE), true);
+			g_simgraph->draw_rect_clipped(offset.x + to + 1, offset.y + 1, h - 2, h - 2, g_simgraph->palette_lookup(COL_ORANGE), true CLIP_NUM_DEFAULT);
 			break;
 		case 3:
-			display_fillbox_wh_clip_rgb(offset.x + to + 1, offset.y + 1, h - 2, h - 2, color_idx_to_rgb(COL_RED), true);
+			g_simgraph->draw_rect_clipped(offset.x + to + 1, offset.y + 1, h - 2, h - 2, g_simgraph->palette_lookup(COL_RED), true CLIP_NUM_DEFAULT);
 			break;
 		case 0:
 		default:
-			display_fillbox_wh_clip_rgb( offset.x+h/2, offset.y + 1, to-2, h - 2, color_idx_to_rgb( COL_GREEN ), true );
-			display_right_triangle_rgb(offset.x + to, offset.y, h, color_idx_to_rgb(COL_MAGENTA), true);
+			g_simgraph->draw_rect_clipped( offset.x+h/2, offset.y + 1, to-2, h - 2, g_simgraph->palette_lookup( COL_GREEN ), true CLIP_NUM_DEFAULT);
+			g_simgraph->draw_right_triangle(offset.x + to, offset.y, h, g_simgraph->palette_lookup(COL_MAGENTA), true);
 			break;
 	}
 }
diff --git a/src/simutrans/gui/components/gui_speedbar.h b/src/simutrans/gui/components/gui_speedbar.h
index 683568db9..81669c5f3 100644
--- a/src/simutrans/gui/components/gui_speedbar.h
+++ b/src/simutrans/gui/components/gui_speedbar.h
@@ -67,7 +67,7 @@ private:
 
 public:
 	gui_routebar_t() { base = 100; state = 0; height = 9; value = 0; reserve_value = 0; }
-	void set_reservation(const sint32 *value, PIXVAL color = color_idx_to_rgb(COL_BLUE));
+	void set_reservation(const sint32 *value, PIXVAL color = g_simgraph->palette_lookup(COL_BLUE));
 	void set_reserved_color(PIXVAL color) { reserved_color = color; };
 	void set_base(sint32 base);
 	void init(const sint32 *value, uint8 state);
diff --git a/src/simutrans/gui/components/gui_tab_panel.cc b/src/simutrans/gui/components/gui_tab_panel.cc
index e1b6b083a..5b149ebc7 100644
--- a/src/simutrans/gui/components/gui_tab_panel.cc
+++ b/src/simutrans/gui/components/gui_tab_panel.cc
@@ -55,7 +55,7 @@ void gui_tab_panel_t::set_size(scr_size size)
 	for(tab & i : tabs) {
 		i.x_offset = required_size.w - 4;
 		if( i.title ) {
-			i.width = D_H_SPACE*2 + proportional_string_width( i.title );
+			i.width = D_H_SPACE*2 + g_simgraph->calc_text_width( i.title );
 			required_size.h = max( required_size.h, LINESPACE + D_V_SPACE );
 		}
 		else if( i.img ) {
@@ -253,16 +253,16 @@ void gui_tab_panel_t::draw(scr_coord parent_pos)
 	if(  required_size.w>size.w  || tab_offset_x > 0) {
 		left.draw( parent_pos+pos );
 		right.draw( parent_pos+pos );
-		//display_fillbox_wh_clip_rgb(xpos, ypos+required_size.h-1, 10, 1, SYSCOL_TEXT_HIGHLIGHT, true);
-		display_fillbox_wh_clip_rgb(xpos, ypos+required_size.h-1, D_ARROW_LEFT_WIDTH, 1, SYSCOL_HIGHLIGHT, true);
+		//g_simgraph->draw_rect_clipped(xpos, ypos+required_size.h-1, 10, 1, SYSCOL_TEXT_HIGHLIGHT, true CLIP_NUM_DEFAULT);
+		g_simgraph->draw_rect_clipped(xpos, ypos+required_size.h-1, D_ARROW_LEFT_WIDTH, 1, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
 		xpos += D_ARROW_LEFT_WIDTH;
 	}
 
 	int text_x = xpos + D_H_SPACE;
 	int text_y = ypos + (required_size.h - LINESPACE)/2;
 
-	//display_fillbox_wh_clip_rgb(xpos, ypos+required_size.h-1, 4, 1, color_idx_to_rgb(COL_WHITE), true);
-	display_fillbox_wh_clip_rgb(xpos, ypos+required_size.h-1, 4, 1, SYSCOL_HIGHLIGHT, true);
+	//g_simgraph->draw_rect_clipped(xpos, ypos+required_size.h-1, 4, 1, g_simgraph->palette_lookup(COL_WHITE), true CLIP_NUM_DEFAULT);
+	g_simgraph->draw_rect_clipped(xpos, ypos+required_size.h-1, 4, 1, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
 
 	// do not draw under right button
 	int xx = required_size.w>get_size().w ? get_size().w-(D_ARROW_LEFT_WIDTH+2+D_ARROW_RIGHT_WIDTH) : get_size().w;
@@ -281,45 +281,46 @@ void gui_tab_panel_t::draw(scr_coord parent_pos)
 
 		if (i != active_tab) {
 			// Non active tabs
-			display_fillbox_wh_clip_rgb(text_x+1, ypos+2, iter.width-2, 1, SYSCOL_HIGHLIGHT, true);
-			display_fillbox_wh_clip_rgb(text_x, ypos+required_size.h-1, iter.width-2, 1, SYSCOL_HIGHLIGHT, true);
+			g_simgraph->draw_rect_clipped(text_x+1, ypos+2, iter.width-2, 1, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
+			g_simgraph->draw_rect_clipped(text_x, ypos+required_size.h-1, iter.width-2, 1, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
 
-			display_vline_wh_clip_rgb(text_x, ypos+3, required_size.h-4, SYSCOL_HIGHLIGHT, true);
-			display_vline_wh_clip_rgb(text_x+iter.width-1, ypos+3, required_size.h-4, SYSCOL_SHADOW, true);
+			g_simgraph->draw_vline_clipped(text_x,              ypos+3, required_size.h-4, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
+			g_simgraph->draw_vline_clipped(text_x+iter.width-1, ypos+3, required_size.h-4, SYSCOL_SHADOW,    true CLIP_NUM_DEFAULT);
 
 			if(text) {
-				display_proportional_clip_rgb(text_x+D_H_SPACE, text_y+2, text, ALIGN_LEFT, SYSCOL_TEXT, true);
+				g_simgraph->draw_text_clipped(text_x+D_H_SPACE, text_y+2, text, ALIGN_LEFT, SYSCOL_TEXT, true);
 			}
 			else {
 				scr_coord_val const y = ypos   - iter.img->get_pic()->y + required_size.h / 2 - iter.img->get_pic()->h / 2 + 1;
 				scr_coord_val const x = text_x - iter.img->get_pic()->x + iter.width / 2      - iter.img->get_pic()->w / 2;
 //					display_img_blend(iter.img->get_id(), x, y, TRANSPARENT50_FLAG, false, true);
-				display_base_img(iter.img->get_id(), x, y, 1, false, true);
+				g_simgraph->draw_base_img(iter.img->get_id(), x, y, 1, false, true CLIP_NUM_DEFAULT);
 			}
 		}
 		else {
 			// Active tab
-			display_fillbox_wh_clip_rgb(text_x+1, ypos, iter.width-2, 1, SYSCOL_HIGHLIGHT, true);
+			g_simgraph->draw_rect_clipped(text_x+1, ypos, iter.width-2, 1, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
 
-			display_vline_wh_clip_rgb(text_x, ypos+1, required_size.h-2, SYSCOL_HIGHLIGHT, true);
-			display_vline_wh_clip_rgb(text_x+iter.width-1, ypos+1, required_size.h-2, SYSCOL_SHADOW, true);
+			g_simgraph->draw_vline_clipped(text_x,              ypos+1, required_size.h-2, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
+			g_simgraph->draw_vline_clipped(text_x+iter.width-1, ypos+1, required_size.h-2, SYSCOL_SHADOW,    true CLIP_NUM_DEFAULT);
 
 			if(text) {
-				display_proportional_clip_rgb(text_x+D_H_SPACE, text_y, text, ALIGN_LEFT, SYSCOL_TEXT_HIGHLIGHT, true);
+				g_simgraph->draw_text_clipped(text_x+D_H_SPACE, text_y, text, ALIGN_LEFT, SYSCOL_TEXT_HIGHLIGHT, true);
 			}
 			else {
 				scr_coord_val const y = ypos   - iter.img->get_pic()->y + required_size.h / 2 - iter.img->get_pic()->h / 2 - 1;
 				scr_coord_val const x = text_x - iter.img->get_pic()->x + iter.width / 2      - iter.img->get_pic()->w / 2;
-				display_base_img(iter.img->get_id(), x, y, 1, false, true);
+				g_simgraph->draw_base_img(iter.img->get_id(), x, y, 1, false, true CLIP_NUM_DEFAULT);
 			}
 		}
+
 		text_x += iter.width;
 		// reset clipping
 		POP_CLIP();
 
 		i++;
 	}
-	display_fillbox_wh_clip_rgb(text_x, ypos+required_size.h-1, xpos+size.w-text_x, 1, SYSCOL_HIGHLIGHT, true);
+	g_simgraph->draw_rect_clipped(text_x, ypos+required_size.h-1, xpos+size.w-text_x, 1, SYSCOL_HIGHLIGHT, true CLIP_NUM_DEFAULT);
 
 	// draw tab content after tab row
 	// (combobox may open to above, and tab row may draw into it)
diff --git a/src/simutrans/gui/components/gui_textarea.cc b/src/simutrans/gui/components/gui_textarea.cc
index 6db92f782..06dbcd244 100644
--- a/src/simutrans/gui/components/gui_textarea.cc
+++ b/src/simutrans/gui/components/gui_textarea.cc
@@ -62,7 +62,7 @@ scr_size gui_textarea_t::calc_size() const
 			do {
 				next = strchr(buf, '\n');
 				const size_t len = next ? next-buf : 99999;
-				const int px_len = display_calc_proportional_string_len_width(buf, len);
+				const int px_len = g_simgraph->calc_text_width_n(buf, len);
 
 				if(  px_len > x_size  ) {
 					x_size = px_len;
@@ -89,7 +89,7 @@ void gui_textarea_t::draw(scr_coord offset)
 {
 	const char *text(*buf);
 
-	// we cannot use: display_multiline_text(pos.x+offset.x, pos.y+offset.y+10, text, color_idx_to_rgb(COL_BLACK));
+	// we cannot use: display_multiline_text(pos.x+offset.x, pos.y+offset.y+10, text, g_simgraph->palette_lookup(COL_BLACK));
 	// since we also want to dynamically change the size of the component
 	scr_coord_val new_lines = 0;
 
@@ -107,13 +107,13 @@ void gui_textarea_t::draw(scr_coord offset)
 			const size_t len = next != NULL ? next - buf : -1;
 			scr_coord_val const draw_y = y + new_lines;
 			int px_len;
-			if (  -LINESPACE <= draw_y  &&  draw_y <= display_get_height() + LINESPACE) {
+			if (  -LINESPACE <= draw_y  &&  draw_y <= g_simgraph->get_screen_size().h + LINESPACE) {
 				// draw when in screen area
-				px_len = display_text_proportional_len_clip_rgb(x, draw_y, buf, ALIGN_LEFT | DT_CLIP, SYSCOL_TEXT, true, len);
+				px_len = g_simgraph->draw_text_clipped_n(x, draw_y, buf, ALIGN_LEFT | DT_CLIP, SYSCOL_TEXT, true, len CLIP_NUM_DEFAULT);
 			}
 			else {
 				// track required length when out of screen area
-				px_len = display_calc_proportional_string_len_width(buf, len);
+				px_len = g_simgraph->calc_text_width_n(buf, len);
 			}
 			if(px_len>x_size) {
 				x_size = px_len;
diff --git a/src/simutrans/gui/components/gui_textinput.cc b/src/simutrans/gui/components/gui_textinput.cc
index 28b198e56..7774a6ee2 100644
--- a/src/simutrans/gui/components/gui_textinput.cc
+++ b/src/simutrans/gui/components/gui_textinput.cc
@@ -56,7 +56,7 @@ size_t gui_textinput_t::calc_cursor_pos(const int x)
 		uint8 pixel_width = 0;
 		scr_coord_val current_offset = 0;
 		const scr_coord_val adjusted_offset = x - 1 + scroll_offset;
-		while(  get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  adjusted_offset>(current_offset+(pixel_width>>1))  ) {
+		while(  g_simgraph->get_next_char_with_metrics(tmp_text, byte_length, pixel_width)  &&  adjusted_offset>(current_offset+(pixel_width>>1))  ) {
 			current_offset += pixel_width;
 			new_cursor_pos += byte_length;
 		}
@@ -100,7 +100,7 @@ void gui_textinput_t::set_composition_status( char *c, int start, int length )
 			composition_target_length = length;
 
 			const scr_coord gui_xy = win_get_pos( win_get_top() );
-			const int offset_to_target = proportional_string_len_width( composition.get_str(), composition_target_start );
+			const int offset_to_target = g_simgraph->calc_text_width_n( composition.get_str(), composition_target_start );
 			const scr_coord_val x = pos.x + gui_xy.x + get_current_cursor_x() + offset_to_target;
 			const scr_coord_val y = pos.x + gui_xy.y + D_TITLEBAR_HEIGHT;
 			dr_notify_input_pos({ x, y });
@@ -187,7 +187,7 @@ bool gui_textinput_t::infowin_event(const event_t *ev)
 							uint8 byte_length = 0;
 							uint8 pixel_width = 0;
 							// first skip over all contiguous space characters to the left
-							while(  head_cursor_pos>0  &&  get_prev_char_with_metrics(tmp_text, text, byte_length, pixel_width)==SIM_KEY_SPACE  ) {
+							while(  head_cursor_pos>0  &&  g_simgraph->get_prev_char_with_metrics(tmp_text, text, byte_length, pixel_width)==SIM_KEY_SPACE  ) {
 								head_cursor_pos -= byte_length;
 							}
 							// revert text pointer for further processing
@@ -195,7 +195,7 @@ bool gui_textinput_t::infowin_event(const event_t *ev)
 								tmp_text += byte_length;
 							}
 							// then skip over all contiguous non-space characters further to the left
-							while(  head_cursor_pos>0  &&  get_prev_char_with_metrics(tmp_text, text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
+							while(  head_cursor_pos>0  &&  g_simgraph->get_prev_char_with_metrics(tmp_text, text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
 								head_cursor_pos -= byte_length;
 							}
 						}
@@ -216,7 +216,7 @@ bool gui_textinput_t::infowin_event(const event_t *ev)
 							uint8 byte_length = 0;
 							uint8 pixel_width = 0;
 							// first skip over all contiguous non-space characters to the right
-							while(  head_cursor_pos<len  &&  get_next_char_with_metrics(tmp_text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
+							while(  head_cursor_pos<len  &&  g_simgraph->get_next_char_with_metrics(tmp_text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
 								head_cursor_pos += byte_length;
 							}
 							// revert text pointer for further processing
@@ -224,7 +224,7 @@ bool gui_textinput_t::infowin_event(const event_t *ev)
 								tmp_text -= byte_length;
 							}
 							// then skip over all contiguous space characters further to the right
-							while(  head_cursor_pos<len  &&  get_next_char_with_metrics(tmp_text, byte_length, pixel_width)==SIM_KEY_SPACE  ) {
+							while(  head_cursor_pos<len  &&  g_simgraph->get_next_char_with_metrics(tmp_text, byte_length, pixel_width)==SIM_KEY_SPACE  ) {
 								head_cursor_pos += byte_length;
 							}
 						}
@@ -450,7 +450,7 @@ bool gui_textinput_t::infowin_event(const event_t *ev)
 		// use mouse *click* position; update both head and tail cursors
 		tail_cursor_pos = 0;
 		if(  text  ) {
-			tail_cursor_pos = head_cursor_pos = display_fit_proportional( text, ev->click_pos.x - 2 + scroll_offset );
+			tail_cursor_pos = head_cursor_pos = g_simgraph->calc_text_index_for_width( text, ev->click_pos.x - 2 + scroll_offset );
 		}
 		cursor_reference_time = dr_time(); // update reference time for cursor blinking
 		return true;
@@ -465,7 +465,7 @@ bool gui_textinput_t::infowin_event(const event_t *ev)
 		// use mouse *move* position; update head cursor only in order to enable text selection
 		head_cursor_pos = 0;
 		if(  text  ) {
-			head_cursor_pos = display_fit_proportional( text, ev->mouse_pos.x - 1 + scroll_offset );
+			head_cursor_pos = g_simgraph->calc_text_index_for_width( text, ev->mouse_pos.x - 1 + scroll_offset );
 		}
 		cursor_reference_time = dr_time(); // update reference time for cursor blinking
 		return true;
@@ -482,13 +482,13 @@ bool gui_textinput_t::infowin_event(const event_t *ev)
 		const char* tmp_text = text + tail_cursor_pos;
 		uint8 byte_length;
 		uint8 pixel_width;
-		while(  tail_cursor_pos>0  &&  get_prev_char_with_metrics(tmp_text, text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
+		while(  tail_cursor_pos>0  &&  g_simgraph->get_prev_char_with_metrics(tmp_text, text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
 			tail_cursor_pos -= byte_length;
 		}
 		// for head cursor pos -> skip over all contiguous non-space characters to the right
 		const size_t len = strlen(text);
 		tmp_text = text + head_cursor_pos;
-		while(  head_cursor_pos<len  &&  get_next_char_with_metrics(tmp_text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
+		while(  head_cursor_pos<len  &&  g_simgraph->get_next_char_with_metrics(tmp_text, byte_length, pixel_width)!=SIM_KEY_SPACE  ) {
 			head_cursor_pos += byte_length;
 		}
 	}
@@ -578,7 +578,7 @@ void gui_textinput_t::display_with_focus(scr_coord offset, bool has_focus)
 
 void gui_textinput_t::display_with_cursor(scr_coord offset, bool cursor_active, bool cursor_visible)
 {
-	display_img_stretch( gui_theme_t::editfield, scr_rect( pos+offset, size ) );
+	g_simgraph->draw_stretch_map( gui_theme_t::editfield, scr_rect( pos+offset, size ) );
 
 	if(  text  ) {
 
@@ -588,9 +588,9 @@ void gui_textinput_t::display_with_cursor(scr_coord offset, bool cursor_active,
 		}
 
 		// recalculate scroll offset
-		const int text_width = proportional_string_width(text);
+		const int text_width = g_simgraph->calc_text_width(text);
 		const scr_coord_val view_width = size.w - 3;
-		const int cursor_offset = cursor_active ? proportional_string_len_width(text, head_cursor_pos) : 0;
+		const int cursor_offset = cursor_active ? g_simgraph->calc_text_width_n(text, head_cursor_pos) : 0;
 		if(  text_width<=view_width  ) {
 			// case : text is shorter than displayable width of the text input
 			//        -> the only case where left and right alignments differ
@@ -632,45 +632,45 @@ void gui_textinput_t::display_with_cursor(scr_coord offset, bool cursor_active,
 		const int y_offset = pos.y+offset.y+D_GET_CENTER_ALIGN_OFFSET(LINESPACE,size.h);
 
 		// display text (before composition)
-		display_text_proportional_len_clip_rgb(x_base_offset, y_offset, text, ALIGN_LEFT | DT_CLIP, textcol, true, head_cursor_pos);
-		int x_offset = proportional_string_len_width(text, head_cursor_pos);
+		g_simgraph->draw_text_clipped_n(x_base_offset, y_offset, text, ALIGN_LEFT | DT_CLIP, textcol, true, head_cursor_pos CLIP_NUM_DEFAULT);
+		int x_offset = g_simgraph->calc_text_width_n(text, head_cursor_pos);
 
 		// IME text to display?
 		if(  composition.len()  ) {
 //			assert(head_cursor_pos==tail_cursor_pos);
 
-			display_proportional_clip_rgb(x_base_offset+x_offset, y_offset, composition.get_str(), ALIGN_LEFT | DT_CLIP, textcol, true);
+			g_simgraph->draw_text_clipped(x_base_offset+x_offset, y_offset, composition.get_str(), ALIGN_LEFT | DT_CLIP, textcol, true);
 
 			// draw underline
-			int composition_width = proportional_string_width(composition.get_str());
-			display_direct_line_rgb(x_base_offset+x_offset, y_offset+LINESPACE, x_base_offset+x_offset+composition_width, y_offset+LINESPACE-1, textcol);
+			int composition_width = g_simgraph->calc_text_width(composition.get_str());
+			g_simgraph->draw_line(x_base_offset+x_offset, y_offset+LINESPACE, x_base_offset+x_offset+composition_width, y_offset+LINESPACE-1, textcol);
 
 			// mark targeted part in a similar manner to selected text
-			int start_offset = proportional_string_len_width(composition.get_str(), composition_target_start);
-			int highlight_width = proportional_string_len_width(composition.get_str()+composition_target_start, composition_target_length);
-			display_fillbox_wh_clip_rgb(x_base_offset+x_offset+start_offset, y_offset, highlight_width, LINESPACE, SYSCOL_EDIT_BACKGROUND_SELECTED, true);
-			display_text_proportional_len_clip_rgb(x_base_offset+x_offset+start_offset, y_offset, composition.get_str()+composition_target_start, ALIGN_LEFT|DT_CLIP, SYSCOL_EDIT_TEXT_SELECTED, false, composition_target_length);
+			int start_offset = g_simgraph->calc_text_width_n(composition.get_str(), composition_target_start);
+			int highlight_width = g_simgraph->calc_text_width_n(composition.get_str()+composition_target_start, composition_target_length);
+			g_simgraph->draw_rect_clipped(x_base_offset+x_offset+start_offset, y_offset, highlight_width, LINESPACE, SYSCOL_EDIT_BACKGROUND_SELECTED, true CLIP_NUM_DEFAULT);
+			g_simgraph->draw_text_clipped_n(x_base_offset+x_offset+start_offset, y_offset, composition.get_str()+composition_target_start, ALIGN_LEFT|DT_CLIP, SYSCOL_EDIT_TEXT_SELECTED, false, composition_target_length CLIP_NUM_DEFAULT);
 
 			x_offset += composition_width;
 		}
 
 		// display text (after composition)
-		display_proportional_clip_rgb(x_base_offset+x_offset, y_offset, text+head_cursor_pos, ALIGN_LEFT | DT_CLIP, textcol, true);
+		g_simgraph->draw_text_clipped(x_base_offset+x_offset, y_offset, text+head_cursor_pos, ALIGN_LEFT | DT_CLIP, textcol, true);
 
 		if(  cursor_active  ) {
 			// display selected text block with light grey text on charcoal bounding box
 			if(  head_cursor_pos!= tail_cursor_pos  ) {
 				const size_t start_pos = min(head_cursor_pos, tail_cursor_pos);
 				size_t end_pos = ::max(head_cursor_pos, tail_cursor_pos);
-				const scr_coord_val start_offset = proportional_string_len_width(text, start_pos);
-				const scr_coord_val highlight_width = proportional_string_len_width(text+start_pos, end_pos-start_pos);
-				display_fillbox_wh_clip_rgb(x_base_offset+start_offset, y_offset, highlight_width, LINESPACE, SYSCOL_EDIT_BACKGROUND_SELECTED, true);
-				display_text_proportional_len_clip_rgb(x_base_offset+start_offset, y_offset, text+start_pos, ALIGN_LEFT|DT_CLIP, SYSCOL_EDIT_TEXT_SELECTED, false, end_pos-start_pos);
+				const scr_coord_val start_offset = g_simgraph->calc_text_width_n(text, start_pos);
+				const scr_coord_val highlight_width = g_simgraph->calc_text_width_n(text+start_pos, end_pos-start_pos);
+				g_simgraph->draw_rect_clipped(x_base_offset+start_offset, y_offset, highlight_width, LINESPACE, SYSCOL_EDIT_BACKGROUND_SELECTED, true CLIP_NUM_DEFAULT);
+				g_simgraph->draw_text_clipped_n(x_base_offset+start_offset, y_offset, text+start_pos, ALIGN_LEFT|DT_CLIP, SYSCOL_EDIT_TEXT_SELECTED, false, end_pos-start_pos CLIP_NUM_DEFAULT);
 			}
 
 			// display blinking cursor
 			if(  cursor_visible  ) {
-				display_fillbox_wh_clip_rgb(x_base_offset+cursor_offset-1, y_offset, 1, LINESPACE, SYSCOL_CURSOR_BEAM, true);
+				g_simgraph->draw_rect_clipped(x_base_offset+cursor_offset-1, y_offset, 1, LINESPACE, SYSCOL_CURSOR_BEAM, true CLIP_NUM_DEFAULT);
 			}
 		}
 
@@ -712,7 +712,7 @@ bool gui_hidden_textinput_t::infowin_event(const event_t *ev)
 		}
 		// acting on release causes unwanted recalculations of cursor position for long strings and (cursor_offset>0)
 		// moreover, only (click) or (release) event happened inside textinput, the other one could lie outside
-		sint16 asterix_width = display_calc_proportional_string_len_width("*",1);
+		sint16 asterix_width = g_simgraph->calc_text_width_n("*", 1);
 		head_cursor_pos = 0;
 		if (  text  ) {
 			head_cursor_pos = min( strlen(text), ev->click_pos.x/asterix_width );
@@ -729,13 +729,13 @@ bool gui_hidden_textinput_t::infowin_event(const event_t *ev)
 
 void gui_hidden_textinput_t::display_with_cursor(scr_coord const offset, bool, bool const cursor_visible)
 {
-	display_img_stretch( gui_theme_t::editfield, scr_rect( pos+offset, size ) );
+	g_simgraph->draw_stretch_map( gui_theme_t::editfield, scr_rect( pos+offset, size ) );
 
 	if(  text  ) {
 		// the text will be all asterisk, thus we draw them letter by letter
 
 		// set clipping to be within textinput button
-		const clip_dimension old_clip = display_get_clip_wh();
+		const clip_dimension old_clip = g_simgraph->get_clip_rect(CLIP_NUM_DEFAULT_VALUE);
 
 		int text_clip_x = pos.x+offset.x + 1, text_clip_w = size.w - 2;
 		// something to draw?
@@ -743,7 +743,7 @@ void gui_hidden_textinput_t::display_with_cursor(scr_coord const offset, bool, b
 				return;
 		}
 		const int clip_x =  old_clip.x > text_clip_x ? old_clip.x : text_clip_x;
-		display_set_clip_wh( clip_x, old_clip.y, min(old_clip.xx, text_clip_x+text_clip_w)-clip_x, old_clip.h);
+		g_simgraph->set_clip_rect( clip_x, old_clip.y, min(old_clip.xx, text_clip_x+text_clip_w)-clip_x, old_clip.h CLIP_NUM_DEFAULT, false);
 
 		utf8 const *text_pos = (utf8 const*)text;
 		utf8 const *end = (utf8 const*)text + max;
@@ -752,16 +752,16 @@ void gui_hidden_textinput_t::display_with_cursor(scr_coord const offset, bool, b
 		do {
 			// cursor?
 			if(  cursor_visible  &&  text_pos == (utf8 const*)text + head_cursor_pos  ) {
-				display_fillbox_wh_clip_rgb( xpos, pos.y+offset.y+1+(size.h-LINESPACE)/2, 1, LINESPACE, SYSCOL_CURSOR_BEAM, true);
+				g_simgraph->draw_rect_clipped( xpos, pos.y+offset.y+1+(size.h-LINESPACE)/2, 1, LINESPACE, SYSCOL_CURSOR_BEAM, true CLIP_NUM_DEFAULT);
 			}
 			c = utf8_decoder_t::decode((utf8 const *&)text_pos);
 			if(c) {
-				xpos += display_proportional_clip_rgb( xpos, pos.y+offset.y+1+(size.h-LINESPACE)/2, "*", ALIGN_LEFT | DT_CLIP, textcol, true);
+				xpos += g_simgraph->draw_text_clipped( xpos, pos.y+offset.y+1+(size.h-LINESPACE)/2, "*", ALIGN_LEFT | DT_CLIP, textcol, true);
 			}
 		}
 		while(  text_pos < end  &&  c != UNICODE_NUL  );
 
 		// reset clipping
-		display_set_clip_wh(old_clip.x, old_clip.y, old_clip.w, old_clip.h);
+		g_simgraph->set_clip_rect(old_clip.x, old_clip.y, old_clip.w, old_clip.h CLIP_NUM_DEFAULT, false);
 	}
 }
diff --git a/src/simutrans/gui/components/gui_world_view.cc b/src/simutrans/gui/components/gui_world_view.cc
index 4f76084e3..5e6013d87 100644
--- a/src/simutrans/gui/components/gui_world_view.cc
+++ b/src/simutrans/gui/components/gui_world_view.cc
@@ -34,7 +34,7 @@ void world_view_t::invalidate_all()
 world_view_t::world_view_t(scr_size size ) :
 	prepared_rect(),
 	display_rect(),
-	raster(get_base_tile_raster_width())
+	raster(g_simgraph->get_base_tile_raster_width())
 {
 	set_size( size );
 	min_size = size;
@@ -46,7 +46,7 @@ world_view_t::world_view_t(scr_size size ) :
 world_view_t::world_view_t() :
 	prepared_rect(),
 	display_rect(),
-	raster(get_base_tile_raster_width())
+	raster(g_simgraph->get_base_tile_raster_width())
 {
 	world_view_t::view_list.append(this);
 }
@@ -76,7 +76,7 @@ bool world_view_t::infowin_event(const event_t* ev)
 
 void world_view_t::internal_draw(const scr_coord offset, obj_t const* const obj)
 {
-	display_set_image_proc(false);
+	g_simgraph->set_image_procs(false);
 
 	const koord3d here3d    = get_location();
 	const koord   here      = here3d.get_2d();
@@ -110,7 +110,7 @@ void world_view_t::internal_draw(const scr_coord offset, obj_t const* const obj)
 	const scr_coord pos = get_pos() + offset + scr_coord(1, 1);
 
 	// do not draw outside (may happen with scroll bars)
-	const clip_dimension old_clip = display_get_clip_wh();
+	const clip_dimension old_clip = g_simgraph->get_clip_rect(CLIP_NUM_DEFAULT_VALUE);
 
 	// something to draw?
 	const scr_size size = get_size() - scr_size(2, 2);
@@ -136,17 +136,17 @@ void world_view_t::internal_draw(const scr_coord offset, obj_t const* const obj)
 	// prepare clip area
 	const int clip_x = max(old_clip.x, pos.x);
 	const int clip_y = max(old_clip.y, pos.y);
-	display_set_clip_wh(clip_x, clip_y, min(old_clip.xx, pos.x + size.w) - clip_x, min(old_clip.yy, pos.y + size.h) - clip_y);
+	g_simgraph->set_clip_rect(clip_x, clip_y, min(old_clip.xx, pos.x + size.w) - clip_x, min(old_clip.yy, pos.y + size.h) - clip_y CLIP_NUM_DEFAULT, false);
 
-	mark_rect_dirty_wc(pos.x, pos.y, pos.x + size.w, pos.y + size.h);
+	g_simgraph->mark_rect_dirty_wc(pos.x, pos.y, pos.x + size.w, pos.y + size.h);
 
 	/* Not very elegant, but works: Fill everything with black for underground
 	 * mode. */
 	if(  grund_t::underground_mode  ) {
-		display_fillbox_wh_clip_rgb(pos.x, pos.y, size.w, size.h, color_idx_to_rgb(COL_BLACK), true);
+		g_simgraph->draw_rect_clipped(pos.x, pos.y, size.w, size.h, g_simgraph->palette_lookup(COL_BLACK), true CLIP_NUM_DEFAULT);
 	}
 	else {
-		display_fillbox_wh_clip_rgb(pos.x, pos.y, size.w, size.h, env_t::background_color, true);
+		g_simgraph->draw_rect_clipped(pos.x, pos.y, size.w, size.h, env_t::background_color, true CLIP_NUM_DEFAULT);
 	}
 
 	const sint16 yoff = obj && obj->is_moving() ?
@@ -230,8 +230,8 @@ void world_view_t::internal_draw(const scr_coord offset, obj_t const* const obj)
 #endif
 	}
 
-	display_set_clip_wh(old_clip.x, old_clip.y, old_clip.w, old_clip.h);
-	display_ddd_box_clip_rgb(pos.x - 1, pos.y - 1, size.w + 2, size.h + 2, color_idx_to_rgb(MN_GREY0), color_idx_to_rgb(MN_GREY4));
+	g_simgraph->set_clip_rect(old_clip.x, old_clip.y, old_clip.w, old_clip.h CLIP_NUM_DEFAULT, false);
+	g_simgraph->draw_box3d_clipped(pos.x - 1, pos.y - 1, size.w + 2, size.h + 2, g_simgraph->palette_lookup(MN_GREY0), g_simgraph->palette_lookup(MN_GREY4));
 }
 
 
diff --git a/src/simutrans/gui/convoi_filter_frame.cc b/src/simutrans/gui/convoi_filter_frame.cc
index 3f51ecd91..c7fa5959c 100644
--- a/src/simutrans/gui/convoi_filter_frame.cc
+++ b/src/simutrans/gui/convoi_filter_frame.cc
@@ -49,7 +49,7 @@ convoi_filter_frame_t::convoi_filter_frame_t(player_t *player, convoi_frame_t *m
 		filter_buttons[i].init(button_t::square_state, filter_buttons_text[i]);
 		filter_buttons[i].add_listener(this);
 		if(filter_buttons_types[i] < sub_filter) {
-			filter_buttons[i].background_color = color_idx_to_rgb(COL_WHITE);
+			filter_buttons[i].background_color = g_simgraph->palette_lookup(COL_WHITE);
 		}
 		filter_buttons[i].pressed = get_filter(filter_buttons_types[i]);
 	}
diff --git a/src/simutrans/gui/convoi_info.cc b/src/simutrans/gui/convoi_info.cc
index c14c71a22..664a35a40 100644
--- a/src/simutrans/gui/convoi_info.cc
+++ b/src/simutrans/gui/convoi_info.cc
@@ -62,7 +62,7 @@ bool convoi_info_t::route_search_in_progress=false;
 convoi_info_t::convoi_info_t(convoihandle_t cnv, bool edit_schedule) :
 	gui_frame_t(""),
 	text(&freight_info),
-	view(scr_size(max(64, get_base_tile_raster_width()), max(56, (get_base_tile_raster_width() * 7) / 8))),
+	view(scr_size(max(64, g_simgraph->get_base_tile_raster_width()), max(56, (g_simgraph->get_base_tile_raster_width() * 7) / 8))),
 	scroll_freight(&container_freight, true, true)
 {
 	is_saving_gui = false;
@@ -181,11 +181,11 @@ void convoi_info_t::init(convoihandle_t cnv)
 	container_stats.add_table(D_BUTTONS_PER_ROW,0)->set_force_equal_columns(true);
 
 	for (int cost = 0; cost<convoi_t::MAX_CONVOI_COST; cost++) {
-		uint16 curve = chart.add_curve( color_idx_to_rgb(cost_type_color[cost]), cnv->get_finance_history(), convoi_t::MAX_CONVOI_COST, cost, MAX_MONTHS, cost_type_money[cost], false, true, cost_type_money[cost]*2 );
+		uint16 curve = chart.add_curve( g_simgraph->palette_lookup(cost_type_color[cost]), cnv->get_finance_history(), convoi_t::MAX_CONVOI_COST, cost, MAX_MONTHS, cost_type_money[cost], false, true, cost_type_money[cost]*2 );
 
 		button_t *b = container_stats.new_component<button_t>();
 		b->init(button_t::box_state_automatic  | button_t::flexible, cost_type[cost]);
-		b->background_color = color_idx_to_rgb(cost_type_color[cost]);
+		b->background_color = g_simgraph->palette_lookup(cost_type_color[cost]);
 		b->pressed = false;
 
 		button_to_chart.append(b, &chart, curve);
@@ -224,12 +224,12 @@ void convoi_info_t::init(convoihandle_t cnv)
 	details = container_details.new_component<convoi_detail_t>(cnv);
 
 	// indicator bars
-	filled_bar.add_color_value(&cnv->get_loading_limit(), color_idx_to_rgb(COL_YELLOW));
-	filled_bar.add_color_value(&cnv->get_loading_level(), color_idx_to_rgb(COL_GREEN));
+	filled_bar.add_color_value(&cnv->get_loading_limit(), g_simgraph->palette_lookup(COL_YELLOW));
+	filled_bar.add_color_value(&cnv->get_loading_level(), g_simgraph->palette_lookup(COL_GREEN));
 
 	speed_bar.set_base(max_convoi_speed);
 	speed_bar.set_vertical(false);
-	speed_bar.add_color_value(&mean_convoi_speed, color_idx_to_rgb(COL_GREEN));
+	speed_bar.add_color_value(&mean_convoi_speed, g_simgraph->palette_lookup(COL_GREEN));
 
 	// we update this ourself!
 	route_bar.init(&cnv_route_index, 0);
diff --git a/src/simutrans/gui/convoy_item.h b/src/simutrans/gui/convoy_item.h
index dfaa6b7b3..88fb49b21 100644
--- a/src/simutrans/gui/convoy_item.h
+++ b/src/simutrans/gui/convoy_item.h
@@ -18,7 +18,7 @@ class convoy_scrollitem_t : public gui_scrolled_list_t::const_text_scrollitem_t
 private:
 	convoihandle_t cnv;
 public:
-	convoy_scrollitem_t( convoihandle_t c ) : gui_scrolled_list_t::const_text_scrollitem_t( NULL, color_idx_to_rgb(COL_ORANGE) ) { cnv = c; }
+	convoy_scrollitem_t( convoihandle_t c ) : gui_scrolled_list_t::const_text_scrollitem_t( NULL, g_simgraph->palette_lookup(COL_ORANGE) ) { cnv = c; }
 	PIXVAL get_color() const OVERRIDE;
 	convoihandle_t get_convoy() const { return cnv; }
 	char const* get_text() const OVERRIDE;
diff --git a/src/simutrans/gui/curiosity_edit.cc b/src/simutrans/gui/curiosity_edit.cc
index 45f19494c..e3ab1c3da 100644
--- a/src/simutrans/gui/curiosity_edit.cc
+++ b/src/simutrans/gui/curiosity_edit.cc
@@ -185,9 +185,9 @@ void curiosity_edit_frame_t::fill_list()
 		// color code for objects: BLACK: normal, YELLOW: consumer only, GREEN: source only
 		PIXVAL color;
 		switch (i->get_type()) {
-			case building_desc_t::attraction_city: color = color_idx_to_rgb(COL_DARK_BLUE+env_t::gui_player_color_dark); break;
-			case building_desc_t::attraction_land: color = color_idx_to_rgb(40 + env_t::gui_player_color_dark);          break;
-			default:                               color = SYSCOL_TEXT;                                                  break;
+			case building_desc_t::attraction_city: color = g_simgraph->palette_lookup(COL_DARK_BLUE+env_t::gui_player_color_dark); break;
+			case building_desc_t::attraction_land: color = g_simgraph->palette_lookup(40           +env_t::gui_player_color_dark); break;
+			default:                               color = SYSCOL_TEXT;                                                            break;
 		}
 		char const* const name = get_sortedby()==gui_sorting_item_t::BY_NAME_OBJECT ?  i->get_name() : translator::translate(i->get_name());
 		scl.new_component<gui_scrolled_list_t::const_text_scrollitem_t>(name, color);
diff --git a/src/simutrans/gui/curiositylist_frame.cc b/src/simutrans/gui/curiositylist_frame.cc
index 8e02f0192..f9049f959 100644
--- a/src/simutrans/gui/curiositylist_frame.cc
+++ b/src/simutrans/gui/curiositylist_frame.cc
@@ -28,7 +28,7 @@ const char* sort_text[curiositylist::SORT_MODES] = {
 class playername_const_scroll_item_t : public gui_scrolled_list_t::const_text_scrollitem_t {
 public:
 	const uint8 player_nr;
-	playername_const_scroll_item_t( player_t *pl ) : gui_scrolled_list_t::const_text_scrollitem_t( pl->get_name(), color_idx_to_rgb(pl->get_player_color1()+env_t::gui_player_color_dark) ), player_nr(pl->get_player_nr()) { }
+	playername_const_scroll_item_t( player_t *pl ) : gui_scrolled_list_t::const_text_scrollitem_t( pl->get_name(), g_simgraph->palette_lookup(pl->get_player_color1()+env_t::gui_player_color_dark) ), player_nr(pl->get_player_nr()) { }
 };
 
 curiositylist_frame_t::curiositylist_frame_t() :
diff --git a/src/simutrans/gui/curiositylist_stats.cc b/src/simutrans/gui/curiositylist_stats.cc
index 9af096ccc..7bbfc1e39 100644
--- a/src/simutrans/gui/curiositylist_stats.cc
+++ b/src/simutrans/gui/curiositylist_stats.cc
@@ -178,13 +178,13 @@ void curiositylist_stats_t::draw(scr_coord offset)
 		}
 		// now decide on color
 		if(some_crowded) {
-			indicatorfarbe = color_idx_to_rgb(all_crowded ? COL_RED : COL_ORANGE);
+			indicatorfarbe = g_simgraph->palette_lookup(all_crowded ? COL_RED : COL_ORANGE);
 		}
 		else if(pax) {
-			indicatorfarbe = color_idx_to_rgb(mail ? COL_TURQUOISE : COL_DARK_GREEN);
+			indicatorfarbe = g_simgraph->palette_lookup(mail ? COL_TURQUOISE : COL_DARK_GREEN);
 		}
 		else {
-			indicatorfarbe = color_idx_to_rgb(mail ? COL_BLUE : COL_YELLOW);
+			indicatorfarbe = g_simgraph->palette_lookup(mail ? COL_BLUE : COL_YELLOW);
 		}
 
 	indicator.set_color(indicatorfarbe);
diff --git a/src/simutrans/gui/depot_frame.cc b/src/simutrans/gui/depot_frame.cc
index ddc7644c9..48dac8586 100644
--- a/src/simutrans/gui/depot_frame.cc
+++ b/src/simutrans/gui/depot_frame.cc
@@ -240,11 +240,11 @@ void depot_frame_t::init(depot_t *dep)
 	convoi_tile_length_sb = 0;
 	new_vehicle_length_sb = 0;
 	if(  depot->get_max_convoi_length() > 1  ) { // no convoy length bar for ships or aircraft
-		sb_convoi_length.add_color_value(&convoi_tile_length_sb, color_idx_to_rgb(COL_BROWN));
-		sb_convoi_length.add_color_value(&new_vehicle_length_sb, color_idx_to_rgb(COL_DARK_GREEN));
-		sb_convoi_length.add_color_value(&convoi_length_ok_sb, color_idx_to_rgb(COL_GREEN));
-		sb_convoi_length.add_color_value(&convoi_length_slower_sb, color_idx_to_rgb(COL_ORANGE));
-		sb_convoi_length.add_color_value(&convoi_length_too_slow_sb, color_idx_to_rgb(COL_RED));
+		sb_convoi_length.add_color_value(&convoi_tile_length_sb,     g_simgraph->palette_lookup(COL_BROWN));
+		sb_convoi_length.add_color_value(&new_vehicle_length_sb,     g_simgraph->palette_lookup(COL_DARK_GREEN));
+		sb_convoi_length.add_color_value(&convoi_length_ok_sb,       g_simgraph->palette_lookup(COL_GREEN));
+		sb_convoi_length.add_color_value(&convoi_length_slower_sb,   g_simgraph->palette_lookup(COL_ORANGE));
+		sb_convoi_length.add_color_value(&convoi_length_too_slow_sb, g_simgraph->palette_lookup(COL_RED));
 		cont_convoi.add_component(&sb_convoi_length);
 	}
 	add_component(&scrolly_convoi);
@@ -391,12 +391,12 @@ void depot_frame_t::init(depot_t *dep)
 		 */
 		scr_coord placement;
 		scr_coord grid;
-		grid.x = depot->get_x_grid() * get_base_tile_raster_width() / 64 + 4;
-		grid.y = depot->get_y_grid() * get_base_tile_raster_width() / 64 + 6;
-		placement.x = depot->get_x_placement() * get_base_tile_raster_width() / 64 + 2;
-		placement.y = depot->get_y_placement() * get_base_tile_raster_width() / 64 + 2;
-		scr_coord_val grid_dx = depot->get_x_grid() * get_base_tile_raster_width() / 64 / 2;
-		scr_coord_val placement_dx = depot->get_x_grid() * get_base_tile_raster_width() / 64 / 4;
+		grid.x = depot->get_x_grid() * g_simgraph->get_base_tile_raster_width() / 64 + 4;
+		grid.y = depot->get_y_grid() * g_simgraph->get_base_tile_raster_width() / 64 + 6;
+		placement.x = depot->get_x_placement() * g_simgraph->get_base_tile_raster_width() / 64 + 2;
+		placement.y = depot->get_y_placement() * g_simgraph->get_base_tile_raster_width() / 64 + 2;
+		scr_coord_val grid_dx = depot->get_x_grid() * g_simgraph->get_base_tile_raster_width() / 64 / 2;
+		scr_coord_val placement_dx = depot->get_x_grid() * g_simgraph->get_base_tile_raster_width() / 64 / 4;
 
 		sb_convoi_length.set_width(depot->get_max_convoi_length() * (grid.x - grid_dx));
 
@@ -713,23 +713,23 @@ void depot_frame_t::update_data()
 		}
 
 		/* color bars for current convoi: */
-		convoi_pics[0]->lcolor = color_idx_to_rgb(cnv->front()->get_desc()->can_follow(NULL) ? COL_GREEN : COL_YELLOW);
+		convoi_pics[0]->lcolor = g_simgraph->palette_lookup(cnv->front()->get_desc()->can_follow(NULL) ? COL_GREEN : COL_YELLOW);
 		{
 			unsigned i;
 			for(  i = 1;  i < cnv->get_vehicle_count();  i++  ) {
-				convoi_pics[i - 1]->rcolor = color_idx_to_rgb(cnv->get_vehicle(i-1)->get_desc()->can_lead(cnv->get_vehicle(i)->get_desc()) ? COL_GREEN : COL_RED);
-				convoi_pics[i]->lcolor     = color_idx_to_rgb(cnv->get_vehicle(i)->get_desc()->can_follow(cnv->get_vehicle(i-1)->get_desc()) ? COL_GREEN : COL_RED);
+				convoi_pics[i - 1]->rcolor = g_simgraph->palette_lookup(cnv->get_vehicle(i-1)->get_desc()->can_lead(cnv->get_vehicle(i)->get_desc()) ? COL_GREEN : COL_RED);
+				convoi_pics[i]->lcolor     = g_simgraph->palette_lookup(cnv->get_vehicle(i)->get_desc()->can_follow(cnv->get_vehicle(i-1)->get_desc()) ? COL_GREEN : COL_RED);
 			}
-			convoi_pics[i - 1]->rcolor = color_idx_to_rgb(cnv->get_vehicle(i-1)->get_desc()->can_lead(NULL) ? COL_GREEN : COL_YELLOW);
+			convoi_pics[i - 1]->rcolor = g_simgraph->palette_lookup(cnv->get_vehicle(i-1)->get_desc()->can_lead(NULL) ? COL_GREEN : COL_YELLOW);
 		}
 
 		// change green into blue for vehicles that are not available
 		for(  unsigned i = 0;  i < cnv->get_vehicle_count();  i++  ) {
 			if(  !cnv->get_vehicle(i)->get_desc()->is_available(month_now)  ) {
-				if(  convoi_pics[i]->lcolor == color_idx_to_rgb(COL_GREEN)  ) {
+				if(  convoi_pics[i]->lcolor == g_simgraph->palette_lookup(COL_GREEN)  ) {
 					convoi_pics[i]->lcolor = gui_theme_t::gui_color_obsolete;
 				}
-				if(  convoi_pics[i]->rcolor == color_idx_to_rgb(COL_GREEN)  ) {
+				if(  convoi_pics[i]->rcolor == g_simgraph->palette_lookup(COL_GREEN)  ) {
 					convoi_pics[i]->rcolor = gui_theme_t::gui_color_obsolete;
 				}
 			}
@@ -741,7 +741,7 @@ void depot_frame_t::update_data()
 	for(auto const& i : vehicle_map) {
 		vehicle_desc_t const* const    info = i.key;
 		gui_image_list_t::image_data_t& img  = *i.value;
-		const PIXVAL ok_color = info->is_available(month_now) ? color_idx_to_rgb(COL_GREEN) : gui_theme_t::gui_color_obsolete;
+		const PIXVAL ok_color = info->is_available(month_now) ? g_simgraph->palette_lookup(COL_GREEN) : gui_theme_t::gui_color_obsolete;
 
 		img.count = 0;
 		img.lcolor = ok_color;
@@ -757,25 +757,25 @@ void depot_frame_t::update_data()
 
 		if(veh_action == va_insert) {
 			if(!info->can_lead(veh)  ||  (veh  &&  !veh->can_follow(info))) {
-				img.lcolor = color_idx_to_rgb(COL_RED);
-				img.rcolor = color_idx_to_rgb(COL_RED);
+				img.lcolor = g_simgraph->palette_lookup(COL_RED);
+				img.rcolor = g_simgraph->palette_lookup(COL_RED);
 			}
 			else if(!info->can_follow(NULL)) {
-				img.lcolor = color_idx_to_rgb(COL_YELLOW);
+				img.lcolor = g_simgraph->palette_lookup(COL_YELLOW);
 			}
 		}
 		else if(veh_action == va_append) {
 			if(!info->can_follow(veh)  ||  (veh  &&  !veh->can_lead(info))) {
-				img.lcolor = color_idx_to_rgb(COL_RED);
-				img.rcolor = color_idx_to_rgb(COL_RED);
+				img.lcolor = g_simgraph->palette_lookup(COL_RED);
+				img.rcolor = g_simgraph->palette_lookup(COL_RED);
 			}
 			else if(!info->can_lead(NULL)) {
-				img.rcolor = color_idx_to_rgb(COL_YELLOW);
+				img.rcolor = g_simgraph->palette_lookup(COL_YELLOW);
 			}
 		}
 		else if( veh_action == va_sell ) {
-			img.lcolor = color_idx_to_rgb(COL_RED);
-			img.rcolor = color_idx_to_rgb(COL_RED);
+			img.lcolor = g_simgraph->palette_lookup(COL_RED);
+			img.rcolor = g_simgraph->palette_lookup(COL_RED);
 		}
 	}
 
@@ -784,8 +784,8 @@ void depot_frame_t::update_data()
 		if (gui_image_list_t::image_data_t* const imgdat = vehicle_map.get(v->get_desc())) {
 			imgdat->count++;
 			if(veh_action == va_sell) {
-				imgdat->lcolor = color_idx_to_rgb(COL_GREEN);
-				imgdat->rcolor = color_idx_to_rgb(COL_GREEN);
+				imgdat->lcolor = g_simgraph->palette_lookup(COL_GREEN);
+				imgdat->rcolor = g_simgraph->palette_lookup(COL_GREEN);
 			}
 		}
 	}
@@ -1084,7 +1084,7 @@ sint64 depot_frame_t::calc_restwert(const vehicle_desc_t *veh_type)
 
 void depot_frame_t::image_from_storage_list(gui_image_list_t::image_data_t *image_data)
 {
-	if(  image_data->lcolor != color_idx_to_rgb(COL_RED)  &&  image_data->rcolor != color_idx_to_rgb(COL_RED)  ) {
+	if(  image_data->lcolor != g_simgraph->palette_lookup(COL_RED)  &&  image_data->rcolor != g_simgraph->palette_lookup(COL_RED)  ) {
 		if(  veh_action == va_sell  ) {
 			depot->call_depot_tool('s', convoihandle_t(), image_data->text );
 		}
@@ -1466,7 +1466,7 @@ void depot_frame_t::update_vehicle_info_text(scr_coord pos)
 		// cursor over a vehicle in the selection list
 		const vector_tpl<gui_image_list_t::image_data_t*>& vec = (lst == &electrics ? electrics_vec : (lst == &pas ? pas_vec : (lst == &loks ? loks_vec : waggons_vec)));
 		veh_type = vehicle_builder_t::get_info( vec[sel_index]->text );
-		if(  vec[sel_index]->lcolor == color_idx_to_rgb(COL_RED)  ||  veh_action == va_sell  ) {
+		if(  vec[sel_index]->lcolor == g_simgraph->palette_lookup(COL_RED)  ||  veh_action == va_sell  ) {
 			// don't show new_vehicle_length_sb when can't actually add the highlighted vehicle, or selling from inventory
 			new_vehicle_length_sb_force_zero = true;
 		}
diff --git a/src/simutrans/gui/display_settings.cc b/src/simutrans/gui/display_settings.cc
index bfb3048e9..8ce613e65 100644
--- a/src/simutrans/gui/display_settings.cc
+++ b/src/simutrans/gui/display_settings.cc
@@ -117,12 +117,12 @@ gui_settings_t::gui_settings_t()
 	base_icon_height = 32;
 	if (tool_t::general_tool[TOOL_QUERY]->get_icon(NULL) != IMG_EMPTY)
 	{
-		scr_coord_val dummy;
-		display_get_base_image_offset(tool_t::general_tool[TOOL_QUERY]->get_icon(NULL), &dummy, &dummy, &dummy, &base_icon_height);
+		scr_rect r = g_simgraph->get_base_image_offset(tool_t::general_tool[TOOL_QUERY]->get_icon(NULL));
+		base_icon_height = r.h;
 	}
 	// find current zoom factor
 	for (icon_zoom = 0; icon_zoom <= MAX_ZOOM_FACTOR; icon_zoom++) {
-		if (env_t::iconsize.h >= (base_icon_height * zoom_num[icon_zoom]) / zoom_den[icon_zoom]) {
+		if (env_t::iconsize.h >= (base_icon_height * g_simgraph->zoom_num[icon_zoom]) / g_simgraph->zoom_den[icon_zoom]) {
 			// since we go from large size
 			break;
 		}
@@ -202,7 +202,7 @@ void gui_settings_t::draw(scr_coord offset)
 	uint32 loops = world()->get_realFPS();
 	PIXVAL color = SYSCOL_TEXT_HIGHLIGHT;
 	if(  loops < (target_fps*16*3)/4  ) {
-		color = color_idx_to_rgb(( loops <= target_fps*16/2 ) ? COL_RED : COL_YELLOW);
+		color = g_simgraph->palette_lookup(( loops <= target_fps*16/2 ) ? COL_RED : COL_YELLOW);
 	}
 	fps_value_label.set_color(color);
 	fps_value_label.buf().printf(" %d fps", loops/16 );
@@ -217,7 +217,7 @@ void gui_settings_t::draw(scr_coord offset)
 	loops = world()->get_simloops();
 	color = SYSCOL_TEXT_HIGHLIGHT;
 	if(  loops <= 30  ) {
-		color = color_idx_to_rgb((loops<=20) ? COL_RED : COL_YELLOW);
+		color = g_simgraph->palette_lookup((loops<=20) ? COL_RED : COL_YELLOW);
 	}
 	simloops_value_label.set_color(color);
 	simloops_value_label.buf().printf(" %d%c%d", loops/10, get_fraction_sep(), loops%10 );
@@ -259,7 +259,7 @@ bool gui_settings_t::action_triggered(gui_action_creator_t *comp, value_t v)
 	return true;
 
 icon_resize:
-	scr_coord_val new_size = (zoom_num[icon_zoom] * base_icon_height) / zoom_den[icon_zoom];
+	scr_coord_val new_size = (g_simgraph->zoom_num[icon_zoom] * base_icon_height) / g_simgraph->zoom_den[icon_zoom];
 	env_t::iconsize.h = env_t::iconsize.w = new_size;
 
 	// reload windows to update
diff --git a/src/simutrans/gui/enlarge_map_frame.cc b/src/simutrans/gui/enlarge_map_frame.cc
index 9b3471b6c..c2eb458e2 100644
--- a/src/simutrans/gui/enlarge_map_frame.cc
+++ b/src/simutrans/gui/enlarge_map_frame.cc
@@ -195,7 +195,7 @@ void enlarge_map_frame_t::update_preview()
 			if(  pos.x<=old_x  &&  pos.y<=old_y  ){
 				if(  i==(old_x/mx)  ||  j==(old_y/my)  ){
 					// border
-					color = color_idx_to_rgb(COL_WHITE);
+					color = g_simgraph->palette_lookup(COL_WHITE);
 				}
 				else {
 					const sint16 height = welt->lookup_hgt( pos );
@@ -212,7 +212,7 @@ void enlarge_map_frame_t::update_preview()
 	}
 	for(  uint j=0;  j<map.get_height();  j++  ) {
 		for(  uint i=(j<pre_y ? pre_x : 0);  i<map.get_width();   i++  ) {
-			map.at(i,j) = color_idx_to_rgb(COL_GREY1);
+			map.at(i,j) = g_simgraph->palette_lookup(COL_GREY1);
 		}
 	}
 	map_preview.set_map_data(&map);
diff --git a/src/simutrans/gui/fabrik_info.cc b/src/simutrans/gui/fabrik_info.cc
index 47e9106dc..ed03602c8 100644
--- a/src/simutrans/gui/fabrik_info.cc
+++ b/src/simutrans/gui/fabrik_info.cc
@@ -76,7 +76,7 @@ fabrik_info_t::fabrik_info_t(fabrik_t* fab_, const gebaeude_t* gb) :
 	gui_frame_t(""),
 	fab(fab_),
 	chart(NULL),
-	view(scr_size( max(64, get_base_tile_raster_width()), max(56, (get_base_tile_raster_width() * 7) / 8))),
+	view(scr_size( max(64, g_simgraph->get_base_tile_raster_width()), max(56, (g_simgraph->get_base_tile_raster_width() * 7) / 8))),
 	prod(&prod_buf),
 	txt(&info_buf),
 	scroll_info(&container_info)
@@ -246,7 +246,7 @@ void fabrik_info_t::draw(scr_coord pos, scr_size size)
 	boost_passenger.set_transparent(fab->get_prodfactor_pax()>0 ? 0 : TRANSPARENT50_FLAG | OUTLINE_FLAG | SYSCOL_IMAGE_TRANSPARENCY);
 	boost_mail.set_transparent(fab->get_prodfactor_mail()>0 ? 0 : TRANSPARENT50_FLAG | OUTLINE_FLAG | SYSCOL_IMAGE_TRANSPARENCY);
 
-	indicator_color.set_color( color_idx_to_rgb(fabrik_t::status_to_color[fab->get_status()]) );
+	indicator_color.set_color( g_simgraph->palette_lookup(fabrik_t::status_to_color[fab->get_status()]) );
 
 	chart.update();
 
diff --git a/src/simutrans/gui/factory_chart.cc b/src/simutrans/gui/factory_chart.cc
index 81da9705e..632fa695f 100644
--- a/src/simutrans/gui/factory_chart.cc
+++ b/src/simutrans/gui/factory_chart.cc
@@ -176,11 +176,11 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 			for (uint32 g = 0; g < input_count; ++g) {
 				goods_cont.new_component<gui_label_t>(input[g].get_typ()->get_name());
 				for (int s = 0; s < MAX_FAB_GOODS_STAT; ++s) {
-					uint16 curve = goods_chart.add_curve(color_idx_to_rgb(goods_color[count % MAX_GOODS_COLOR] + (s * 3) / 2), input[g].get_stats(), MAX_FAB_GOODS_STAT, s, MAX_MONTH, false, false, true, 0, goods_convert[s]);
+					uint16 curve = goods_chart.add_curve(g_simgraph->palette_lookup(goods_color[count % MAX_GOODS_COLOR] + (s * 3) / 2), input[g].get_stats(), MAX_FAB_GOODS_STAT, s, MAX_MONTH, false, false, true, 0, goods_convert[s]);
 
 					button_t* b = goods_cont.new_component<button_t>();
 					b->init(button_t::box_state_automatic | button_t::flexible, input_type[s]);
-					b->background_color = color_idx_to_rgb(goods_color[count % MAX_GOODS_COLOR] + (s * 3) / 2);
+					b->background_color = g_simgraph->palette_lookup(goods_color[count % MAX_GOODS_COLOR] + (s * 3) / 2);
 					b->pressed = false;
 					button_to_chart.append(b, &goods_chart, curve);
 
@@ -201,11 +201,11 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 			for (uint32 g = 0; g < output_count; ++g) {
 				goods_cont.new_component<gui_label_t>(output[g].get_typ()->get_name());
 				for (int s = 0; s < 3; ++s) {
-					uint16 curve = goods_chart.add_curve(color_idx_to_rgb(goods_color[count % MAX_GOODS_COLOR] + s * 2), output[g].get_stats(), MAX_FAB_GOODS_STAT, s, MAX_MONTH, false, false, true, 0, goods_convert[s]);
+					uint16 curve = goods_chart.add_curve(g_simgraph->palette_lookup(goods_color[count % MAX_GOODS_COLOR] + s * 2), output[g].get_stats(), MAX_FAB_GOODS_STAT, s, MAX_MONTH, false, false, true, 0, goods_convert[s]);
 
 					button_t* b = goods_cont.new_component<button_t>();
 					b->init(button_t::box_state_automatic | button_t::flexible, output_type[s]);
-					b->background_color = color_idx_to_rgb(goods_color[count % MAX_GOODS_COLOR] + s * 2);
+					b->background_color = g_simgraph->palette_lookup(goods_color[count % MAX_GOODS_COLOR] + s * 2);
 					b->pressed = false;
 					button_to_chart.append(b, &goods_chart, curve);
 				}
@@ -214,7 +214,7 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 		}
 		goods_cont.new_component<gui_empty_t>();
 		scr_size contsz = goods_cont.get_min_size();
-		if (contsz.w > display_get_width()) {
+		if (contsz.w > g_simgraph->get_screen_size().w) {
 			tab_panel.add_tab(&goods_pane, translator::translate("Goods"));
 		}
 		else {
@@ -241,7 +241,7 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 			else if (prod_cell_button[cell] < MAX_FAB_STAT) {
 				uint8 s = prod_cell_button[cell];
 				// add curve
-				uint16 curve = prod_chart.add_curve( color_idx_to_rgb(prod_color[s]), factory->get_stats(), MAX_FAB_STAT, s, MAX_MONTH, (2<=s  &&  s<=4) ? gui_chart_t::PERCENT : gui_chart_t::STANDARD, false, true, 0, prod_convert[s] );
+				uint16 curve = prod_chart.add_curve( g_simgraph->palette_lookup(prod_color[s]), factory->get_stats(), MAX_FAB_STAT, s, MAX_MONTH, (2<=s  &&  s<=4) ? gui_chart_t::PERCENT : gui_chart_t::STANDARD, false, true, 0, prod_convert[s] );
 				// only show buttons, if the is something to do ...
 				if(
 					(s==FAB_BOOST_ELECTRIC  &&  (factory->get_desc()->is_electricity_producer()  ||  factory->get_desc()->get_electric_boost()==0))  ||
@@ -254,7 +254,7 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 				// add button
 				button_t *b = prod_cont.new_component<button_t>();
 				b->init(button_t::box_state_automatic | button_t::flexible, prod_type[s]);
-				b->background_color = color_idx_to_rgb(prod_color[s]);
+				b->background_color = g_simgraph->palette_lookup(prod_color[s]);
 				b->pressed = false;
 				button_to_chart.append(b, &prod_chart, curve);
 			}
@@ -262,14 +262,14 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 			else if (prod_cell_ref[cell] < MAX_FAB_REF_LINE) {
 				uint8 r = prod_cell_ref[cell];
 				// add curve
-				uint16 curve = prod_chart.add_curve( color_idx_to_rgb(ref_color[r]), prod_ref_line_data + r, 0, 0, MAX_MONTH, r<3 ? gui_chart_t::PERCENT : gui_chart_t::STANDARD, false, true, 0, ref_convert[r] );
+				uint16 curve = prod_chart.add_curve( g_simgraph->palette_lookup(ref_color[r]), prod_ref_line_data + r, 0, 0, MAX_MONTH, r<3 ? gui_chart_t::PERCENT : gui_chart_t::STANDARD, false, true, 0, ref_convert[r] );
 				if(
 					(r==FAB_REF_MAX_BOOST_ELECTRIC  &&  (factory->get_desc()->is_electricity_producer()  ||  factory->get_desc()->get_electric_boost()==0))  ||
-					(r==FAB_REF_MAX_BOOST_PAX  &&  factory->get_desc()->get_pax_boost()==0)  ||
-					(r==FAB_REF_MAX_BOOST_MAIL  &&  factory->get_desc()->get_mail_boost()==0)  ||
-					(r==FAB_REF_DEMAND_ELECTRIC  &&  (factory->get_desc()->is_electricity_producer()  ||  factory->get_desc()->get_electric_demand()==0))  ||
-					(r==FAB_REF_DEMAND_PAX  &&  factory->get_desc()->get_pax_demand()==0)  ||
-					(r==FAB_REF_DEMAND_MAIL  &&  factory->get_desc()->get_mail_demand()==0)
+					(r==FAB_REF_MAX_BOOST_PAX       &&   factory->get_desc()->get_pax_boost()==0)  ||
+					(r==FAB_REF_MAX_BOOST_MAIL      &&   factory->get_desc()->get_mail_boost()==0)  ||
+					(r==FAB_REF_DEMAND_ELECTRIC     &&  (factory->get_desc()->is_electricity_producer()  ||  factory->get_desc()->get_electric_demand()==0))  ||
+					(r==FAB_REF_DEMAND_PAX          &&   factory->get_desc()->get_pax_demand()==0)  ||
+					(r==FAB_REF_DEMAND_MAIL         &&   factory->get_desc()->get_mail_demand()==0)
 				) {
 					prod_cont.new_component<gui_empty_t>();
 					continue;
@@ -277,7 +277,7 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 				// add button
 				button_t *b = prod_cont.new_component<button_t>();
 				b->init(button_t::box_state_automatic | button_t::flexible, ref_type[r]);
-				b->background_color = color_idx_to_rgb(ref_color[r]);
+				b->background_color = g_simgraph->palette_lookup(ref_color[r]);
 				b->pressed = false;
 				button_to_chart.append(b, &prod_chart, curve);
 			}
@@ -289,7 +289,7 @@ void factory_chart_t::set_factory(const fabrik_t *_factory)
 	prod_cont.end_table();
 	prod_cont.new_component<gui_empty_t>();
 	scr_size sz = prod_cont.get_min_size();
-	if (sz.w > display_get_width()) {
+	if (sz.w > g_simgraph->get_screen_size().w) {
 		tab_panel.add_tab(&prod_pane, translator::translate("Production/Boost"));
 	}
 	else {
diff --git a/src/simutrans/gui/factory_edit.cc b/src/simutrans/gui/factory_edit.cc
index f83fe1367..c32195d95 100644
--- a/src/simutrans/gui/factory_edit.cc
+++ b/src/simutrans/gui/factory_edit.cc
@@ -200,8 +200,8 @@ void factory_edit_frame_t::fill_list()
 	scl.set_selection(-1);
 	for(factory_desc_t const* const i : factory_list) {
 		PIXVAL const color =
-			i->is_consumer_only() ? color_idx_to_rgb(COL_DARK_BLUE + env_t::gui_player_color_dark) :
-			i->is_producer_only() ? color_idx_to_rgb(40 + env_t::gui_player_color_dark)            :
+			i->is_consumer_only() ? g_simgraph->palette_lookup(COL_DARK_BLUE + env_t::gui_player_color_dark) :
+			i->is_producer_only() ? g_simgraph->palette_lookup(40            + env_t::gui_player_color_dark)            :
 			SYSCOL_TEXT;
 		char const* const name = get_sortedby()==gui_sorting_item_t::BY_NAME_OBJECT ?  i->get_name() : translator::translate(i->get_name());
 		scl.new_component<gui_scrolled_list_t::const_text_scrollitem_t>(name, color);
diff --git a/src/simutrans/gui/factorylist_frame.cc b/src/simutrans/gui/factorylist_frame.cc
index 732a4abaa..d8f40576b 100644
--- a/src/simutrans/gui/factorylist_frame.cc
+++ b/src/simutrans/gui/factorylist_frame.cc
@@ -26,7 +26,10 @@ const char *factorylist_frame_t::sort_text[factorylist::SORT_MODES] = {
 class playername_const_scroll_item_t : public gui_scrolled_list_t::const_text_scrollitem_t {
 public:
 	const uint8 player_nr;
-	playername_const_scroll_item_t( player_t *pl ) : gui_scrolled_list_t::const_text_scrollitem_t( pl->get_name(), color_idx_to_rgb(pl->get_player_color1()+env_t::gui_player_color_dark) ), player_nr(pl->get_player_nr()) { }
+	playername_const_scroll_item_t( player_t *pl )
+		: gui_scrolled_list_t::const_text_scrollitem_t( pl->get_name(), g_simgraph->palette_lookup(pl->get_player_color1()+env_t::gui_player_color_dark) )
+		, player_nr(pl->get_player_nr())
+	{ }
 };
 
 factorylist_frame_t::factorylist_frame_t() :
diff --git a/src/simutrans/gui/factorylist_stats.cc b/src/simutrans/gui/factorylist_stats.cc
index 7e469a126..c628ed429 100644
--- a/src/simutrans/gui/factorylist_stats.cc
+++ b/src/simutrans/gui/factorylist_stats.cc
@@ -117,7 +117,7 @@ void factorylist_stats_t::draw(scr_coord pos)
 	boost_electric.set_transparent(fab->get_prodfactor_electric()>0 ? 0 : TRANSPARENT50_FLAG | OUTLINE_FLAG | SYSCOL_IMAGE_TRANSPARENCY);
 	boost_passenger.set_transparent(fab->get_prodfactor_pax()>0 ? 0 : TRANSPARENT50_FLAG | OUTLINE_FLAG | SYSCOL_IMAGE_TRANSPARENCY);
 	boost_mail.set_transparent(fab->get_prodfactor_mail()>0 ? 0 : TRANSPARENT50_FLAG | OUTLINE_FLAG | SYSCOL_IMAGE_TRANSPARENCY);
-	indicator.set_color( color_idx_to_rgb(fabrik_t::status_to_color[fab->get_status()]) );
+	indicator.set_color( g_simgraph->palette_lookup(fabrik_t::status_to_color[fab->get_status()]) );
 
 	gui_aligned_container_t::draw(pos);
 }
diff --git a/src/simutrans/gui/ground_info.cc b/src/simutrans/gui/ground_info.cc
index 97465b4a8..721e6c703 100644
--- a/src/simutrans/gui/ground_info.cc
+++ b/src/simutrans/gui/ground_info.cc
@@ -13,11 +13,11 @@
 grund_info_t::grund_info_t(const grund_t* _gr) :
 	base_infowin_t("",NULL),
 	gr(_gr),
-	lview(_gr->get_pos(), scr_size(max(64, get_base_tile_raster_width()), max(56, (get_base_tile_raster_width() * 7) / 8)))
+	lview(_gr->get_pos(), scr_size(max(64, g_simgraph->get_base_tile_raster_width()), max(56, (g_simgraph->get_base_tile_raster_width() * 7) / 8)))
 {
 	fill_buffer();
 	set_embedded(&lview);
-	textarea.set_width(textarea.get_size().w + get_base_tile_raster_width() - 64);
+	textarea.set_width(textarea.get_size().w + g_simgraph->get_base_tile_raster_width() - 64);
 	recalc_size();
 }
 
diff --git a/src/simutrans/gui/gui_frame.cc b/src/simutrans/gui/gui_frame.cc
index 680dd1e42..841620169 100644
--- a/src/simutrans/gui/gui_frame.cc
+++ b/src/simutrans/gui/gui_frame.cc
@@ -48,7 +48,7 @@ void gui_frame_t::set_windowsize(scr_size new_windowsize)
 	if(  new_windowsize != windowsize  ) {
 		// mark old size dirty
 		scr_coord const& pos = win_get_pos(this);
-		mark_rect_dirty_wc( pos.x, pos.y, pos.x+windowsize.w, pos.y+windowsize.h );
+		g_simgraph->mark_rect_dirty_wc( pos.x, pos.y, pos.x+windowsize.w, pos.y+windowsize.h );
 
 		// minimum size //25-may-02  markus weber  added
 		new_windowsize.clip_lefttop(min_windowsize);
@@ -96,7 +96,7 @@ void gui_frame_t::reset_min_windowsize()
  */
 FLAGGED_PIXVAL gui_frame_t::get_titlecolor() const
 {
-	return owner ? PLAYER_FLAG|color_idx_to_rgb(owner->get_player_color1()+env_t::gui_player_color_dark) : env_t::default_window_title_color;
+	return owner ? (PLAYER_FLAG | g_simgraph->palette_lookup(owner->get_player_color1()+env_t::gui_player_color_dark)) : env_t::default_window_title_color;
 }
 
 
@@ -167,16 +167,16 @@ void gui_frame_t::draw(scr_coord pos, scr_size size)
 	scr_size titlebar_size(0, ( has_title()*D_TITLEBAR_HEIGHT ));
 	// draw background
 	if(  opaque  ) {
-		display_img_stretch( gui_theme_t::windowback, scr_rect( pos + titlebar_size, size - titlebar_size ) );
+		g_simgraph->draw_stretch_map( gui_theme_t::windowback, scr_rect( pos + titlebar_size, size - titlebar_size ) );
 		if(  dirty  ) {
-			mark_rect_dirty_wc(pos.x, pos.y, pos.x + size.w, pos.y + titlebar_size.h );
+			g_simgraph->mark_rect_dirty_wc(pos.x, pos.y, pos.x + size.w, pos.y + titlebar_size.h );
 		}
 	}
 	else {
 		if(  dirty  ) {
-			mark_rect_dirty_wc(pos.x, pos.y, pos.x + size.w, pos.y + size.h + titlebar_size.h );
+			g_simgraph->mark_rect_dirty_wc(pos.x, pos.y, pos.x + size.w, pos.y + size.h + titlebar_size.h );
 		}
-		display_blend_wh_rgb( pos.x+1, pos.y+titlebar_size.h, size.w-2, size.h-titlebar_size.h, color_transparent, percent_transparent );
+		g_simgraph->tint_rect( pos.x+1, pos.y+titlebar_size.h, size.w-2, size.h-titlebar_size.h, color_transparent, percent_transparent );
 	}
 	dirty = false;
 
@@ -186,8 +186,8 @@ void gui_frame_t::draw(scr_coord pos, scr_size size)
 
 	// for shadows of the windows
 	if(  gui_theme_t::gui_drop_shadows  ) {
-		display_blend_wh_rgb( pos.x+size.w, pos.y+1, 2, size.h, color_idx_to_rgb(COL_BLACK), 50 );
-		display_blend_wh_rgb( pos.x+1, pos.y+size.h, size.w, 2, color_idx_to_rgb(COL_BLACK), 50 );
+		g_simgraph->tint_rect( pos.x+size.w, pos.y+1,      2, size.h, g_simgraph->palette_lookup(COL_BLACK), 50 );
+		g_simgraph->tint_rect( pos.x+1,      pos.y+size.h, size.w, 2, g_simgraph->palette_lookup(COL_BLACK), 50 );
 	}
 }
 
diff --git a/src/simutrans/gui/gui_theme.cc b/src/simutrans/gui/gui_theme.cc
index 37a02380c..9e516f57a 100644
--- a/src/simutrans/gui/gui_theme.cc
+++ b/src/simutrans/gui/gui_theme.cc
@@ -140,57 +140,57 @@ void gui_theme_t::init_gui_defaults()
 {
 	skinverwaltung_t::restore_all_skins();
 
-	gui_color_text                         = color_idx_to_rgb(COL_BLACK);
-	gui_color_text_highlight               = color_idx_to_rgb(COL_WHITE);
-	gui_color_text_shadow                  = color_idx_to_rgb(COL_BLACK);
-	gui_color_text_title                   = color_idx_to_rgb(207);
-	gui_color_text_strong                  = color_idx_to_rgb(COL_RED);
-	gui_color_text_minus                   = color_idx_to_rgb(COL_RED);
-	gui_color_text_plus                    = color_idx_to_rgb(COL_BLACK);
-	gui_color_text_unused                  = color_idx_to_rgb(COL_YELLOW);
-
-	gui_color_edit_text                    = color_idx_to_rgb(COL_WHITE);
-	gui_color_edit_text_selected           = color_idx_to_rgb(COL_GREY5);
-	gui_color_edit_text_disabled           = color_idx_to_rgb(COL_GREY3);
-	gui_color_edit_background_selected     = color_idx_to_rgb(COL_GREY2);
-	gui_color_edit_beam                    = color_idx_to_rgb(COL_WHITE);
-
-	gui_color_chart_background             = color_idx_to_rgb(MN_GREY1);
-	gui_color_chart_lines_zero             = color_idx_to_rgb(MN_GREY4);
-	gui_color_chart_lines_odd              = color_idx_to_rgb(COL_WHITE);
-	gui_color_chart_lines_even             = color_idx_to_rgb(MN_GREY0);
-
-	gui_color_list_text_selected_focus     = color_idx_to_rgb(COL_WHITE);
-	gui_color_list_text_selected_nofocus   = color_idx_to_rgb(MN_GREY3);
-	gui_color_list_background_selected_f   = color_idx_to_rgb(COL_BLUE);
-	gui_color_list_background_selected_nf  = color_idx_to_rgb(COL_LIGHT_BLUE);
-
-	gui_color_button_text                  = color_idx_to_rgb(COL_BLACK);
-	gui_color_button_text_disabled         = color_idx_to_rgb(MN_GREY0);
-	gui_color_button_text_selected         = color_idx_to_rgb(COL_BLACK);
-
-	gui_color_colored_button_text          = color_idx_to_rgb(COL_BLACK);
-	gui_color_colored_button_text_selected = color_idx_to_rgb(COL_WHITE);
-	gui_color_checkbox_text                = color_idx_to_rgb(COL_BLACK);
-	gui_color_checkbox_text_disabled       = color_idx_to_rgb(MN_GREY0);
-	gui_color_ticker_background            = color_idx_to_rgb(MN_GREY2);
-	gui_color_ticker_divider               = color_idx_to_rgb(COL_BLACK);
-	gui_color_statusbar_text               = color_idx_to_rgb(COL_BLACK);
-	gui_color_statusbar_background         = color_idx_to_rgb(MN_GREY1);
-	gui_color_statusbar_divider            = color_idx_to_rgb(MN_GREY4);
-
-	gui_highlight_color                    = color_idx_to_rgb(MN_GREY4);
-	gui_shadow_color                       = color_idx_to_rgb(MN_GREY0);
-
-	gui_color_loadingbar_inner             = color_idx_to_rgb(COL_GREY5);
-	gui_color_loadingbar_progress          = color_idx_to_rgb(COL_BLUE);
-
-	gui_color_obsolete                     = color_idx_to_rgb(COL_BLUE);
-	gui_color_empty                        = color_idx_to_rgb(COL_WHITE);
-
-	gui_color_image_transparency          = color_idx_to_rgb(COL_BLACK);
-
-	gui_color_object_highlight            = color_idx_to_rgb(COL_RED);
+	gui_color_text                         = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_text_highlight               = g_simgraph->palette_lookup(COL_WHITE);
+	gui_color_text_shadow                  = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_text_title                   = g_simgraph->palette_lookup(207);
+	gui_color_text_strong                  = g_simgraph->palette_lookup(COL_RED);
+	gui_color_text_minus                   = g_simgraph->palette_lookup(COL_RED);
+	gui_color_text_plus                    = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_text_unused                  = g_simgraph->palette_lookup(COL_YELLOW);
+
+	gui_color_edit_text                    = g_simgraph->palette_lookup(COL_WHITE);
+	gui_color_edit_text_selected           = g_simgraph->palette_lookup(COL_GREY5);
+	gui_color_edit_text_disabled           = g_simgraph->palette_lookup(COL_GREY3);
+	gui_color_edit_background_selected     = g_simgraph->palette_lookup(COL_GREY2);
+	gui_color_edit_beam                    = g_simgraph->palette_lookup(COL_WHITE);
+
+	gui_color_chart_background             = g_simgraph->palette_lookup(MN_GREY1);
+	gui_color_chart_lines_zero             = g_simgraph->palette_lookup(MN_GREY4);
+	gui_color_chart_lines_odd              = g_simgraph->palette_lookup(COL_WHITE);
+	gui_color_chart_lines_even             = g_simgraph->palette_lookup(MN_GREY0);
+
+	gui_color_list_text_selected_focus     = g_simgraph->palette_lookup(COL_WHITE);
+	gui_color_list_text_selected_nofocus   = g_simgraph->palette_lookup(MN_GREY3);
+	gui_color_list_background_selected_f   = g_simgraph->palette_lookup(COL_BLUE);
+	gui_color_list_background_selected_nf  = g_simgraph->palette_lookup(COL_LIGHT_BLUE);
+
+	gui_color_button_text                  = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_button_text_disabled         = g_simgraph->palette_lookup(MN_GREY0);
+	gui_color_button_text_selected         = g_simgraph->palette_lookup(COL_BLACK);
+
+	gui_color_colored_button_text          = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_colored_button_text_selected = g_simgraph->palette_lookup(COL_WHITE);
+	gui_color_checkbox_text                = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_checkbox_text_disabled       = g_simgraph->palette_lookup(MN_GREY0);
+	gui_color_ticker_background            = g_simgraph->palette_lookup(MN_GREY2);
+	gui_color_ticker_divider               = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_statusbar_text               = g_simgraph->palette_lookup(COL_BLACK);
+	gui_color_statusbar_background         = g_simgraph->palette_lookup(MN_GREY1);
+	gui_color_statusbar_divider            = g_simgraph->palette_lookup(MN_GREY4);
+
+	gui_highlight_color                    = g_simgraph->palette_lookup(MN_GREY4);
+	gui_shadow_color                       = g_simgraph->palette_lookup(MN_GREY0);
+
+	gui_color_loadingbar_inner             = g_simgraph->palette_lookup(COL_GREY5);
+	gui_color_loadingbar_progress          = g_simgraph->palette_lookup(COL_BLUE);
+
+	gui_color_obsolete                     = g_simgraph->palette_lookup(COL_BLUE);
+	gui_color_empty                        = g_simgraph->palette_lookup(COL_WHITE);
+
+	gui_color_image_transparency           = g_simgraph->palette_lookup(COL_BLACK);
+
+	gui_color_object_highlight             = g_simgraph->palette_lookup(COL_RED);
 
 	env_t::gui_player_color_bright = 4;
 	env_t::gui_player_color_dark   = 1;
@@ -214,7 +214,7 @@ void gui_theme_t::init_gui_defaults()
 	gui_indicator_size           = scr_size(20,4);
 	gui_focus_offset             = scr_coord(1,1);
 
-	gui_buttons_per_row          = max(2, min(4, display_get_width() / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
+	gui_buttons_per_row          = max(2, min(4, g_simgraph->get_screen_size().w / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
 
 	gui_titlebar_height  = 16;
 	gui_frame_left       = 10;
@@ -229,7 +229,7 @@ void gui_theme_t::init_gui_defaults()
 
 	gui_drop_shadows     = false;
 
-	gui_color_chat_window_network_transparency = color_idx_to_rgb(COL_WHITE);
+	gui_color_chat_window_network_transparency = g_simgraph->palette_lookup(COL_WHITE);
 }
 
 
@@ -414,7 +414,7 @@ bool gui_theme_t::themes_init(const char *file_name, bool init_fonts, bool init_
 	// reload current font if requested size differs and we are allowed to do so
 	uint8 new_size = contents.get_int("font_size", env_t::fontsize );
 	if(  init_fonts  &&  new_size!=0  &&  LINESPACE!=new_size  ) {
-		if(  display_load_font( env_t::fontname.c_str() )  ) {
+		if(  g_simgraph->load_font(env_t::fontname.c_str(), false)  ) {
 			env_t::fontsize = new_size;
 		}
 	}
@@ -583,13 +583,13 @@ gui_theme_t::gui_color_object_highlight                 = (PIXVAL)contents.get_c
 	// default iconsize scaling (must be read before the images)
 	env_t::iconscaling = contents.get_int("icon_scaling", env_t::iconscaling);
 	if (skinverwaltung_t::tool_icons_general) {
-		env_t::iconsize = display_get_best_matching_size(skinverwaltung_t::tool_icons_general->get_image_id(0), env_t::iconscaling);
+		env_t::iconsize = g_simgraph->get_best_matching_size(skinverwaltung_t::tool_icons_general->get_image_id(0), env_t::iconscaling);
 	}
 
 	env_t::chat_window_transparency =   100 - contents.get_int("gui_chat_window_network_transparency", 100 - env_t::chat_window_transparency);
 
 	// needs to be changed after resize events too
-	gui_buttons_per_row = max(2, min(4, display_get_width() / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
+	gui_buttons_per_row = max(2, min(4, g_simgraph->get_screen_size().w / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
 
 	if(  toolbar_last_used_t::last_used_tools  &&  init_tools  ) {
 		// only re-init if already inited
diff --git a/src/simutrans/gui/gui_theme.h b/src/simutrans/gui/gui_theme.h
index a2822c9f7..0a2434de9 100644
--- a/src/simutrans/gui/gui_theme.h
+++ b/src/simutrans/gui/gui_theme.h
@@ -130,7 +130,7 @@ class image_t;
 
 // The width of a typical dialogue (either list/covoi/factory) and initial width when it makes sense
 #define D_DEFAULT_WIDTH (D_MARGINS_X + D_BUTTONS_PER_ROW*D_BUTTON_WIDTH + (D_BUTTONS_PER_ROW-1)*D_H_SPACE)
-#define D_DEFAULT_HEIGHT (max(56, get_base_tile_raster_width() * 7 / 8) + 208 + D_SCROLLBAR_HEIGHT)
+#define D_DEFAULT_HEIGHT (max(56, g_simgraph->get_base_tile_raster_width() * 7 / 8) + 208 + D_SCROLLBAR_HEIGHT)
 
 // Max Kielland: align helper, returns the offset to apply to N1 for a center alignment around N2
 #define D_GET_CENTER_ALIGN_OFFSET(N1,N2) ((N2-N1)>>1)
diff --git a/src/simutrans/gui/halt_info.cc b/src/simutrans/gui/halt_info.cc
index aa41379b4..e828135af 100644
--- a/src/simutrans/gui/halt_info.cc
+++ b/src/simutrans/gui/halt_info.cc
@@ -281,7 +281,7 @@ halt_info_t::halt_info_t(halthandle_t halt) :
 		scrolly_freight(&container_freight, true, true),
 		scrolly_departure(departure_board, true, true),
 		scrolly_details(halt_detail, true, true),
-		view(koord3d::invalid, scr_size(max(64, get_base_tile_raster_width()), max(56, get_base_tile_raster_width() * 7 / 8)))
+		view(koord3d::invalid, scr_size(max(64, g_simgraph->get_base_tile_raster_width()), max(56, g_simgraph->get_base_tile_raster_width() * 7 / 8)))
 {
 	if (halt.is_bound()) {
 		init(halt);
@@ -401,11 +401,11 @@ void halt_info_t::init(halthandle_t halt)
 	chart.set_background(SYSCOL_CHART_BACKGROUND);
 	container_chart.add_component(&chart, D_BUTTONS_PER_ROW);
 	for (int cost = 0; cost<MAX_HALT_COST; cost++) {
-		uint16 curve = chart.add_curve(color_idx_to_rgb(cost_type_color[cost]), halt->get_finance_history(), MAX_HALT_COST, index_of_haltinfo[cost], MAX_MONTHS, 0, false, true, 0);
+		uint16 curve = chart.add_curve(g_simgraph->palette_lookup(cost_type_color[cost]), halt->get_finance_history(), MAX_HALT_COST, index_of_haltinfo[cost], MAX_MONTHS, 0, false, true, 0);
 
 		button_t *b = container_chart.new_component<button_t>();
 		b->init(button_t::box_state_automatic | button_t::flexible, cost_type[cost]);
-		b->background_color = color_idx_to_rgb(cost_type_color[cost]);
+		b->background_color = g_simgraph->palette_lookup(cost_type_color[cost]);
 		b->pressed = false;
 		button_to_chart.append(b, &chart, curve);
 	}
@@ -467,13 +467,13 @@ void halt_info_t::update_components()
 		lb_happy[2].update();
 	}
 	else {
-		if(  has_character( 0x263A )  ) {
+		if(  g_simgraph->font_has_character( 0x263A )  ) {
 			utf8 happy[4], unhappy[4];
 			happy[ utf16_to_utf8( 0x263A, happy ) ] = 0;
 			unhappy[ utf16_to_utf8( 0x2639, unhappy ) ] = 0;
 			lb_happy[0].buf().printf(translator::translate("Passengers %d %s, %d %s, %d no route"), halt->get_pax_happy(), happy, halt->get_pax_unhappy(), unhappy, halt->get_pax_no_route());
 		}
-		else if(  has_character( 30 )  ) {
+		else if(  g_simgraph->font_has_character( 30 )  ) {
 			lb_happy[0].buf().printf(translator::translate("Passengers %d %c, %d %c, %d no route"), halt->get_pax_happy(), 30, halt->get_pax_unhappy(), 31, halt->get_pax_no_route());
 		}
 		else {
@@ -613,7 +613,7 @@ void gui_halt_detail_t::update_connections( halthandle_t halt )
 			new_component<gui_line_button_t>(line);
 
 			// Line labels with color of player
-			gui_label_buf_t *lb = new_component<gui_label_buf_t>(PLAYER_FLAG | color_idx_to_rgb(line->get_owner()->get_player_color1()+env_t::gui_player_color_dark) );
+			gui_label_buf_t *lb = new_component<gui_label_buf_t>(PLAYER_FLAG | g_simgraph->palette_lookup(line->get_owner()->get_player_color1()+env_t::gui_player_color_dark) );
 			lb->buf().append( line->get_name() );
 			lb->update();
 		}
@@ -633,7 +633,7 @@ void gui_halt_detail_t::update_connections( halthandle_t halt )
 			new_component<gui_convoi_button_t>(cnv);
 
 			// Line labels with color of player
-			gui_label_buf_t *lb = new_component<gui_label_buf_t>(PLAYER_FLAG | color_idx_to_rgb(cnv->get_owner()->get_player_color1()+env_t::gui_player_color_dark) );
+			gui_label_buf_t *lb = new_component<gui_label_buf_t>(PLAYER_FLAG | g_simgraph->palette_lookup(cnv->get_owner()->get_player_color1()+env_t::gui_player_color_dark) );
 			lb->buf().append( cnv->get_name() );
 			lb->update();
 		}
diff --git a/src/simutrans/gui/halt_list_frame.cc b/src/simutrans/gui/halt_list_frame.cc
index a92385827..1928ba4c9 100644
--- a/src/simutrans/gui/halt_list_frame.cc
+++ b/src/simutrans/gui/halt_list_frame.cc
@@ -184,7 +184,7 @@ static bool passes_filter_special(haltestelle_t const& s)
 
 	if (halt_list_frame_t::get_filter(halt_list_frame_t::ueberfuellt_filter)) {
 		PIXVAL const color = s.get_status_farbe();
-		if (color == color_idx_to_rgb(COL_RED) || color == color_idx_to_rgb(COL_ORANGE)) {
+		if (color == g_simgraph->palette_lookup(COL_RED) || color == g_simgraph->palette_lookup(COL_ORANGE)) {
 			return true; // overcrowded
 		}
 	}
diff --git a/src/simutrans/gui/headquarter_info.cc b/src/simutrans/gui/headquarter_info.cc
index a485a08ed..8aa857e77 100644
--- a/src/simutrans/gui/headquarter_info.cc
+++ b/src/simutrans/gui/headquarter_info.cc
@@ -11,7 +11,7 @@
 #include "../player/simplay.h"
 
 headquarter_info_t::headquarter_info_t(player_t* player) : base_infowin_t(player->get_name(), player),
-	headquarter_view(koord3d::invalid, scr_size( max(64, get_base_tile_raster_width()), max(56, (get_base_tile_raster_width()*7)/8) ) )
+	headquarter_view(koord3d::invalid, scr_size( max(64, g_simgraph->get_base_tile_raster_width()), max(56, (g_simgraph->get_base_tile_raster_width()*7)/8) ) )
 {
 	this->player = player;
 
diff --git a/src/simutrans/gui/help_frame.cc b/src/simutrans/gui/help_frame.cc
index 941911b9a..1fea23c96 100644
--- a/src/simutrans/gui/help_frame.cc
+++ b/src/simutrans/gui/help_frame.cc
@@ -272,6 +272,8 @@ void help_frame_t::set_text(const char * buf, bool resize_frame )
 {
 	helptext.set_text(buf);
 
+	const scr_size screen = g_simgraph->get_screen_size();
+
 	if(  resize_frame  ) {
 
 		// try to get the following sizes
@@ -289,8 +291,8 @@ void help_frame_t::set_text(const char * buf, bool resize_frame )
 
 		if(  generaltext.is_visible()  ) {
 			generaltext.set_pos( scr_coord(D_MARGIN_LEFT, D_MARGIN_TOP) );
-			generaltext.set_size( scr_size( min(180,display_get_width()/3), 0 ) );
-			int generalwidth = min( display_get_width()/3, generaltext.get_preferred_size().w );
+			generaltext.set_size( scr_size( min(180, screen.w/3), 0 ) );
+			int generalwidth = min( screen.w/3, generaltext.get_preferred_size().w );
 			generaltext.set_size( scr_size( generalwidth, helptext.get_size().h ) );
 			generaltext.set_size( generaltext.get_preferred_size() );
 		}
@@ -305,11 +307,11 @@ void help_frame_t::set_text(const char * buf, bool resize_frame )
 			size_x += generaltext.get_size().w + D_SCROLLBAR_WIDTH + D_H_SPACE;
 		}
 		// set window size
-		if(  size_x > display_get_width()-32  ) {
-			size_x = display_get_width()-32;
+		if(  size_x > screen.w-32  ) {
+			size_x = screen.w-32;
 		}
 
-		const scr_coord_val h = display_get_height() - D_TITLEBAR_HEIGHT - win_get_statusbar_height() - TICKER_HEIGHT;
+		const scr_coord_val h = screen.h - D_TITLEBAR_HEIGHT - win_get_statusbar_height() - TICKER_HEIGHT;
 		if(  size_y>h) {
 			size_y = h;
 		}
diff --git a/src/simutrans/gui/kennfarbe.cc b/src/simutrans/gui/kennfarbe.cc
index 61b1332d4..42dcbff99 100644
--- a/src/simutrans/gui/kennfarbe.cc
+++ b/src/simutrans/gui/kennfarbe.cc
@@ -22,7 +22,7 @@ class choose_color_button_t : public button_t
 public:
 	choose_color_button_t() : button_t()
 	{
-		w = max(D_BUTTON_HEIGHT, display_get_char_width('X') + D_BUTTON_PADDINGS_X);
+		w = max(D_BUTTON_HEIGHT, g_simgraph->get_char_width('X') + D_BUTTON_PADDINGS_X);
 	}
 	scr_size get_min_size() const OVERRIDE
 	{
@@ -68,7 +68,7 @@ farbengui_t::farbengui_t(player_t *player_) :
 	for(unsigned i=0;  i<28;  i++) {
 		player_color_1[i] = new_component<choose_color_button_t>();
 		player_color_1[i]->init( button_t::box_state, (used_colors1 & (1<<i) ? "X" : " "));
-		player_color_1[i]->background_color = color_idx_to_rgb(i*8+4);
+		player_color_1[i]->background_color = g_simgraph->palette_lookup(i*8+4);
 		player_color_1[i]->add_listener(this);
 	}
 	player_color_1[player->get_player_color1()/8]->pressed = true;
@@ -82,7 +82,7 @@ farbengui_t::farbengui_t(player_t *player_) :
 	for(unsigned i=0;  i<28;  i++) {
 		player_color_2[i] = new_component<choose_color_button_t>();
 		player_color_2[i]->init( button_t::box_state, (used_colors2 & (1<<i) ? "X" : " "));
-		player_color_2[i]->background_color = color_idx_to_rgb(i*8+4);
+		player_color_2[i]->background_color = g_simgraph->palette_lookup(i*8+4);
 		player_color_2[i]->add_listener(this);
 	}
 	player_color_2[player->get_player_color2()/8]->pressed = true;
diff --git a/src/simutrans/gui/label_info.cc b/src/simutrans/gui/label_info.cc
index ab6e60bd5..21fd9dbf1 100644
--- a/src/simutrans/gui/label_info.cc
+++ b/src/simutrans/gui/label_info.cc
@@ -16,7 +16,7 @@
 
 label_info_t::label_info_t(label_t* l) :
 	gui_frame_t( translator::translate("Marker"), l->get_owner()),
-	view(l->get_pos(), scr_size( max(64, get_base_tile_raster_width()), max(56, (get_base_tile_raster_width()*7)/8) ))
+	view(l->get_pos(), scr_size( max(64, g_simgraph->get_base_tile_raster_width()), max(56, (g_simgraph->get_base_tile_raster_width()*7)/8) ))
 {
 	label = l;
 
diff --git a/src/simutrans/gui/labellist_stats.cc b/src/simutrans/gui/labellist_stats.cc
index 268a9086f..285a12a1e 100644
--- a/src/simutrans/gui/labellist_stats.cc
+++ b/src/simutrans/gui/labellist_stats.cc
@@ -78,7 +78,7 @@ labellist_stats_t::labellist_stats_t(koord label_pos)
 
 	if (const label_t *lb = get_label()) {
 		if (lb->get_owner()) {
-			label.set_color(PLAYER_FLAG | color_idx_to_rgb(lb->get_owner()->get_player_color1() + env_t::gui_player_color_dark));
+			label.set_color(PLAYER_FLAG | g_simgraph->palette_lookup(lb->get_owner()->get_player_color1() + env_t::gui_player_color_dark));
 		}
 		else {
 			label.set_color(env_t::default_window_title_color);
diff --git a/src/simutrans/gui/line_item.h b/src/simutrans/gui/line_item.h
index 277ca482e..5520e586f 100644
--- a/src/simutrans/gui/line_item.h
+++ b/src/simutrans/gui/line_item.h
@@ -37,7 +37,7 @@ public:
 	// to update selected status
 	void draw( scr_coord offset ) OVERRIDE;
 	// normal items
-	line_scrollitem_t( linehandle_t l, select_modes_t sm = SELECT_ITEM) : gui_scrolled_list_t::const_text_scrollitem_t( NULL, color_idx_to_rgb(COL_ORANGE) ), select_mode(sm) { line = l; }
+	line_scrollitem_t( linehandle_t l, select_modes_t sm = SELECT_ITEM) : gui_scrolled_list_t::const_text_scrollitem_t( NULL, g_simgraph->palette_lookup(COL_ORANGE) ), select_mode(sm) { line = l; }
 	PIXVAL get_color() const OVERRIDE;
 	linehandle_t get_line() const { return line; }
 	char const* get_text() const OVERRIDE;
diff --git a/src/simutrans/gui/line_management_gui.cc b/src/simutrans/gui/line_management_gui.cc
index 9191a3101..d5ea4c98c 100644
--- a/src/simutrans/gui/line_management_gui.cc
+++ b/src/simutrans/gui/line_management_gui.cc
@@ -110,7 +110,7 @@ line_management_gui_t::line_management_gui_t( linehandle_t line_, player_t* play
 	lb_convoi_count.set_text( "no convois" );
 	add_component( &lb_convoi_count, 3 );
 
-	capacity_bar.add_color_value( &load, color_idx_to_rgb( COL_GREEN ) );
+	capacity_bar.add_color_value( &load, g_simgraph->palette_lookup( COL_GREEN ) );
 	add_component( &capacity_bar, 2 );
 	new_component<gui_fill_t>();
 
@@ -201,11 +201,11 @@ void line_management_gui_t::init(bool not_rdwr)
 		// init_chart
 		if( chart.get_curve_count() == 0 ) {
 			for( int cost = 0; cost < MAX_LINE_COST; cost++ ) {
-				uint16 curve = chart.add_curve( color_idx_to_rgb( cost_type_color[ cost ] ), line->get_finance_history(), MAX_LINE_COST, idx2cost[cost], MAX_MONTHS, cost_type_money[ cost ], cost_type_default[cost], true, cost_type_money[ cost ] * 2 );
+				uint16 curve = chart.add_curve( g_simgraph->palette_lookup( cost_type_color[ cost ] ), line->get_finance_history(), MAX_LINE_COST, idx2cost[cost], MAX_MONTHS, cost_type_money[ cost ], cost_type_default[cost], true, cost_type_money[ cost ] * 2 );
 
 				button_t *b = container_stats.new_component<button_t>();
 				b->init( button_t::box_state_automatic | button_t::flexible, cost_type[ cost ] );
-				b->background_color = color_idx_to_rgb( cost_type_color[ cost ] );
+				b->background_color = g_simgraph->palette_lookup( cost_type_color[ cost ] );
 				b->pressed = cost_type_default[cost];
 				b->add_listener( this );
 
diff --git a/src/simutrans/gui/map_frame.cc b/src/simutrans/gui/map_frame.cc
index 3cd203921..b6fae1c3e 100644
--- a/src/simutrans/gui/map_frame.cc
+++ b/src/simutrans/gui/map_frame.cc
@@ -66,7 +66,7 @@ public:
 	void draw(scr_coord offset) OVERRIDE
 	{
 		scr_coord pos = get_pos() + offset;
-		display_fillbox_wh_clip_rgb( pos.x, pos.y+D_GET_CENTER_ALIGN_OFFSET(D_INDICATOR_BOX_HEIGHT,LINESPACE), D_INDICATOR_BOX_WIDTH, D_INDICATOR_BOX_HEIGHT, color, false );
+		g_simgraph->draw_rect_clipped( pos.x, pos.y+D_GET_CENTER_ALIGN_OFFSET(D_INDICATOR_BOX_HEIGHT,LINESPACE), D_INDICATOR_BOX_WIDTH, D_INDICATOR_BOX_HEIGHT, color, false CLIP_NUM_DEFAULT);
 		label.draw( pos+scr_size(D_INDICATOR_BOX_WIDTH+D_H_SPACE,0) );
 	}
 };
@@ -83,7 +83,7 @@ public:
 		double bar_width = (double)get_size().w/(double)MAX_SEVERITY_COLORS;
 		// color bar
 		for(  int i=0;  i<MAX_SEVERITY_COLORS;  i++  ) {
-			display_fillbox_wh_clip_rgb(pos.x + (scr_coord_val)(i*bar_width), pos.y+2, (scr_coord_val)bar_width+1, 7, minimap_t::calc_severity_color(i, MAX_SEVERITY_COLORS-1), false);
+			g_simgraph->draw_rect_clipped(pos.x + (scr_coord_val)(i*bar_width), pos.y+2, (scr_coord_val)bar_width+1, 7, minimap_t::calc_severity_color(i, MAX_SEVERITY_COLORS-1), false CLIP_NUM_DEFAULT);
 		}
 	}
 	scr_size get_min_size() const OVERRIDE
@@ -314,7 +314,7 @@ map_frame_t::map_frame_t() :
 	viewable_players[ 0 ] = -1;
 	for(  int np = 0, count = 1;  np < MAX_PLAYER_COUNT;  np++  ) {
 		if(  welt->get_player( np )  &&  welt->get_player( np )->get_finance()->has_convoi()) {
-			viewed_player_c.new_component<gui_scrolled_list_t::const_text_scrollitem_t>(welt->get_player( np )->get_name(), color_idx_to_rgb(welt->get_player( np )->get_player_color1()+env_t::gui_player_color_dark));
+			viewed_player_c.new_component<gui_scrolled_list_t::const_text_scrollitem_t>(welt->get_player( np )->get_name(), g_simgraph->palette_lookup(welt->get_player( np )->get_player_color1()+env_t::gui_player_color_dark));
 			viewable_players[ count++ ] = np;
 		}
 	}
@@ -383,7 +383,7 @@ map_frame_t::map_frame_t() :
 	filter_container.set_table_layout(1, 0);
 
 	int w = network_filter_container.get_min_size().w;
-	const int FILTER_BUTTONS_PER_ROW = max(3, min(5, max(display_get_width(),w) / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
+	const int FILTER_BUTTONS_PER_ROW = max(3, min(5, max(g_simgraph->get_screen_size().w, w) / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
 	filter_container.add_table(FILTER_BUTTONS_PER_ROW,0)->set_force_equal_columns(true);
 	// insert filter buttons in legend container
 	for (int index=0; index<MAP_MAX_BUTTONS; index++) {
@@ -437,12 +437,11 @@ void map_frame_t::update_buttons()
 {
 	for(  int i=0;  i<MAP_MAX_BUTTONS;  i++  ) {
 		filter_buttons[i].pressed = (button_init[i].mode&env_t::default_mapmode)!=0;
-		filter_buttons[i].background_color = color_idx_to_rgb(filter_buttons[i].pressed ? button_init[i].select_color : button_init[i].color);
+		filter_buttons[i].background_color = g_simgraph->palette_lookup(filter_buttons[i].pressed ? button_init[i].select_color : button_init[i].color);
 	}
 }
 
 
-
 static bool compare_factories(const factory_desc_t *const a, const factory_desc_t *const b)
 {
 	const bool a_producer_only = a->get_supplier_count() == 0;
@@ -728,7 +727,7 @@ void map_frame_t::draw(scr_coord pos, scr_size size)
 	// may add compass
 	if(  skinverwaltung_t::compass_map  &&  env_t::compass_map_position!=0  ) {
 		const uint16 isometric_img_offset = minimap_t::get_instance()->is_isometric() ? 4 : 0;
-		display_img_aligned( skinverwaltung_t::compass_map->get_image_id( isometric_img_offset+welt->get_settings().get_rotation() ),
+		g_simgraph->draw_img_aligned( skinverwaltung_t::compass_map->get_image_id( isometric_img_offset+welt->get_settings().get_rotation() ),
 							 scrolly.get_client()+pos+scr_coord(4,4+D_TITLEBAR_HEIGHT)-scr_size(8,8), env_t::compass_map_position, false );
 	}
 }
diff --git a/src/simutrans/gui/messagebox.cc b/src/simutrans/gui/messagebox.cc
index 4327f793a..9d06749c6 100644
--- a/src/simutrans/gui/messagebox.cc
+++ b/src/simutrans/gui/messagebox.cc
@@ -32,7 +32,7 @@ fatal_news::fatal_news(const char* text) :
 	copy_to_clipboard.set_focusable(false);
 	add_component(&copy_to_clipboard);
 
-	textarea.set_width(display_get_width()/2);
+	textarea.set_width(g_simgraph->get_screen_size().w/2);
 	recalc_size();
 }
 
@@ -83,7 +83,7 @@ void news_img::init(image_id id)
 
 news_loc::news_loc(const char* text, koord3d k, FLAGGED_PIXVAL color) :
 	news_window(text, color),
-	view(k, scr_size( max(64, get_base_tile_raster_width()), max(56, (get_base_tile_raster_width()*7)/8) ))
+	view(k, scr_size( max(64, g_simgraph->get_base_tile_raster_width()), max(56, (g_simgraph->get_base_tile_raster_width()*7)/8) ))
 {
 	textarea.set_size(scr_size(textarea.get_size().w + view.get_size().w + D_H_SPACE + 1, 0));
 	set_embedded(&view);
diff --git a/src/simutrans/gui/minimap.cc b/src/simutrans/gui/minimap.cc
index 45c3741ee..0efc9b379 100644
--- a/src/simutrans/gui/minimap.cc
+++ b/src/simutrans/gui/minimap.cc
@@ -341,7 +341,7 @@ static void display_airport( const scr_coord_val xx, const scr_coord_val yy, con
 	for ( int i = 0; i < 11; i++ ) {
 		for ( int j = 0; j < 11; j++ ) {
 			if ( symbol[i + j * 11] == 'X' ) {
-				display_vline_wh_clip_rgb( x + i, y + j, 1,  color, true );
+				g_simgraph->draw_vline_clipped(x + i, y + j, 1,  color, true CLIP_NUM_DEFAULT);
 			}
 		}
 	}
@@ -373,7 +373,7 @@ static void display_harbor( const scr_coord_val xx, const scr_coord_val yy, cons
 	for ( int i = 0; i < 11; i++ ) {
 		for ( int j = 0; j < 11; j++ ) {
 			if ( symbol[i + j * 11] == 'X' ) {
-				display_vline_wh_clip_rgb( x + i, y + j, 1,  color, true );
+				g_simgraph->draw_vline_clipped(x + i, y + j, 1,  color, true CLIP_NUM_DEFAULT);
 			}
 		}
 	}
@@ -392,10 +392,10 @@ static void display_thick_line( scr_coord_val x1, scr_coord_val y1, scr_coord_va
 		x2 -= thickness/2;
 		for(  int i = 0;  i < thickness;  i++  ) {
 			if ( !dotting ) {
-				display_direct_line_rgb( x1 + i, y1, x2 + i, y2, col );
+				g_simgraph->draw_line( x1 + i, y1, x2 + i, y2, col );
 			}
 			else {
-				display_direct_line_dotted_rgb( x1 + i, y1, x2 + i, y2, dot_full, dot_empty, col );
+				g_simgraph->draw_line_dotted( x1 + i, y1, x2 + i, y2, dot_full, dot_empty, col );
 			}
 		}
 	}
@@ -405,10 +405,10 @@ static void display_thick_line( scr_coord_val x1, scr_coord_val y1, scr_coord_va
 		y2 -= thickness/2;
 		for(  int i = 0;  i < thickness;  i++  ) {
 			if ( !dotting ) {
-				display_direct_line_rgb( x1, y1 + i, x2, y2 + i, col );
+				g_simgraph->draw_line( x1, y1 + i, x2, y2 + i, col );
 			}
 			else {
-				display_direct_line_dotted_rgb( x1, y1 + i, x2, y2 + i, dot_full, dot_empty, col );
+				g_simgraph->draw_line_dotted( x1, y1 + i, x2, y2 + i, dot_full, dot_empty, col );
 			}
 		}
 	}
@@ -422,12 +422,12 @@ static void display_thick_line( scr_coord_val x1, scr_coord_val y1, scr_coord_va
 		y2 -= thickness*y_multiplier/2;
 		for(  int i = 0;  i < thickness;  i++  ) {
 			if ( !dotting ) {
-				display_direct_line_rgb( x1+i, y1+i*y_multiplier, x2+i, y2+i*y_multiplier, col );
-				display_direct_line_rgb( x1+i+1, y1+i*y_multiplier, x2+i+1, y2+i*y_multiplier, col );
+				g_simgraph->draw_line( x1+i, y1+i*y_multiplier, x2+i, y2+i*y_multiplier, col );
+				g_simgraph->draw_line( x1+i+1, y1+i*y_multiplier, x2+i+1, y2+i*y_multiplier, col );
 			}
 			else {
-				display_direct_line_dotted_rgb( x1 + i, y1 + i*y_multiplier, x2 + i, y2 + i*y_multiplier, dot_full, dot_empty, col );
-				display_direct_line_dotted_rgb( x1 + i + 1, y1 + i*y_multiplier, x2 + i + 1, y2 + i*y_multiplier, dot_full, dot_empty, col );
+				g_simgraph->draw_line_dotted( x1 + i, y1 + i*y_multiplier, x2 + i, y2 + i*y_multiplier, dot_full, dot_empty, col );
+				g_simgraph->draw_line_dotted( x1 + i + 1, y1 + i*y_multiplier, x2 + i + 1, y2 + i*y_multiplier, dot_full, dot_empty, col );
 			}
 		}
 	}
@@ -439,8 +439,8 @@ static void line_segment_draw( waytype_t type, scr_coord start, const uint8 star
 	// airplanes are different, so we must check for them first
 	if(  type ==  air_wt  ) {
 		// ignore offset for airplanes
-		draw_bezier_rgb( start.x, start.y, end.x, end.y, 50, 50, 50, 50, colore, 5, 5 );
-		draw_bezier_rgb( start.x + 1, start.y + 1, end.x + 1, end.y + 1, 50, 50, 50, 50, colore, 5, 5 );
+		g_simgraph->draw_bezier(start.x,   start.y,   end.x,   end.y,   50, 50, 50, 50, colore, 5, 5);
+		g_simgraph->draw_bezier(start.x+1, start.y+1, end.x+1, end.y+1, 50, 50, 50, 50, colore, 5, 5);
 	}
 	else {
 		// determine line style
@@ -583,9 +583,9 @@ PIXVAL minimap_t::calc_severity_color(sint32 amount, sint32 max_value)
 	if(max_value!=0) {
 		// color array goes from light blue to red
 		const sint32 severity = ((sint64)amount * MAX_SEVERITY_COLORS) / ((sint64)max_value + 1);
-		return color_idx_to_rgb( minimap_t::severity_color[ clamp( severity, 0, MAX_SEVERITY_COLORS-1 ) ]);
+		return g_simgraph->palette_lookup( minimap_t::severity_color[ clamp( severity, 0, MAX_SEVERITY_COLORS-1 ) ]);
 	}
-	return color_idx_to_rgb( minimap_t::severity_color[0]);
+	return g_simgraph->palette_lookup( minimap_t::severity_color[0]);
 }
 
 
@@ -599,9 +599,9 @@ PIXVAL minimap_t::calc_severity_color_log(sint32 amount, sint32 max_value)
 		else {
 			severity = (uint32)( log( (double)amount*(double)(1<<MAX_SEVERITY_COLORS)/(double)max_value) + 0.5 );
 		}
-		return color_idx_to_rgb( minimap_t::severity_color[ clamp( severity, 0, MAX_SEVERITY_COLORS-1 ) ]);
+		return g_simgraph->palette_lookup( minimap_t::severity_color[ clamp( severity, 0, MAX_SEVERITY_COLORS-1 ) ]);
 	}
-	return color_idx_to_rgb( minimap_t::severity_color[0]);
+	return g_simgraph->palette_lookup( minimap_t::severity_color[0]);
 }
 
 
@@ -676,7 +676,7 @@ PIXVAL minimap_t::calc_height_color(const sint16 hoehe, const sint16 groundwater
 	else {
 		relative_index = hoehe-groundwater;
 	}
-	return color_idx_to_rgb(map_type_color[clamp( relative_index+MAX_MAP_TYPE_WATER-1, 0, MAX_MAP_TYPE_WATER+MAX_MAP_TYPE_LAND-1 )]);
+	return g_simgraph->palette_lookup(map_type_color[clamp( relative_index+MAX_MAP_TYPE_WATER-1, 0, MAX_MAP_TYPE_WATER+MAX_MAP_TYPE_LAND-1 )]);
 }
 
 
@@ -685,12 +685,12 @@ PIXVAL minimap_t::calc_height_color(const sint16 hoehe, const sint16 groundwater
  */
 PIXVAL minimap_t::calc_ground_color(const grund_t *gr)
 {
-	PIXVAL color = color_idx_to_rgb(COL_BLACK);
+	PIXVAL color = g_simgraph->palette_lookup(COL_BLACK);
 
 #ifdef DEBUG_ROUTES
 	/* for debug purposes only ...*/
 	if(gr->get_flag(grund_t::marked)) {
-		color = color_idx_to_rgb(COL_PURPLE);
+		color = g_simgraph->palette_lookup(COL_PURPLE);
 	}
 	else
 #endif
@@ -700,10 +700,10 @@ PIXVAL minimap_t::calc_ground_color(const grund_t *gr)
 	else {
 		switch(gr->get_typ()) {
 			case grund_t::brueckenboden:
-				color = color_idx_to_rgb(MN_GREY3);
+				color = g_simgraph->palette_lookup(MN_GREY3);
 				break;
 			case grund_t::tunnelboden:
-				color = color_idx_to_rgb(COL_BROWN);
+				color = g_simgraph->palette_lookup(COL_BROWN);
 				break;
 			case grund_t::monorailboden:
 				color = COL_MONORAIL;
@@ -714,7 +714,7 @@ PIXVAL minimap_t::calc_ground_color(const grund_t *gr)
 					gebaeude_t *gb = gr->find<gebaeude_t>();
 					fabrik_t *fab = gb ? gb->get_fabrik() : NULL;
 					if(fab==NULL) {
-						color = color_idx_to_rgb(COL_GREY3);
+						color = g_simgraph->palette_lookup(COL_GREY3);
 					}
 					else {
 						color = fab->get_color();
@@ -729,12 +729,12 @@ PIXVAL minimap_t::calc_ground_color(const grund_t *gr)
 					if(fab==NULL) {
 						sint16 height = corner_sw(gr->get_grund_hang());
 						if( mode&MAP_HIDE_CONTOUR ) {
-							color = color_idx_to_rgb(map_type_color[1]); // second deep water color
+							color = g_simgraph->palette_lookup(map_type_color[1]); // second deep water color
 						}
 						else {
 							color = calc_height_color( world->lookup_hgt( gr->get_pos().get_2d() ) + height, world->get_water_hgt( gr->get_pos().get_2d() ) );
 						}
-						//color = color_idx_to_rgb(COL_BLUE); // water with boat?
+						//color = g_simgraph->palette_lookup(COL_BLUE); // water with boat?
 					}
 					else {
 						color = fab->get_color();
@@ -752,7 +752,7 @@ PIXVAL minimap_t::calc_ground_color(const grund_t *gr)
 						case air_wt: color = COL_RUNWAY; break;
 						case monorail_wt:
 						default: // all other ways light red ...
-							color = color_idx_to_rgb(135); break;
+							color = g_simgraph->palette_lookup(135); break;
 					}
 				}
 				else {
@@ -762,11 +762,11 @@ PIXVAL minimap_t::calc_ground_color(const grund_t *gr)
 					}
 					else {
 						if( mode&MAP_HIDE_CONTOUR ) {
-							color = color_idx_to_rgb(map_type_color[MAX_MAP_TYPE_WATER+2]); // lowest land color
+							color = g_simgraph->palette_lookup(map_type_color[MAX_MAP_TYPE_WATER+2]); // lowest land color
 						}
 						else if( mode&MAP_CLIMATES ) {
 							static uint8 climate_color[ 8 ] = { 0, COL_YELLOW, COL_LIGHT_GREEN, COL_GREEN, COL_DARK_GREEN, COL_DARK_YELLOW, COL_BROWN, COL_GREY4 };
-							color = color_idx_to_rgb( climate_color[ world->get_climate(gr->get_pos().get_2d()) ] );
+							color = g_simgraph->palette_lookup( climate_color[ world->get_climate(gr->get_pos().get_2d()) ] );
 						}
 						else {
 							sint16 height = corner_sw(gr->get_grund_hang());
@@ -868,15 +868,15 @@ bool minimap_t::calc_map_pixel(const grund_t *gr)
 				const schiene_t* sch = (const schiene_t*)(gr->get_weg(track_wt));
 				// show signals
 				if (sch->has_sign() || sch->has_signal()) {
-					set_map_color(k, color_idx_to_rgb(COL_YELLOW));
+					set_map_color(k, g_simgraph->palette_lookup(COL_YELLOW));
 					return true;
 				}
 				else if (sch->is_electrified()) {
-					set_map_color(k, color_idx_to_rgb(COL_RED));
+					set_map_color(k, g_simgraph->palette_lookup(COL_RED));
 					return true;
 				}
 				else {
-					set_map_color(k, color_idx_to_rgb(COL_WHITE));
+					set_map_color(k, g_simgraph->palette_lookup(COL_WHITE));
 					return true;
 				}
 
@@ -903,7 +903,7 @@ bool minimap_t::calc_map_pixel(const grund_t *gr)
 
 		case MAP_FOREST:
 			if (gr->obj_count() > 1 && gr->obj_bei(gr->obj_count() - 1)->get_typ() == obj_t::baum) {
-				set_map_color(k, color_idx_to_rgb(COL_GREEN));
+				set_map_color(k, g_simgraph->palette_lookup(COL_GREEN));
 				return true;
 			}
 			break;
@@ -911,16 +911,16 @@ bool minimap_t::calc_map_pixel(const grund_t *gr)
 	case MAP_OWNER:
 		// show ownership
 		if (gr->is_halt()) {
-			set_map_color(k, color_idx_to_rgb(gr->get_halt()->get_owner()->get_player_color1() + 3));
+			set_map_color(k, g_simgraph->palette_lookup(gr->get_halt()->get_owner()->get_player_color1() + 3));
 			return true;
 		}
 		else if (weg_t* weg = gr->get_weg_nr(0)) {
-			set_map_color(k, weg->get_owner() == NULL ? color_idx_to_rgb(COL_ORANGE) : color_idx_to_rgb(weg->get_owner()->get_player_color1() + 3));
+			set_map_color(k, weg->get_owner() == NULL ? g_simgraph->palette_lookup(COL_ORANGE) : g_simgraph->palette_lookup(weg->get_owner()->get_player_color1() + 3));
 			return true;
 		}
 		if (gebaeude_t* gb = gr->find<gebaeude_t>()) {
 			if (gb->get_owner() != NULL) {
-				set_map_color(k, color_idx_to_rgb(gb->get_owner()->get_player_color1() + 3));
+				set_map_color(k, g_simgraph->palette_lookup(gb->get_owner()->get_player_color1() + 3));
 				return true;
 			}
 		}
@@ -975,7 +975,7 @@ void minimap_t::calc_map_pixel(const koord k)
 			for (int i = 0; i < plan->get_haltlist_count(); i++) {
 				halthandle_t halt = plan->get_haltlist()[i];
 				if (halt->get_pax_enabled() && !halt->get_pax_connections().empty()) {
-					set_map_color(k, color_idx_to_rgb(halt->get_owner()->get_player_color1() + 3));
+					set_map_color(k, g_simgraph->palette_lookup(halt->get_owner()->get_player_color1() + 3));
 					return;
 				}
 			}
@@ -987,7 +987,7 @@ void minimap_t::calc_map_pixel(const koord k)
 			for (int i = 0; i < plan->get_haltlist_count(); i++) {
 				halthandle_t halt = plan->get_haltlist()[i];
 				if (halt->get_mail_enabled() && !halt->get_mail_connections().empty()) {
-					set_map_color(k, color_idx_to_rgb(halt->get_owner()->get_player_color1() + 3));
+					set_map_color(k, g_simgraph->palette_lookup(halt->get_owner()->get_player_color1() + 3));
 					return;
 				}
 			}
@@ -1009,7 +1009,7 @@ void minimap_t::calc_map_pixel(const koord k)
 			set_map_color(k, calc_ground_color(last_tunnel));
 		}
 		else {
-			set_map_color(k, color_idx_to_rgb(COL_BLACK));
+			set_map_color(k, g_simgraph->palette_lookup(COL_BLACK));
 		}
 	}
 	else if(grund_t::underground_mode == grund_t::ugm_level) {
@@ -1027,7 +1027,7 @@ void minimap_t::calc_map_pixel(const koord k)
 			set_map_color(k, calc_ground_color(gr));
 		}
 		else {
-			set_map_color(k, color_idx_to_rgb(COL_BLACK));
+			set_map_color(k, g_simgraph->palette_lookup(COL_BLACK));
 		}
 	}
 	else {
@@ -1096,7 +1096,7 @@ void minimap_t::calc_map()
 	else {
 		// always the whole map ...
 		if(isometric) {
-			map_data->init( color_idx_to_rgb(COL_BLACK) );
+			map_data->init( g_simgraph->palette_lookup(COL_BLACK) );
 		}
 		koord k;
 		for(  k.y=0;  k.y < world->get_size().y;  k.y++  ) {
@@ -1222,21 +1222,21 @@ const fabrik_t* minimap_t::get_factory_near( const koord, bool enlarge ) const
 const fabrik_t* minimap_t::draw_factory_connections(const fabrik_t* const fab, bool supplier_link, const scr_coord pos) const
 {
 	if(fab) {
-		PIXVAL color = supplier_link ? color_idx_to_rgb(COL_RED) : color_idx_to_rgb(COL_WHITE);
+		PIXVAL color = supplier_link ? g_simgraph->palette_lookup(COL_RED) : g_simgraph->palette_lookup(COL_WHITE);
 		scr_coord fabpos = map_to_screen_coord( fab->get_pos().get_2d() ) + pos;
 		const vector_tpl<koord>& consumer = supplier_link ? fab->get_suppliers() : fab->get_consumer();
 		for(koord lieferziel : consumer) {
 			const fabrik_t * fab2 = fabrik_t::get_fab(lieferziel);
 			if (fab2) {
 				const scr_coord end = map_to_screen_coord( lieferziel ) + pos;
-				display_direct_line_rgb(fabpos.x, fabpos.y, end.x, end.y, color);
-				display_fillbox_wh_clip_rgb(end.x, end.y, 3, 3, ((world->get_ticks() >> 10) & 1) == 0 ? color_idx_to_rgb(COL_RED) : color_idx_to_rgb(COL_WHITE), true);
+				g_simgraph->draw_line(fabpos.x, fabpos.y, end.x, end.y, color);
+				g_simgraph->draw_rect_clipped(end.x, end.y, 3, 3, ((world->get_ticks() >> 10) & 1) == 0 ? g_simgraph->palette_lookup(COL_RED) : g_simgraph->palette_lookup(COL_WHITE), true CLIP_NUM_DEFAULT);
 
 				scr_coord boxpos = end + scr_coord(10, 0);
 				const char * name = translator::translate(fab2->get_name());
-				int name_width = proportional_string_width(name)+(LINESPACE/2);
+				int name_width = g_simgraph->calc_text_width(name) + (LINESPACE/2);
 				boxpos.x = clamp( boxpos.x, pos.x, pos.x+get_size().w-name_width );
-				display_ddd_proportional_clip(boxpos.x, boxpos.y, color_idx_to_rgb(5), color_idx_to_rgb(COL_WHITE), name, true);
+				g_simgraph->draw_textbox3d_clipped(boxpos.x, boxpos.y, g_simgraph->palette_lookup(5), g_simgraph->palette_lookup(COL_WHITE), name, true CLIP_NUM_DEFAULT);
 			}
 		}
 	}
@@ -1336,12 +1336,12 @@ void minimap_t::draw(scr_coord pos)
 	}
 
 	if(  (uint16)cur_size.w > map_data->get_width()  ) {
-		display_fillbox_wh_clip_rgb( pos.x+new_off.x+map_data->get_width(), new_off.y+pos.y, 32767, map_data->get_height(), color_idx_to_rgb(COL_BLACK), true);
+		g_simgraph->draw_rect_clipped( pos.x+new_off.x+map_data->get_width(), new_off.y+pos.y, 32767, map_data->get_height(), g_simgraph->palette_lookup(COL_BLACK), true CLIP_NUM_DEFAULT);
 	}
 	if(  (uint16)cur_size.h > map_data->get_height()  ) {
-		display_fillbox_wh_clip_rgb( pos.x+new_off.x, pos.y+new_off.y+map_data->get_height(), 32767, 32767, color_idx_to_rgb(COL_BLACK), true);
+		g_simgraph->draw_rect_clipped( pos.x+new_off.x, pos.y+new_off.y+map_data->get_height(), 32767, 32767, g_simgraph->palette_lookup(COL_BLACK), true CLIP_NUM_DEFAULT);
 	}
-	display_array_wh( cur_off.x+pos.x, new_off.y+pos.y, map_data->get_width(), map_data->get_height(), map_data->to_array());
+	g_simgraph->draw_array( cur_off.x+pos.x, new_off.y+pos.y, map_data->get_width(), map_data->get_height(), map_data->to_array());
 
 	if(  !current_cnv.is_bound()  &&  mode & MAP_LINES    ) {
 		vector_tpl<linehandle_t> linee;
@@ -1455,24 +1455,24 @@ void minimap_t::draw(scr_coord pos)
 			// top and bottom part
 			const int toplines = min( p4.y, p2.y );
 			for( scr_coord_val y = 0;  y < toplines;  y++  ) {
-				display_blend_wh_rgb( pos.x+p1.x-2*y, pos.y+y, 4*y+4, 1, color_idx_to_rgb(COL_WHITE), 75 );
-				display_blend_wh_rgb( pos.x+p3.x-2*y, pos.y+p3.y-y-1, 4*y+4, 1, color_idx_to_rgb(COL_WHITE), 75 );
+				g_simgraph->tint_rect( pos.x+p1.x-2*y, pos.y+y,        4*y+4, 1, g_simgraph->palette_lookup(COL_WHITE), 75 );
+				g_simgraph->tint_rect( pos.x+p3.x-2*y, pos.y+p3.y-y-1, 4*y+4, 1, g_simgraph->palette_lookup(COL_WHITE), 75 );
 			}
 			// center area
 			if(  p1.x < p3.x  ) {
 				for( scr_coord_val y = toplines;  y < p3.y-toplines;  y++  ) {
-					display_blend_wh_rgb( pos.x+(y-toplines)*2, pos.y+y, 4*toplines+4, 1, color_idx_to_rgb(COL_WHITE), 75 );
+					g_simgraph->tint_rect( pos.x+(y-toplines)*2, pos.y+y, 4*toplines+4, 1, g_simgraph->palette_lookup(COL_WHITE), 75 );
 				}
 			}
 			else {
 				for( scr_coord_val y = toplines;  y < p3.y-toplines;  y++  ) {
-					display_blend_wh_rgb( pos.x+(y-toplines)*2, pos.y+p3.y-y-1, 4*toplines+4, 1, color_idx_to_rgb(COL_WHITE), 75 );
+					g_simgraph->tint_rect( pos.x+(y-toplines)*2, pos.y+p3.y-y-1, 4*toplines+4, 1, g_simgraph->palette_lookup(COL_WHITE), 75 );
 				}
 			}
 		}
 		else {
 			// easier with rectangular maps ...
-			display_blend_wh_rgb( cur_off.x+pos.x, cur_off.y+pos.y, map_data->get_width(), map_data->get_height(), color_idx_to_rgb(COL_WHITE), 75 );
+			g_simgraph->tint_rect( cur_off.x+pos.x, cur_off.y+pos.y, map_data->get_width(), map_data->get_height(), g_simgraph->palette_lookup(COL_WHITE), 75 );
 		}
 
 		scr_coord k1,k2;
@@ -1501,7 +1501,7 @@ void minimap_t::draw(scr_coord pos)
 				diagonal = seg.start_diagonal;
 			}
 			// and finally draw ...
-			line_segment_draw( seg.waytype, k1, seg.start_offset*offset, k2, seg.end_offset*offset, diagonal, color_idx_to_rgb(color) );
+			line_segment_draw( seg.waytype, k1, seg.start_offset*offset, k2, seg.end_offset*offset, diagonal, g_simgraph->palette_lookup(color) );
 		}
 	}
 
@@ -1602,7 +1602,7 @@ void minimap_t::draw(scr_coord pos)
 		}
 		else {
 			const int stype = station->get_station_type();
-			color = color_idx_to_rgb(station->get_owner()->get_player_color1()+3);
+			color = g_simgraph->palette_lookup(station->get_owner()->get_player_color1()+3);
 
 			// invalid=0, loadingbay=1, railstation = 2, dock = 4, busstop = 8, airstop = 16, monorailstop = 32, tramstop = 64, maglevstop=128, narrowgaugestop=256
 			if(  stype > 0  ) {
@@ -1629,7 +1629,7 @@ void minimap_t::draw(scr_coord pos)
 					if(  (stype>>type)&1  ) {
 						image_id img = skinverwaltung_t::station_type->get_image_id(type);
 						if(  img!=IMG_EMPTY  ) {
-							display_color_img( img, temp_stop.x+diagonal_dist+4+(icon/2)*12, temp_stop.y+diagonal_dist+4+(icon&1)*12, station->get_owner()->get_player_nr(), false, false );
+							g_simgraph->draw_color_img( img, temp_stop.x+diagonal_dist+4+(icon/2)*12, temp_stop.y+diagonal_dist+4+(icon&1)*12, station->get_owner()->get_player_nr(), false, false CLIP_NUM_DEFAULT);
 							icon++;
 						}
 					}
@@ -1652,17 +1652,19 @@ void minimap_t::draw(scr_coord pos)
 		}
 
 		int out_radius = (radius == 0) ? 1 : radius;
-		display_filled_circle_rgb( temp_stop.x, temp_stop.y, radius, color );
-		display_circle_rgb( temp_stop.x, temp_stop.y, out_radius, color_idx_to_rgb(COL_BLACK) );
+		g_simgraph->draw_filled_circle(temp_stop.x, temp_stop.y, radius,     color );
+		g_simgraph->draw_empty_circle (temp_stop.x, temp_stop.y, out_radius, g_simgraph->palette_lookup(COL_BLACK));
+
 		if(  diagonal_dist>0  ) {
-			display_filled_circle_rgb( temp_stop.x+diagonal_dist, temp_stop.y+diagonal_dist, radius, color );
-			display_circle_rgb( temp_stop.x+diagonal_dist, temp_stop.y+diagonal_dist, out_radius, color_idx_to_rgb(COL_BLACK) );
+			g_simgraph->draw_filled_circle( temp_stop.x+diagonal_dist, temp_stop.y+diagonal_dist, radius,     color );
+			g_simgraph->draw_empty_circle ( temp_stop.x+diagonal_dist, temp_stop.y+diagonal_dist, out_radius, g_simgraph->palette_lookup(COL_BLACK));
+
 			for(  int i=1;  i < diagonal_dist;  i++  ) {
-				display_filled_circle_rgb( temp_stop.x+i, temp_stop.y+i, radius, color );
+				g_simgraph->draw_filled_circle( temp_stop.x+i, temp_stop.y+i, radius, color );
 			}
 			out_radius = sqrt_i32( 2*out_radius+1 );
-			display_direct_line_rgb( temp_stop.x+out_radius, temp_stop.y-out_radius, temp_stop.x+out_radius+diagonal_dist, temp_stop.y-out_radius+diagonal_dist, color_idx_to_rgb(COL_BLACK) );
-			display_direct_line_rgb( temp_stop.x-out_radius, temp_stop.y+out_radius, temp_stop.x-out_radius+diagonal_dist, temp_stop.y+out_radius+diagonal_dist, color_idx_to_rgb(COL_BLACK) );
+			g_simgraph->draw_line( temp_stop.x+out_radius, temp_stop.y-out_radius, temp_stop.x+out_radius+diagonal_dist, temp_stop.y-out_radius+diagonal_dist, g_simgraph->palette_lookup(COL_BLACK) );
+			g_simgraph->draw_line( temp_stop.x-out_radius, temp_stop.y+out_radius, temp_stop.x-out_radius+diagonal_dist, temp_stop.y+out_radius+diagonal_dist, g_simgraph->palette_lookup(COL_BLACK) );
 		}
 
 		if(  koord_distance( last_world_pos, station->get_basis_pos() ) <= 2  ) {
@@ -1673,7 +1675,7 @@ void minimap_t::draw(scr_coord pos)
 	if(  display_station.is_bound()  ) {
 		scr_coord temp_stop = map_to_screen_coord( display_station->get_basis_pos() );
 		temp_stop = temp_stop + pos;
-		display_ddd_proportional_clip( temp_stop.x + 10, temp_stop.y + 7, color_idx_to_rgb(display_station->get_owner()->get_player_color1()+3), color_idx_to_rgb(COL_WHITE), display_station->get_name(), false );
+		g_simgraph->draw_textbox3d_clipped(temp_stop.x + 10, temp_stop.y + 7, g_simgraph->palette_lookup(display_station->get_owner()->get_player_color1()+3), g_simgraph->palette_lookup(COL_WHITE), display_station->get_name(), false CLIP_NUM_DEFAULT);
 	}
 	max_waiting_change = new_max_waiting_change; // update waiting tendencies
 
@@ -1681,20 +1683,20 @@ void minimap_t::draw(scr_coord pos)
 	// ADD: if CRTL key is pressed, temporary show the name
 	if(  mode & MAP_TOWN  ) {
 		const weighted_vector_tpl<stadt_t*>& staedte = world->get_cities();
-		const PIXVAL col = color_idx_to_rgb(showing_schedule ? COL_BLACK : COL_WHITE);
+		const PIXVAL col = g_simgraph->palette_lookup(showing_schedule ? COL_BLACK : COL_WHITE);
 
 		for(stadt_t* const stadt : staedte ) {
 			const char * name = stadt->get_name();
 
 			scr_coord p = map_to_screen_coord( stadt->get_pos() );
 			p += pos;
-			display_proportional_clip_rgb( p.x, p.y, name, ALIGN_LEFT, col, true );
+			g_simgraph->draw_text_clipped( p.x, p.y, name, ALIGN_LEFT, col, true );
 		}
 	}
 
 	// draw city limit
 	if(  mode & MAP_CITYLIMIT  ) {
-		const PIXVAL col = color_idx_to_rgb(showing_schedule ? COL_DARK_BROWN : COL_ORANGE);
+		const PIXVAL col = g_simgraph->palette_lookup(showing_schedule ? COL_DARK_BROWN : COL_ORANGE);
 
 		// for all cities
 		for(stadt_t* const stadt :  world->get_cities()  ) {
@@ -1714,10 +1716,10 @@ void minimap_t::draw(scr_coord pos)
 				c[i] = map_to_screen_coord(k[i]) + pos;
 			}
 
-			display_direct_line_dotted_rgb( c[0].x, c[0].y, c[1].x, c[1].y, 3, 3, col );
-			display_direct_line_dotted_rgb( c[1].x, c[1].y, c[2].x, c[2].y, 3, 3, col );
-			display_direct_line_dotted_rgb( c[2].x, c[2].y, c[3].x, c[3].y, 3, 3, col );
-			display_direct_line_dotted_rgb( c[3].x, c[3].y, c[0].x, c[0].y, 3, 3, col );
+			g_simgraph->draw_line_dotted( c[0].x, c[0].y, c[1].x, c[1].y, 3, 3, col );
+			g_simgraph->draw_line_dotted( c[1].x, c[1].y, c[2].x, c[2].y, 3, 3, col );
+			g_simgraph->draw_line_dotted( c[2].x, c[2].y, c[3].x, c[3].y, 3, 3, col );
+			g_simgraph->draw_line_dotted( c[3].x, c[3].y, c[0].x, c[0].y, 3, 3, col );
 		}
 	}
 
@@ -1734,8 +1736,8 @@ void minimap_t::draw(scr_coord pos)
 				}
 				PIXVAL color = calc_severity_color_log(gb->get_passagier_level(), max_tourist_ziele);
 				int radius = max( (number_to_radius( pax*4 )*zoom_in)/zoom_out, 1 );
-				display_filled_circle_rgb( gb_pos.x, gb_pos.y, radius, color );
-				display_circle_rgb( gb_pos.x, gb_pos.y, radius, color_idx_to_rgb(COL_BLACK) );
+				g_simgraph->draw_filled_circle(gb_pos.x, gb_pos.y, radius, color);
+				g_simgraph->draw_empty_circle (gb_pos.x, gb_pos.y, radius, g_simgraph->palette_lookup(COL_BLACK) );
 			}
 			// otherwise larger attraction will be shown more often ...
 		}
@@ -1755,8 +1757,8 @@ void minimap_t::draw(scr_coord pos)
 			koord size = f->get_desc()->get_building()->get_size(f->get_rotate());
 			sint16 x_size = max( 5, size.x*zoom_in );
 			sint16 y_size = max( 5, size.y*zoom_in );
-			display_fillbox_wh_clip_rgb( fab_pos.x-1, fab_pos.y-1, x_size+2, y_size+2, color_idx_to_rgb(COL_BLACK), false );
-			display_fillbox_wh_clip_rgb( fab_pos.x, fab_pos.y, x_size, y_size, f->get_color(), false );
+			g_simgraph->draw_rect_clipped( fab_pos.x-1, fab_pos.y-1, x_size+2, y_size+2, g_simgraph->palette_lookup(COL_BLACK), false CLIP_NUM_DEFAULT);
+			g_simgraph->draw_rect_clipped( fab_pos.x, fab_pos.y, x_size, y_size, f->get_color(), false CLIP_NUM_DEFAULT);
 		}
 	}
 
@@ -1767,19 +1769,21 @@ void minimap_t::draw(scr_coord pos)
 				depot_pos = depot_pos + pos;
 				// offset of one to avoid
 				static uint8 depot_typ_to_color[19]={ COL_ORANGE, COL_YELLOW, COL_RED, 0, 0, 0, 0, 0, 0, COL_PURPLE, COL_DARK_RED, COL_DARK_ORANGE, 0, 0, 0, 0, 0, 0, COL_LIGHT_RED };
-				display_filled_circle_rgb( depot_pos.x, depot_pos.y, 4, color_idx_to_rgb(depot_typ_to_color[d->get_typ() - obj_t::bahndepot]) );
-				display_circle_rgb( depot_pos.x, depot_pos.y, 4, color_idx_to_rgb(COL_BLACK) );
+				g_simgraph->draw_filled_circle(depot_pos.x, depot_pos.y, 4, g_simgraph->palette_lookup(depot_typ_to_color[d->get_typ() - obj_t::bahndepot]) );
+				g_simgraph->draw_empty_circle (depot_pos.x, depot_pos.y, 4, g_simgraph->palette_lookup(COL_BLACK) );
 			}
 		}
 	}
 
 	// zoom/resize "selection box" in map
 	// this must be rotated by 45 degree (sin45=cos45=0,5*sqrt(2)=0.707...)
-	const sint16 raster=get_tile_raster_width();
+	const sint16 raster = g_simgraph->get_tile_raster_width();
+
+	const scr_size screen = g_simgraph->get_screen_size();
 
 	// calculate and draw the rotated coordinates
 	koord ij = world->get_viewport()->get_world_position();
-	const koord diff = koord( display_get_width()/(2*raster), display_get_height()/raster );
+	const koord diff = koord( screen.w/(2*raster), screen.h/raster );
 
 	koord view[4];
 	scr_coord test[4];
@@ -1790,10 +1794,10 @@ void minimap_t::draw(scr_coord pos)
 	view[3] = ij + koord( diff.y+diff.x, diff.y-diff.x );
 
 	// try to find tile under the four corners of the screen
-	test[0] = scr_coord(display_get_width(),0);
+	test[0] = scr_coord(screen.w,0);
 	test[1] = scr_coord(0,0);
-	test[2] = scr_coord(0,display_get_height());
-	test[3] = scr_coord(display_get_width(),display_get_height());
+	test[2] = scr_coord(0,screen.h);
+	test[3] = scr_coord(screen.w, screen.h);
 
 	for(int i=0; i<4; i++) {
 		sint32 dummy1, dummy2;
@@ -1808,7 +1812,7 @@ void minimap_t::draw(scr_coord pos)
 		c[i] = map_to_screen_coord( view[i] ) + pos;
 	}
 	for(  int i=0;  i<4;  i++  ) {
-		display_direct_line_rgb( c[i].x, c[i].y, c[(i+1)%4].x, c[(i+1)%4].y, color_idx_to_rgb(showing_schedule?COL_RED:COL_YELLOW));
+		g_simgraph->draw_line( c[i].x, c[i].y, c[(i+1)%4].x, c[(i+1)%4].y, g_simgraph->palette_lookup(showing_schedule?COL_RED:COL_YELLOW));
 	}
 
 	if(  !showing_schedule  ) {
@@ -1821,10 +1825,10 @@ void minimap_t::draw(scr_coord pos)
 			scr_coord fabpos = map_to_screen_coord( fab->get_pos().get_2d() );
 			scr_coord boxpos = fabpos + scr_coord(10, 0);
 			const char * name = translator::translate(fab->get_name());
-			int name_width = proportional_string_width(name)+(LINESPACE/2);
+			int name_width = g_simgraph->calc_text_width(name) + (LINESPACE/2);
 			boxpos.x = clamp( boxpos.x, 0, 0+get_size().w-name_width );
 			boxpos += pos;
-			display_ddd_proportional_clip(boxpos.x, boxpos.y, color_idx_to_rgb(10), color_idx_to_rgb(COL_WHITE), name, true);
+			g_simgraph->draw_textbox3d_clipped(boxpos.x, boxpos.y, g_simgraph->palette_lookup(10), g_simgraph->palette_lookup(COL_WHITE), name, true CLIP_NUM_DEFAULT);
 		}
 
 		for (int i = win_get_open_count() - 1; i >= 0; i--) {
@@ -1845,7 +1849,7 @@ void minimap_t::draw(scr_coord pos)
 		scr_coord_val wd = max( zoom_in/zoom_out, 1) * 2 + 1; // to have it always odd
 		for(  int i = 0;  i < current_cnv->get_vehicle_count();  i++  ) {
 			const scr_coord veh_pos = map_to_screen_coord(current_cnv->get_vehicle(i)->get_pos().get_2d()) + pos;
-			display_fillbox_wh_clip_rgb(veh_pos.x-(wd/2)+offset, veh_pos.y-(wd/2)+offset, wd, wd, color_idx_to_rgb(COL_MAGENTA), true);
+			g_simgraph->draw_rect_clipped(veh_pos.x-(wd/2)+offset, veh_pos.y-(wd/2)+offset, wd, wd, g_simgraph->palette_lookup(COL_MAGENTA), true CLIP_NUM_DEFAULT);
 		}
 	}
 }
diff --git a/src/simutrans/gui/money_frame.cc b/src/simutrans/gui/money_frame.cc
index f4f5b6199..59872e634 100644
--- a/src/simutrans/gui/money_frame.cc
+++ b/src/simutrans/gui/money_frame.cc
@@ -365,14 +365,14 @@ money_frame_t::money_frame_t(player_t *player) :
 					const int curve_type = cost_type[3*cost+2];
 					const int curve_precision = curve_type == gui_chart_t::STANDARD ? 0 : 2;
 					sint16 curve = i == 0
-					? chart.add_curve(  color_idx_to_rgb(cost_type_color[cost]), *chart_table_year,  MAX_PLAYER_COST_BUTTON, cost, MAX_PLAYER_HISTORY_YEARS,  curve_type, false, true, curve_precision)
-					: mchart.add_curve( color_idx_to_rgb(cost_type_color[cost]), *chart_table_month, MAX_PLAYER_COST_BUTTON, cost, MAX_PLAYER_HISTORY_MONTHS, curve_type, false, true, curve_precision);
+					? chart.add_curve(  g_simgraph->palette_lookup(cost_type_color[cost]), *chart_table_year,  MAX_PLAYER_COST_BUTTON, cost, MAX_PLAYER_HISTORY_YEARS,  curve_type, false, true, curve_precision)
+					: mchart.add_curve( g_simgraph->palette_lookup(cost_type_color[cost]), *chart_table_month, MAX_PLAYER_COST_BUTTON, cost, MAX_PLAYER_HISTORY_MONTHS, curve_type, false, true, curve_precision);
 					// add button
 					button_t *b;
 					if (i == 0) {
 						b = current->new_component<button_t>();
 						b->init(button_t::box_state_automatic | button_t::flexible, cost_type_name[cost]);
-						b->background_color = color_idx_to_rgb(cost_type_color[cost]);
+						b->background_color = g_simgraph->palette_lookup(cost_type_color[cost]);
 						b->pressed = false;
 						buttons[cost] = b;
 					}
diff --git a/src/simutrans/gui/obj_info.cc b/src/simutrans/gui/obj_info.cc
index c2ce4ce88..8aa14d590 100644
--- a/src/simutrans/gui/obj_info.cc
+++ b/src/simutrans/gui/obj_info.cc
@@ -13,7 +13,7 @@
 
 obj_infowin_t::obj_infowin_t(const obj_t* obj) :
 	base_infowin_t(translator::translate( obj->get_name() ), obj->get_owner()),
-	view(obj, scr_size( max(64, get_base_tile_raster_width()), max(56, (get_base_tile_raster_width()*7)/8) ))
+	view(obj, scr_size( max(64, g_simgraph->get_base_tile_raster_width()), max(56, (g_simgraph->get_base_tile_raster_width()*7)/8) ))
 {
 	fill_buffer();
 	//textarea.set_width( textarea.get_size().w + get_base_tile_raster_width() - 64);
diff --git a/src/simutrans/gui/player_frame.cc b/src/simutrans/gui/player_frame.cc
index e6aa76130..32cec2c20 100644
--- a/src/simutrans/gui/player_frame.cc
+++ b/src/simutrans/gui/player_frame.cc
@@ -68,7 +68,7 @@ ki_kontroll_t::ki_kontroll_t() :
 
 		// Prepare finances button
 		player_get_finances[i].init( button_t::box | button_t::flexible, "");
-		player_get_finances[i].background_color = PLAYER_FLAG | color_idx_to_rgb((player ? player->get_player_color1():i*8)+env_t::gui_player_color_bright);
+		player_get_finances[i].background_color = PLAYER_FLAG | g_simgraph->palette_lookup((player ? player->get_player_color1():i*8)+env_t::gui_player_color_bright);
 		player_get_finances[i].add_listener(this);
 
 		// Player type selector, Combobox
@@ -94,7 +94,7 @@ ki_kontroll_t::ki_kontroll_t() :
 
 		// password/locked button
 		player_lock[i] = new_component<password_button_t>();
-		player_lock[i]->background_color = color_idx_to_rgb((player && player->is_locked()) ? (player->is_unlock_pending() ? COL_YELLOW : COL_RED) : COL_GREEN);
+		player_lock[i]->background_color = g_simgraph->palette_lookup((player && player->is_locked()) ? (player->is_unlock_pending() ? COL_YELLOW : COL_RED) : COL_GREEN);
 		player_lock[i]->add_listener(this);
 		player_lock[i]->set_rigid(true);
 
@@ -289,8 +289,8 @@ void ki_kontroll_t::update_data()
 			}
 
 			// always update locking status
-			player_get_finances[i].background_color = PLAYER_FLAG | color_idx_to_rgb(player->get_player_color1()+env_t::gui_player_color_bright);
-			player_lock[i]->background_color = color_idx_to_rgb(player->is_locked() ? (player->is_unlock_pending() ? COL_YELLOW : COL_RED) : COL_GREEN);
+			player_get_finances[i].background_color = PLAYER_FLAG | g_simgraph->palette_lookup(player->get_player_color1()+env_t::gui_player_color_bright);
+			player_lock[i]->background_color = g_simgraph->palette_lookup(player->is_locked() ? (player->is_unlock_pending() ? COL_YELLOW : COL_RED) : COL_GREEN);
 
 			// human players cannot be deactivated
 			if (i>1) {
@@ -390,7 +390,7 @@ void ki_kontroll_t::draw(scr_coord pos, scr_size size)
 			player_active[i-2].pressed = player !=NULL	&&	player->is_active();
 		}
 
-		player_lock[i]->background_color = color_idx_to_rgb(player	&&	player->is_locked() ? (player->is_unlock_pending() ? COL_YELLOW : COL_RED) : COL_GREEN);
+		player_lock[i]->background_color = g_simgraph->palette_lookup(player	&&	player->is_locked() ? (player->is_unlock_pending() ? COL_YELLOW : COL_RED) : COL_GREEN);
 	}
 
 	player_change_to[welt->get_active_player_nr()].pressed = true;
diff --git a/src/simutrans/gui/player_ranking_frame.cc b/src/simutrans/gui/player_ranking_frame.cc
index b0d5af0b0..f16929af7 100644
--- a/src/simutrans/gui/player_ranking_frame.cc
+++ b/src/simutrans/gui/player_ranking_frame.cc
@@ -177,7 +177,7 @@ void player_button_t::update()
 	player_t* player = world()->get_player(player_nr);
 	if (player) {
 		set_text(player->get_name());
-		background_color = color_idx_to_rgb(player->get_player_color1() + env_t::gui_player_color_bright);
+		background_color = g_simgraph->palette_lookup(player->get_player_color1() + env_t::gui_player_color_bright);
 		enable();
 		set_visible(true);
 	}
@@ -246,7 +246,7 @@ player_ranking_frame_t::player_ranking_frame_t(uint8 selected_player_nr) :
 	{
 		for (uint8 i = 0; i < MAX_PLAYER_RANKING_CHARTS; i++) {
 			bt_charts[i].init(button_t::roundbox_state | button_t::flexible, cost_type_name[i]);
-			bt_charts[i].background_color = color_idx_to_rgb(cost_type_color[i]);
+			bt_charts[i].background_color = g_simgraph->palette_lookup(cost_type_color[i]);
 			if (i == selected_item) bt_charts[i].pressed = true;
 			bt_charts[i].add_listener(this);
 			add_component(&bt_charts[i]);
@@ -404,7 +404,7 @@ void player_ranking_frame_t::update_chart(bool full_update)
 			switch (count)
 			{
 			case 1:
-				cont_players.new_component<gui_label_t>("1", color_idx_to_rgb(COL_YELLOW), gui_label_t::centered);
+				cont_players.new_component<gui_label_t>("1", g_simgraph->palette_lookup(COL_YELLOW), gui_label_t::centered);
 				break;
 			case 2:
 				cont_players.new_component<gui_label_t>("2", 0, gui_label_t::centered);
@@ -446,7 +446,7 @@ void player_ranking_frame_t::update_chart(bool full_update)
 				const int curve_type = (int)cost_type[selected_item];
 				const int curve_precision = (curve_type == gui_chart_t::STANDARD) ? 0 : (curve_type == gui_chart_t::MONEY || curve_type == gui_chart_t::PERCENT) ? 2 : 1;
 				//			gui_chart_t::chart_marker_t marker = (np==selected_player) ? gui_chart_t::square : gui_chart_t::none;
-				chart.add_curve(color_idx_to_rgb(player->get_player_color1() + 3), *p_chart_table, MAX_PLAYER_COUNT - 1, np, chart_years_back, curve_type, true, false, curve_precision, NULL);
+				chart.add_curve(g_simgraph->palette_lookup(player->get_player_color1() + 3), *p_chart_table, MAX_PLAYER_COUNT - 1, np, chart_years_back, curve_type, true, false, curve_precision, NULL);
 			}
 		}
 
diff --git a/src/simutrans/gui/savegame_frame.cc b/src/simutrans/gui/savegame_frame.cc
index 365aa83c0..00bb8b840 100644
--- a/src/simutrans/gui/savegame_frame.cc
+++ b/src/simutrans/gui/savegame_frame.cc
@@ -31,7 +31,7 @@ public:
 	del_button_t() : button_t()
 	{
 		init(button_t::roundbox, "X");
-		w = max(D_BUTTON_HEIGHT, display_get_char_width('X') + D_BUTTON_PADDINGS_X);
+		w = max(D_BUTTON_HEIGHT, g_simgraph->get_char_width('X') + D_BUTTON_PADDINGS_X);
 	}
 	scr_size get_min_size() const OVERRIDE
 	{
diff --git a/src/simutrans/gui/scenario_info.cc b/src/simutrans/gui/scenario_info.cc
index 14526a963..0b410f537 100644
--- a/src/simutrans/gui/scenario_info.cc
+++ b/src/simutrans/gui/scenario_info.cc
@@ -84,7 +84,8 @@ scenario_info_t::scenario_info_t() :
 	}
 
 	set_resizemode(diagonal_resize);
-	scr_size ms(min(display_get_width() / 2, 500), min(display_get_height() / 2, 300));
+	const scr_size screen = g_simgraph->get_screen_size();
+	scr_size ms(min(screen.w / 2, 500), min(screen.h / 2, 300));
 	set_min_windowsize(ms);
 	set_windowsize(ms);
 }
diff --git a/src/simutrans/gui/schedule_list.cc b/src/simutrans/gui/schedule_list.cc
index 165cb0b3f..bfa075a99 100644
--- a/src/simutrans/gui/schedule_list.cc
+++ b/src/simutrans/gui/schedule_list.cc
@@ -234,9 +234,11 @@ bool schedule_list_gui_t::action_triggered( gui_action_creator_t *comp, value_t
 			// try to open to the right
 			scr_coord sc = win_get_pos( this );
 			scr_coord lc = sc;
+			const scr_size screen = g_simgraph->get_screen_size();
+
 			lc.x += get_windowsize().w;
-			if( lc.x > display_get_width() ) {
-				lc.x = max( 0, display_get_width() - 100 );
+			if( lc.x > screen.w ) {
+				lc.x = max( 0, screen.w - 100 );
 			}
 			if(  line_info  ) {
 				// close if open
diff --git a/src/simutrans/gui/server_frame.cc b/src/simutrans/gui/server_frame.cc
index 7fc587eed..9682a406a 100644
--- a/src/simutrans/gui/server_frame.cc
+++ b/src/simutrans/gui/server_frame.cc
@@ -44,8 +44,8 @@ public:
 			scr_coord p = get_pos() + offset;
 			scr_size mapsize( gi->get_map()->get_width(), gi->get_map()->get_height() );
 			// 3D border around the map graphic
-			display_ddd_box_clip_rgb(p.x, p.y, mapsize.w + 2, mapsize.h + 2, color_idx_to_rgb(MN_GREY0), color_idx_to_rgb(MN_GREY4) );
-			display_array_wh( p.x + 1, p.y + 1, mapsize.w, mapsize.h, gi->get_map()->to_array() );
+			g_simgraph->draw_box3d_clipped(p.x, p.y, mapsize.w + 2, mapsize.h + 2, g_simgraph->palette_lookup(MN_GREY0), g_simgraph->palette_lookup(MN_GREY4) );
+			g_simgraph->draw_array( p.x + 1, p.y + 1, mapsize.w, mapsize.h, gi->get_map()->to_array() );
 		}
 	}
 
@@ -417,7 +417,8 @@ bool server_frame_t::action_triggered (gui_action_creator_t *comp, value_t p)
 			join.disable();
 			server_scrollitem_t *item = (server_scrollitem_t*)serverlist.get_element( p.i );
 			if(  item->online()  ) {
-				display_show_load_pointer(1);
+				g_simgraph->set_show_load_cursor(true);
+
 				const char *err = network_gameinfo( ((server_scrollitem_t*)serverlist.get_element( p.i ))->get_dns(), &gi );
 				if(  err  &&  *((server_scrollitem_t*)serverlist.get_element(p.i))->get_altdns()  ) {
 					item->set_color(MONEY_MINUS);
@@ -431,7 +432,7 @@ bool server_frame_t::action_triggered (gui_action_creator_t *comp, value_t p)
 					item->set_color( MONEY_MINUS );
 					update_error( err );
 				}
-				display_show_load_pointer(0);
+				g_simgraph->set_show_load_cursor(false);
 			}
 			else {
 				item->set_color( MONEY_MINUS );
@@ -445,7 +446,7 @@ bool server_frame_t::action_triggered (gui_action_creator_t *comp, value_t p)
 
 			dbg->warning("action_triggered()", "newserver_name: %s", newserver_name);
 
-			display_show_load_pointer(1);
+			g_simgraph->set_show_load_cursor(true);
 			const char *err = network_gameinfo( newserver_name, &gi );
 			if (  err == NULL  ) {
 				custom_valid = true;
@@ -456,7 +457,7 @@ bool server_frame_t::action_triggered (gui_action_creator_t *comp, value_t p)
 				join.disable();
 				update_error( "Server did not respond!" );
 			}
-			display_show_load_pointer(0);
+			g_simgraph->set_show_load_cursor(false);
 			serverlist.set_selection( -1 );
 		}
 	}
@@ -495,21 +496,21 @@ bool server_frame_t::action_triggered (gui_action_creator_t *comp, value_t p)
 
 		// Prefer serverlist entry if one is selected
 		if (  serverlist.get_selection() >= 0  ) {
-			display_show_load_pointer(1);
+			g_simgraph->set_show_load_cursor(true);
 			filename += ((server_scrollitem_t*)serverlist.get_selected_item())->get_dns();
 			destroy_win( this );
 			welt->load( filename.c_str() );
 			welt->type_of_generation = karte_t::CLIENT_WORLD;
-			display_show_load_pointer(0);
+			g_simgraph->set_show_load_cursor(false);
 		}
 		// If we have a valid custom server entry, connect to that
 		else if (  custom_valid  ) {
-			display_show_load_pointer(1);
+			g_simgraph->set_show_load_cursor(true);
 			filename += newserver_name;
 			destroy_win( this );
 			welt->load( filename.c_str() );
 			welt->type_of_generation = karte_t::CLIENT_WORLD;
-			display_show_load_pointer(0);
+			g_simgraph->set_show_load_cursor(false);
 		}
 		else {
 			dbg->error( "server_frame_t::action_triggered()", "join pressed without valid selection or custom server entry" );
diff --git a/src/simutrans/gui/settings_frame.cc b/src/simutrans/gui/settings_frame.cc
index 8a8800f59..3298d1b02 100644
--- a/src/simutrans/gui/settings_frame.cc
+++ b/src/simutrans/gui/settings_frame.cc
@@ -176,7 +176,7 @@ bool settings_frame_t::infowin_event(const event_t *ev)
 		climates.read( sets );
 
 		// only the rgb colours have been changed, the colours in system format must be updated
-		env_t_rgb_to_system_colors();
+		g_simgraph->env_t_rgb_to_system_colors();
 	}
 	return gui_frame_t::infowin_event(ev);
 }
diff --git a/src/simutrans/gui/simwin.cc b/src/simutrans/gui/simwin.cc
index 6a5161dc3..c82e6e1a5 100644
--- a/src/simutrans/gui/simwin.cc
+++ b/src/simutrans/gui/simwin.cc
@@ -185,14 +185,14 @@ static int display_gadget_box(sint8 code,
 
 	if(pushed) {
 		// mark_rect_dirty_wc(x, y, D_GADGET_WIDTH, D_TITLEBAR_HEIGHT);
-		display_fillbox_wh_clip_rgb(x, y, D_GADGET_WIDTH, D_TITLEBAR_HEIGHT, lighter, false);
+		g_simgraph->draw_rect_clipped(x, y, D_GADGET_WIDTH, D_TITLEBAR_HEIGHT, lighter, false CLIP_NUM_DEFAULT);
 	}
 
 	// Do we have a gadget image?
 	if(  img != NULL  ) {
 
 		// Max Kielland: This center the gadget image and compensates for any left/top margins within the image to be backward compatible with older PAK sets.
-		display_img_aligned(img->imageid, scr_rect(x, y, D_GADGET_WIDTH, D_TITLEBAR_HEIGHT), ALIGN_CENTER_H | ALIGN_CENTER_V, false);
+		g_simgraph->draw_img_aligned(img->imageid, scr_rect(x, y, D_GADGET_WIDTH, D_TITLEBAR_HEIGHT), ALIGN_CENTER_H | ALIGN_CENTER_V, false);
 
 	}
 	else {
@@ -211,12 +211,12 @@ static int display_gadget_box(sint8 code,
 		else if(  code == SKIN_GADGET_PINNED  ) {
 			gadget_text = "S";
 		}
-		display_proportional_rgb( x+4, y+4, gadget_text, ALIGN_LEFT, SYSCOL_TEXT, false );
+		g_simgraph->draw_text( x+4, y+4, gadget_text, ALIGN_LEFT, SYSCOL_TEXT, false );
 	}
 
 	int side = x+REVERSE_GADGETS*D_GADGET_WIDTH-1;
-	display_vline_wh_clip_rgb(side+1, y+1, D_TITLEBAR_HEIGHT-2, lighter, false);
-	display_vline_wh_clip_rgb(side,   y+1, D_TITLEBAR_HEIGHT-2, darker,  false);
+	g_simgraph->draw_vline_clipped(side+1, y+1, D_TITLEBAR_HEIGHT-2, lighter, false CLIP_NUM_DEFAULT);
+	g_simgraph->draw_vline_clipped(side,   y+1, D_TITLEBAR_HEIGHT-2, darker,  false CLIP_NUM_DEFAULT);
 
 	// return width of gadget
 	return D_GADGET_WIDTH;
@@ -331,25 +331,25 @@ static void win_draw_window_title(const scr_coord pos, const scr_size size,
 {
 	PUSH_CLIP_FIT(pos.x, pos.y, size.w, size.h);
 
-	PIXVAL lighter = display_blend_colors(title_color, color_idx_to_rgb(COL_WHITE), 25);
-	PIXVAL darker  = display_blend_colors(title_color, color_idx_to_rgb(COL_BLACK), 25);
+	PIXVAL lighter = g_simgraph->blend_colors(title_color, g_simgraph->palette_lookup(COL_WHITE), 25);
+	PIXVAL darker  = g_simgraph->blend_colors(title_color, g_simgraph->palette_lookup(COL_BLACK), 25);
 
 	// fill title bar with color
-	display_fillbox_wh_clip_rgb(pos.x, pos.y, size.w, D_TITLEBAR_HEIGHT, title_color, true);
+	g_simgraph->draw_rect_clipped(pos.x, pos.y, size.w, D_TITLEBAR_HEIGHT, title_color, true CLIP_NUM_DEFAULT);
 
 	// border of title bar
-	display_fillbox_wh_clip_rgb( pos.x + 1, pos.y,                         size.w - 2, 1, lighter, false ); // top
-	display_fillbox_wh_clip_rgb( pos.x + 1, pos.y + D_TITLEBAR_HEIGHT - 1, size.w - 2, 1, darker,  false ); // bottom
+	g_simgraph->draw_rect_clipped( pos.x + 1, pos.y,                         size.w - 2, 1, lighter, false CLIP_NUM_DEFAULT); // top
+	g_simgraph->draw_rect_clipped( pos.x + 1, pos.y + D_TITLEBAR_HEIGHT - 1, size.w - 2, 1, darker,  false CLIP_NUM_DEFAULT); // bottom
 
-	display_vline_wh_clip_rgb( pos.x,              pos.y, D_TITLEBAR_HEIGHT, lighter, false ); // left
-	display_vline_wh_clip_rgb( pos.x + size.w - 1, pos.y, D_TITLEBAR_HEIGHT, darker,  false ); // right
+	g_simgraph->draw_vline_clipped( pos.x,              pos.y, D_TITLEBAR_HEIGHT, lighter, false CLIP_NUM_DEFAULT); // left
+	g_simgraph->draw_vline_clipped( pos.x + size.w - 1, pos.y, D_TITLEBAR_HEIGHT, darker,  false CLIP_NUM_DEFAULT); // right
 
 	// Draw the gadgets and then move left and draw text.
 	flags.gotopos = (welt_pos != koord3d::invalid);
 	int width = display_gadget_boxes( &flags, pos.x+(REVERSE_GADGETS?0:size.w-D_GADGET_WIDTH), pos.y, lighter, darker, gadget_state, sticky, goto_pushed );
-	int titlewidth = display_proportional_clip_rgb( pos.x + (REVERSE_GADGETS?width+4:4), pos.y+(D_TITLEBAR_HEIGHT-LINEASCENT)/2, text, ALIGN_LEFT, text_color, false );
+	int titlewidth = g_simgraph->draw_text_clipped( pos.x + (REVERSE_GADGETS?width+4:4), pos.y+(D_TITLEBAR_HEIGHT-LINEASCENT)/2, text, ALIGN_LEFT, text_color, false );
 	if(  flags.gotopos  ) {
-		display_proportional_clip_rgb( pos.x + (REVERSE_GADGETS?width+4:4)+titlewidth+8, pos.y+(D_TITLEBAR_HEIGHT-LINEASCENT)/2, welt_pos.get_fullstr(), ALIGN_LEFT, text_color, false );
+		g_simgraph->draw_text_clipped( pos.x + (REVERSE_GADGETS?width+4:4)+titlewidth+8, pos.y+(D_TITLEBAR_HEIGHT-LINEASCENT)/2, welt_pos.get_fullstr(), ALIGN_LEFT, text_color, false );
 	}
 	POP_CLIP();
 }
@@ -365,12 +365,12 @@ static void win_draw_window_dragger(scr_coord pos, scr_size size)
 	pos += size;
 	if(  skinverwaltung_t::gadget  &&  skinverwaltung_t::gadget->get_image_id(SKIN_WINDOW_RESIZE)!=IMG_EMPTY  ) {
 		const image_t *dragger = skinverwaltung_t::gadget->get_image(SKIN_WINDOW_RESIZE);
-		display_color_img( dragger->get_id(), pos.x-dragger->get_pic()->w, pos.y-dragger->get_pic()->h, 0, false, false);
+		g_simgraph->draw_color_img( dragger->get_id(), pos.x-dragger->get_pic()->w, pos.y-dragger->get_pic()->h, 0, false, false CLIP_NUM_DEFAULT);
 	}
 	else {
 		int dragger_size = min(D_DRAGGER_WIDTH, D_DRAGGER_HEIGHT);
 		for(  int x=1;  x<dragger_size;  x++  ) {
-			display_fillbox_wh_clip_rgb( pos.x-x, pos.y-dragger_size+x, x, 1, color_idx_to_rgb((x & 1) ? COL_BLACK : MN_GREY4), true);
+			g_simgraph->draw_rect_clipped( pos.x-x, pos.y-dragger_size+x, x, 1, g_simgraph->palette_lookup((x & 1) ? COL_BLACK : MN_GREY4), true CLIP_NUM_DEFAULT);
 		}
 	}
 }
@@ -685,9 +685,14 @@ void rdwr_all_win(loadsave_t *file)
 
 scr_rect win_get_max_window_area()
 {
+	const scr_size screen = g_simgraph->get_screen_size();
+
 	scr_coord other_pos((env_t::menupos == MENU_LEFT) * env_t::iconsize.w, (env_t::menupos == MENU_TOP) * env_t::iconsize.h + (env_t::menupos == MENU_BOTTOM) * win_get_statusbar_height());
-	scr_size other_size(display_get_width() - other_pos.x - (env_t::menupos == MENU_RIGHT) * env_t::iconsize.w,
-		display_get_height() - win_get_statusbar_height() - env_t::iconsize.h);
+	scr_size other_size{
+		screen.w - other_pos.x - (env_t::menupos == MENU_RIGHT) * env_t::iconsize.w,
+		screen.h - win_get_statusbar_height() - env_t::iconsize.h
+	};
+
 	if (show_ticker) {
 		other_size.h -= TICKER_HEIGHT;
 		if (env_t::menupos == MENU_BOTTOM) {
@@ -823,7 +828,7 @@ int create_win(scr_coord pos, gui_frame_t *const gui, wintype const wt, ptrdiff_
 		if (!wins.empty()) {
 			// mark old dirty
 			const scr_size size = wins.back().gui->get_windowsize();
-			mark_rect_dirty_wc( wins.back().pos.x - 1, wins.back().pos.y - 1, wins.back().pos.x + size.w + 2, wins.back().pos.y + size.h + 2 + D_TITLEBAR_HEIGHT ); // -1, +2 for env_t::window_frame_active
+			g_simgraph->mark_rect_dirty_wc( wins.back().pos.x - 1, wins.back().pos.y - 1, wins.back().pos.x + size.w + 2, wins.back().pos.y + size.h + 2 + D_TITLEBAR_HEIGHT ); // -1, +2 for env_t::window_frame_active
 		}
 
 		wins.append( simwin_t() );
@@ -876,7 +881,8 @@ int create_win(scr_coord pos, gui_frame_t *const gui, wintype const wt, ptrdiff_
 		// use default width
 		stored.clip_lefttop(scr_size(D_DEFAULT_WIDTH, D_DEFAULT_HEIGHT));
 		// clip to display size
-		stored.clip_rightbottom( scr_size(display_get_width(), display_get_height() - env_t::iconsize.h - win_get_statusbar_height() ) );
+		const scr_size screen = g_simgraph->get_screen_size();
+		stored.clip_rightbottom( scr_size(screen.w, screen.h - env_t::iconsize.h - win_get_statusbar_height() ) );
 
 		if (stored != gui->get_windowsize()) {
 			// send tailored resize event
@@ -895,7 +901,7 @@ int create_win(scr_coord pos, gui_frame_t *const gui, wintype const wt, ptrdiff_
 		// try to go next to mouse bar
 		if (pos.x == -1) {
 			pos.x = get_mouse_pos().x - gui->get_windowsize().w / 2;
-			pos.y = get_mouse_pos().y - gui->get_windowsize().h - get_tile_raster_width()/4;
+			pos.y = get_mouse_pos().y - gui->get_windowsize().h - g_simgraph->get_tile_raster_width()/4;
 		}
 
 		// make sure window is on screen
@@ -918,7 +924,7 @@ static int notify_top_win()
 {
 	// mark new dirty
 	scr_size size = wins.back().gui->get_windowsize();
-	mark_rect_dirty_wc( wins.back().pos.x - 1, wins.back().pos.y - 1, wins.back().pos.x + size.w + 2, wins.back().pos.y + size.h + 2 ); // -1, +2 for env_t::window_frame_active
+	g_simgraph->mark_rect_dirty_wc( wins.back().pos.x - 1, wins.back().pos.y - 1, wins.back().pos.x + size.w + 2, wins.back().pos.y + size.h + 2 ); // -1, +2 for env_t::window_frame_active
 
 	event_t ev;
 
@@ -948,7 +954,7 @@ int top_win(int win, bool keep_state )
 
 	// mark old dirty
 	scr_size size = wins.back().gui->get_windowsize();
-	mark_rect_dirty_wc( wins.back().pos.x - 1, wins.back().pos.y - 1, wins.back().pos.x + size.w + 2, wins.back().pos.y + size.h + 2 ); // -1, +2 for env_t::window_frame_active
+	g_simgraph->mark_rect_dirty_wc( wins.back().pos.x - 1, wins.back().pos.y - 1, wins.back().pos.x + size.w + 2, wins.back().pos.y + size.h + 2 ); // -1, +2 for env_t::window_frame_active
 	wins.back().dirty = true;
 
 	simwin_t tmp = wins[win];
@@ -1006,7 +1012,7 @@ static bool destroy_framed_win(simwin_t *wins)
 
 	// mark dirty
 	const scr_size size = wins->gui->get_windowsize();
-	mark_rect_dirty_wc( wins->pos.x - 1, wins->pos.y - 1, wins->pos.x + size.w + 2, wins->pos.y + size.h + 2 ); // -1, +2 for env_t::window_frame_active
+	g_simgraph->mark_rect_dirty_wc( wins->pos.x - 1, wins->pos.y - 1, wins->pos.x + size.w + 2, wins->pos.y + size.h + 2 ); // -1, +2 for env_t::window_frame_active
 
 	// save windowsize for later
 	save_windowsize(wins);
@@ -1123,7 +1129,7 @@ void rollup_all_win()
 			wins[curWin].rollup = true;
 			gui_frame_t *gui = wins[curWin].gui;
 			scr_size size = gui->get_windowsize();
-			mark_rect_dirty_wc( wins[curWin].pos.x, wins[curWin].pos.y, wins[curWin].pos.x+size.w, wins[curWin].pos.y+size.h );
+			g_simgraph->mark_rect_dirty_wc( wins[curWin].pos.x, wins[curWin].pos.y, wins[curWin].pos.x+size.w, wins[curWin].pos.y+size.h );
 			all_rolldown_flag = false;
 		}
 	}
@@ -1143,7 +1149,7 @@ void rolldown_all_win()
 		wins[curWin].rollup = false;
 		gui_frame_t *gui = wins[curWin].gui;
 		scr_size size = gui->get_windowsize();
-		mark_rect_dirty_wc( wins[curWin].pos.x, wins[curWin].pos.y, wins[curWin].pos.x+size.w, wins[curWin].pos.y+size.h );
+		g_simgraph->mark_rect_dirty_wc( wins[curWin].pos.x, wins[curWin].pos.y, wins[curWin].pos.x+size.w, wins[curWin].pos.y+size.h );
 	}
 }
 
@@ -1160,7 +1166,7 @@ void display_win(int win)
 	FLAGGED_PIXVAL text_color = env_t::front_window_text_color;
 	if(  (unsigned)win!=wins.get_count()-1  ) {
 		// not top => darker
-		title_color = display_blend_colors(title_color, color_idx_to_rgb(COL_BLACK), env_t::bottom_window_darkness);
+		title_color = g_simgraph->blend_colors(title_color, g_simgraph->palette_lookup(COL_BLACK), env_t::bottom_window_darkness);
 		text_color = env_t::bottom_window_text_color;
 	}
 	bool need_dragger = comp->get_resizemode() != gui_frame_t::no_resize;
@@ -1181,16 +1187,16 @@ void display_win(int win)
 	}
 	if(  wins[win].dirty  ) {
 		// not sure this is still a useful call
-		mark_rect_dirty_wc( wins[win].pos.x, wins[win].pos.y, wins[win].pos.x+size.w+1, wins[win].pos.y+2 );
+		g_simgraph->mark_rect_dirty_wc( wins[win].pos.x, wins[win].pos.y, wins[win].pos.x+size.w+1, wins[win].pos.y+2 );
 		wins[win].dirty = false;
 	}
 	// mark top window, if requested
 	if(env_t::window_frame_active  &&  (unsigned)win==wins.get_count()-1) {
 		if(!wins[win].rollup) {
-			display_ddd_box_clip_rgb( wins[win].pos.x-1, wins[win].pos.y-1, size.w+2, size.h+2, title_color, title_color);
+			g_simgraph->draw_box3d_clipped( wins[win].pos.x-1, wins[win].pos.y-1, size.w+2, size.h+2, title_color, title_color);
 		}
 		else {
-			display_ddd_box_clip_rgb( wins[win].pos.x-1, wins[win].pos.y-1, size.w+2, D_TITLEBAR_HEIGHT + 2, title_color, title_color);
+			g_simgraph->draw_box3d_clipped( wins[win].pos.x-1, wins[win].pos.y-1, size.w+2, D_TITLEBAR_HEIGHT + 2, title_color, title_color);
 		}
 	}
 	if(!wins[win].rollup) {
@@ -1289,10 +1295,12 @@ static void snap_check_win( const int win, scr_coord *r, const scr_coord from_po
 
 		if(  i==wins_count  ) {
 			// Allow snap to screen edge
+			const scr_size screen = g_simgraph->get_screen_size();
+
 			other_pos.x = (env_t::menupos==MENU_LEFT)*env_t::iconsize.w;
 			other_pos.y = (env_t::menupos==MENU_TOP)*env_t::iconsize.h + (env_t::menupos==MENU_BOTTOM)*win_get_statusbar_height();
-			other_size.x = display_get_width() - other_pos.x - (env_t::menupos==MENU_RIGHT)*env_t::iconsize.w;
-			other_size.y = display_get_height()-win_get_statusbar_height()-env_t::iconsize.h;
+			other_size.x = screen.w - other_pos.x - (env_t::menupos==MENU_RIGHT)*env_t::iconsize.w;
+			other_size.y = screen.h - win_get_statusbar_height()-env_t::iconsize.h;
 			if(  show_ticker  ) {
 				other_size.y -= TICKER_HEIGHT;
 			}
@@ -1399,7 +1407,7 @@ static void move_win(int win, event_t *ev)
 
 	wins[win].pos += delta;
 	// need to mark all of old and new positions dirty. -1, +2 for env_t::window_frame_active
-	mark_rect_dirty_wc( from_pos.x - 1, from_pos.y - 1, from_pos.x + from_size.x + 2, from_pos.y + from_size.y + 2 );
+	g_simgraph->mark_rect_dirty_wc( from_pos.x - 1, from_pos.y - 1, from_pos.x + from_size.x + 2, from_pos.y + from_size.y + 2 );
 	wins[win].dirty = true;
 
 	// set dirty flag to refill background
@@ -1431,7 +1439,7 @@ static void resize_win(int win, event_t *ev)
 	}
 
 	// since we may be smaller afterwards
-	mark_rect_dirty_wc( from_pos.x - 1, from_pos.y - 1, from_pos.x + from_size.x + 2, from_pos.y + from_size.y + 2 ); // -1, +2 for env_t::window_frame_active
+	g_simgraph->mark_rect_dirty_wc( from_pos.x - 1, from_pos.y - 1, from_pos.x + from_size.x + 2, from_pos.y + from_size.y + 2 ); // -1, +2 for env_t::window_frame_active
 	// set dirty flag to refill background
 	if(wl) {
 		wl->set_background_dirty();
@@ -1545,7 +1553,9 @@ bool check_pos_win(event_t *ev,bool modal)
 	}
 
 	// click in main menu?
-	scr_coord menuoffset((env_t::menupos == MENU_RIGHT) * (display_get_width() - env_t::iconsize.w), (env_t::menupos == MENU_BOTTOM) * (display_get_height() - env_t::iconsize.h) - D_TITLEBAR_HEIGHT);
+	const scr_size screen = g_simgraph->get_screen_size();
+	scr_coord menuoffset((env_t::menupos == MENU_RIGHT) * (screen.w - env_t::iconsize.w), (env_t::menupos == MENU_BOTTOM) * (screen.h - env_t::iconsize.h) - D_TITLEBAR_HEIGHT);
+
 	if (!tool_t::toolbar_tool.empty()  &&
 		tool_t::toolbar_tool[0]->get_tool_selector()  &&
 		(is_dragging  ||  tool_t::toolbar_tool[0]->get_tool_selector()->is_hit(x-menuoffset.x, y-menuoffset.y))  &&
@@ -1568,13 +1578,13 @@ bool check_pos_win(event_t *ev,bool modal)
 			if (my < env_t::iconsize.h) {
 				new_pos = 1 << MENU_TOP;
 			}
-			if (my > display_get_height()- env_t::iconsize.h) {
+			if (my > screen.h- env_t::iconsize.h) {
 				new_pos |= 1 << MENU_BOTTOM;
 			}
 			if (mx < env_t::iconsize.w) {
 				new_pos |= 1 << MENU_LEFT;
 			}
-			if (mx > display_get_width() - env_t::iconsize.w) {
+			if (mx > screen.w - env_t::iconsize.w) {
 				new_pos |= 1 << MENU_RIGHT;
 			}
 			if (new_pos  &&  new_pos!=(1<<env_t::menupos)) {
@@ -1635,13 +1645,13 @@ bool check_pos_win(event_t *ev,bool modal)
 	}
 
 	// swallow all other events in the infobar
-	if(  !(ev->ev_class == EVENT_KEYBOARD  ||  ev->ev_class == EVENT_STRING)  &&  y > display_get_height()- win_get_statusbar_height()  ) {
+	if(  !(ev->ev_class == EVENT_KEYBOARD  ||  ev->ev_class == EVENT_STRING)  &&  y > screen.h- win_get_statusbar_height()  ) {
 		// swallow event
 		return true;
 	}
 
 	// swallow all other events in ticker (if there)
-	if(  !(ev->ev_class == EVENT_KEYBOARD  ||  ev->ev_class == EVENT_STRING)  &&  show_ticker  &&  y > display_get_height()- win_get_statusbar_height() - TICKER_HEIGHT  ) {
+	if(  !(ev->ev_class == EVENT_KEYBOARD  ||  ev->ev_class == EVENT_STRING)  &&  show_ticker  &&  y > screen.h - win_get_statusbar_height() - TICKER_HEIGHT  ) {
 		if(  IS_LEFTCLICK(ev)  ) {
 			ticker::process_click(x);
 		}
@@ -1736,7 +1746,7 @@ bool check_pos_win(event_t *ev,bool modal)
 						wins[i].rollup ^= 1;
 						gui_frame_t *gui = wins[i].gui;
 						scr_size size = gui->get_windowsize();
-						mark_rect_dirty_wc( wins[i].pos.x, wins[i].pos.y, wins[i].pos.x+size.w, wins[i].pos.y+size.h );
+						g_simgraph->mark_rect_dirty_wc( wins[i].pos.x, wins[i].pos.y, wins[i].pos.x+size.w, wins[i].pos.y+size.h );
 						if(  wins[i].rollup  ) {
 							wl->set_background_dirty();
 						}
@@ -1792,19 +1802,26 @@ void win_poll_event(event_t* const ev)
 	// main window resized
 	if(  ev->ev_class==EVENT_SYSTEM  &&  ev->ev_code==SYSTEM_RESIZE  ) {
 		// main window resized
-		simgraph_resize( ev->new_window_size );
-		gui_theme_t::gui_buttons_per_row = max(2, min(4, display_get_width() / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
+		g_simgraph->on_window_resized( ev->new_window_size );
+
+		const scr_size screen = g_simgraph->get_screen_size();
+
+		gui_theme_t::gui_buttons_per_row = max(2, min(4, screen.w / (D_BUTTON_WIDTH + D_H_SPACE + D_MARGIN_LEFT)));
 		ticker::redraw();
 		tool_t::update_toolbars();
+
 		for( uint i = 0; i<wins.get_count(); i++ ) {
 			win_clamp_xywh_position(wins[i].gui, wins[i].pos, wins[i].gui->get_min_windowsize(), true );
 		}
+
 		wl->set_dirty();
 		wl->get_viewport()->metrics_updated();
 		ev->ev_class = IGNORE_EVENT;
+
 		// now see how much of the status text fits the display
-		scr_coord_val time_width = proportional_string_width(tick_to_string(wl->get_ticks()));
-		scr_coord_val player_width = proportional_string_width(wl->get_active_player()->get_name());
+		scr_coord_val time_width = g_simgraph->calc_text_width(tick_to_string(wl->get_ticks()));
+		scr_coord_val player_width = g_simgraph->calc_text_width(wl->get_active_player()->get_name());
+
 		char buffer[128];
 		if (env_t::player_finance_display_account) {
 			money_to_string(buffer, (double)world()->get_active_player()->get_finance()->get_account_balance() / 100.0);
@@ -1812,8 +1829,10 @@ void win_poll_event(event_t* const ev)
 		else {
 			money_to_string(buffer, (double)world()->get_active_player()->get_finance()->get_netwealth() / 100.0);
 		}
-		scr_coord_val money_width = proportional_string_width(buffer);
-		scr_coord_val position_width = proportional_string_width(wl->get_zeiger()->get_pos().get_str());
+
+		scr_coord_val money_width = g_simgraph->calc_text_width(buffer);
+		scr_coord_val position_width = g_simgraph->calc_text_width(wl->get_zeiger()->get_pos().get_str());
+
 		// if too long shorten radically
 		status_show_compact = (time_width + player_width + money_width + position_width) * 1.2 > ev->new_window_size.w;
 	}
@@ -1857,49 +1876,57 @@ uint16 win_get_statusbar_height()
 // finally updates the display
 void win_display_flush(double konto)
 {
-	const sint16 disp_width = display_get_width();
-	const sint16 disp_height = display_get_height();
+	const scr_size screen = g_simgraph->get_screen_size();
 
 	// display main menu
 	tool_selector_t *main_menu = tool_t::toolbar_tool[0]->get_tool_selector();
 	scr_coord menu_pos(0,0);
-	scr_size menu_size(disp_width, env_t::iconsize.h);
-	scr_rect clip_rr(0, env_t::iconsize.h, disp_width, disp_height - env_t::iconsize.h);
+	scr_size menu_size(screen.w, env_t::iconsize.h);
+	scr_rect clip_rr(0, env_t::iconsize.h, screen.w, screen.h - env_t::iconsize.h);
+
 	switch (env_t::menupos) {
 		case MENU_TOP:
 			// pos default (see above)
 			// size default
 			// rect default
 			break;
+
 		case MENU_BOTTOM:
-			menu_pos = scr_coord(0, disp_height - env_t::iconsize.h);
+			menu_pos = scr_coord(0, screen.h - env_t::iconsize.h);
 			// size default
 			clip_rr.y = 0;
 			break;
+
 		case MENU_LEFT:
 			// pos default (see above)
-			menu_size = scr_size(env_t::iconsize.w, disp_height-win_get_statusbar_height()-show_ticker*TICKER_HEIGHT);
-			clip_rr = scr_rect(env_t::iconsize.h, 0, disp_width - env_t::iconsize.w, disp_height);
+			menu_size = scr_size(env_t::iconsize.w, screen.h - win_get_statusbar_height()-show_ticker*TICKER_HEIGHT);
+			clip_rr = scr_rect(env_t::iconsize.h, 0, screen.w - env_t::iconsize.w, screen.h);
 			break;
+
 		case MENU_RIGHT:
-			menu_pos.x = disp_width - env_t::iconsize.w;
-			menu_size = scr_size(env_t::iconsize.w, disp_height - win_get_statusbar_height()-show_ticker*TICKER_HEIGHT );
-			clip_rr = scr_rect(0, 0, disp_width - env_t::iconsize.w, disp_height);
+			menu_pos.x = screen.h - env_t::iconsize.w;
+			menu_size = scr_size(env_t::iconsize.w, screen.h - win_get_statusbar_height()-show_ticker*TICKER_HEIGHT );
+			clip_rr = scr_rect(0, 0, screen.w - env_t::iconsize.w, screen.h);
 			break;
 	}
 
-	display_set_clip_wh( menu_pos.x, menu_pos.y, menu_size.w, menu_size.h );
+	g_simgraph->set_clip_rect( menu_pos.x, menu_pos.y, menu_size.w, menu_size.h CLIP_NUM_DEFAULT, false);
 
 	if(  skinverwaltung_t::toolbar_background  &&  skinverwaltung_t::toolbar_background->get_image_id(0) != IMG_EMPTY  ) {
 		const image_id back_img = skinverwaltung_t::toolbar_background->get_image_id(0);
-		display_fit_img_to_width( back_img, env_t::iconsize.w );
+		g_simgraph->fit_img_to_width( back_img, env_t::iconsize.w );
 
-		stretch_map_t imag = { {IMG_EMPTY, IMG_EMPTY, IMG_EMPTY}, {IMG_EMPTY, back_img, IMG_EMPTY}, {IMG_EMPTY, IMG_EMPTY, IMG_EMPTY} };
-		display_img_stretch(imag, scr_rect(menu_pos, menu_size));
+		stretch_map_t imag = {
+			{ IMG_EMPTY, IMG_EMPTY, IMG_EMPTY },
+			{ IMG_EMPTY, back_img,  IMG_EMPTY },
+			{ IMG_EMPTY, IMG_EMPTY, IMG_EMPTY }
+		};
+		g_simgraph->draw_stretch_map(imag, scr_rect(menu_pos, menu_size));
 	}
 	else {
-		display_fillbox_wh_rgb( menu_pos.x, menu_pos.y, menu_size.w, menu_size.h, color_idx_to_rgb(MN_GREY2), false );
+		g_simgraph->draw_rect( menu_pos.x, menu_pos.y, menu_size.w, menu_size.h, g_simgraph->palette_lookup(MN_GREY2), false );
 	}
+
 	// .. extra logic to enable tooltips
 	tooltip_element = main_menu->is_hit( get_mouse_pos().x-menu_pos.x, get_mouse_pos().y-menu_pos.y) ? main_menu : NULL;
 	void *old_inside_event_handling = inside_event_handling;
@@ -1908,7 +1935,7 @@ void win_display_flush(double konto)
 	main_menu->draw(menu_pos, menu_size);
 	inside_event_handling = old_inside_event_handling;
 
-	display_set_clip_wh(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h);
+	g_simgraph->set_clip_rect(clip_rr.x, clip_rr.y, clip_rr.w, clip_rr.h CLIP_NUM_DEFAULT, false);
 
 	if(show_ticker  ||  !ticker::empty()) {
 		if (!show_ticker  ||  wl->is_dirty()) {
@@ -1922,7 +1949,15 @@ void win_display_flush(double konto)
 	}
 
 	if(  skinverwaltung_t::compass_iso  &&  env_t::compass_screen_position  ) {
-		display_img_aligned( skinverwaltung_t::compass_iso->get_image_id( wl->get_settings().get_rotation() ), scr_rect(D_MARGIN_LEFT, env_t::iconsize.h+D_MARGIN_TOP,disp_width-2*4,disp_height- env_t::iconsize.h -D_MARGIN_TOP-D_MARGIN_BOTTOM-win_get_statusbar_height()-(TICKER_HEIGHT)*show_ticker), env_t::compass_screen_position, false );
+		const image_id img = skinverwaltung_t::compass_iso->get_image_id(wl->get_settings().get_rotation());
+		const scr_rect area = {
+			D_MARGIN_LEFT,
+			env_t::iconsize.h+D_MARGIN_TOP,
+			screen.w - 2*4,
+			screen.h - env_t::iconsize.h - D_MARGIN_TOP - D_MARGIN_BOTTOM - win_get_statusbar_height() - (TICKER_HEIGHT)*show_ticker
+		};
+
+		g_simgraph->draw_img_aligned(img, area, env_t::compass_screen_position, false );
 	}
 
 	{
@@ -1938,20 +1973,20 @@ void win_display_flush(double konto)
 				// display tooltip when current owner is invalid or when it is within visible duration
 				uint32 elapsed_time;
 				if(  !tooltip_owner  ||  ((elapsed_time=dr_time()-tooltip_register_time)>env_t::tooltip_delay  &&  elapsed_time<=env_t::tooltip_delay+env_t::tooltip_duration)  ) {
-					const sint16 width = proportional_string_width(tooltip_text)+(LINESPACE/2);
+					const sint16 width = g_simgraph->calc_text_width(tooltip_text)+(LINESPACE/2);
 					scr_coord pos{ tooltip_xpos, tooltip_ypos };
 					win_clamp_xywh_position( NULL, pos, scr_size( width, (LINESPACE*9)/7 ), true );
-					display_ddd_proportional_clip( pos.x, pos.y, env_t::tooltip_color, env_t::tooltip_textcolor, tooltip_text, true);
+					g_simgraph->draw_textbox3d_clipped( pos.x, pos.y, env_t::tooltip_color, env_t::tooltip_textcolor, tooltip_text, true CLIP_NUM_DEFAULT);
 					if(wl) {
 						wl->set_background_dirty();
 					}
 				}
 			}
 			else if(!static_tooltip_text.empty()) {
-				const sint16 width = proportional_string_width(static_tooltip_text.c_str())+ (LINESPACE/2);
+				const sint16 width = g_simgraph->calc_text_width(static_tooltip_text.c_str())+ (LINESPACE/2);
 				scr_coord pos = get_mouse_pos();
 				win_clamp_xywh_position( NULL, pos, scr_size(width, (LINESPACE*9)/7), true);
-				display_ddd_proportional_clip(pos.x, pos.y, env_t::tooltip_color, env_t::tooltip_textcolor, static_tooltip_text.c_str(), true);
+				g_simgraph->draw_textbox3d_clipped(pos.x, pos.y, env_t::tooltip_color, env_t::tooltip_textcolor, static_tooltip_text.c_str(), true CLIP_NUM_DEFAULT);
 				if(wl) {
 					wl->set_background_dirty();
 				}
@@ -1986,13 +2021,14 @@ void win_display_flush(double konto)
 
 	// statusbar background
 	scr_coord_val const status_bar_height = win_get_statusbar_height();
-	scr_coord_val const status_bar_y =env_t::menupos == MENU_BOTTOM ? 0 : disp_height - status_bar_height;
+	scr_coord_val const status_bar_y =env_t::menupos == MENU_BOTTOM ? 0 : screen.h - status_bar_height;
 	scr_coord_val const status_bar_text_y = status_bar_y + (status_bar_height - LINESPACE) / 2;
 	scr_coord_val const status_bar_icon_y = status_bar_y + (status_bar_height - 15) / 2;
-	display_set_clip_wh( 0, 0, disp_width, disp_height );
-	display_fillbox_wh_rgb(0, status_bar_y - 1, disp_width, 1, SYSCOL_STATUSBAR_DIVIDER, false);
-	display_fillbox_wh_rgb(0, env_t::menupos == MENU_BOTTOM ? status_bar_height : status_bar_y - 1, disp_width, 1, SYSCOL_STATUSBAR_DIVIDER, false);
-	display_fillbox_wh_rgb(0, status_bar_y, disp_width, status_bar_height, SYSCOL_STATUSBAR_BACKGROUND, false);
+
+	g_simgraph->set_clip_rect( 0, 0, screen.w, screen.h CLIP_NUM_DEFAULT, false);
+	g_simgraph->draw_rect(0, status_bar_y - 1, screen.w, 1, SYSCOL_STATUSBAR_DIVIDER, false);
+	g_simgraph->draw_rect(0, env_t::menupos == MENU_BOTTOM ? status_bar_height : status_bar_y - 1, screen.w, 1, SYSCOL_STATUSBAR_DIVIDER, false);
+	g_simgraph->draw_rect(0, status_bar_y, screen.w, status_bar_height, SYSCOL_STATUSBAR_BACKGROUND, false);
 
 	bool tooltip_check = env_t::menupos == MENU_BOTTOM ? get_mouse_pos().y < status_bar_height : get_mouse_pos().y > status_bar_y;
 	if(  tooltip_check  ) {
@@ -2003,7 +2039,7 @@ void win_display_flush(double konto)
 	scr_coord_val left_border = 2;
 
 	// season icon
-	display_color_img( skinverwaltung_t::seasons_icons->get_image_id(wl->get_season()), left_border, status_bar_icon_y, 0, false, true );
+	g_simgraph->draw_color_img( skinverwaltung_t::seasons_icons->get_image_id(wl->get_season()), left_border, status_bar_icon_y, 0, false, true CLIP_NUM_DEFAULT);
 	if(  tooltip_check  &&  tooltip_xpos<14  ) {
 		static char const* const seasons[] = { "q2", "q3", "q4", "q1" };
 		tooltip_text = translator::translate(seasons[wl->get_season()]);
@@ -2011,12 +2047,12 @@ void win_display_flush(double konto)
 	}
 	left_border += 14;
 
-	scr_coord_val right_border = disp_width-4;
+	scr_coord_val right_border = screen.w - 4;
 
 	// shown if timeline game
 	if(  wl->use_timeline()  &&  skinverwaltung_t::timelinesymbol  ) {
 		right_border -= 14;
-		display_color_img( skinverwaltung_t::timelinesymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true );
+		g_simgraph->draw_color_img( skinverwaltung_t::timelinesymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true CLIP_NUM_DEFAULT);
 		if(  tooltip_check  &&  tooltip_xpos>=right_border  ) {
 			tooltip_text = translator::translate("timeline");
 			tooltip_check = false;
@@ -2026,7 +2062,7 @@ void win_display_flush(double konto)
 	// shown if connected
 	if(  env_t::networkmode  &&  skinverwaltung_t::networksymbol  ) {
 		right_border -= 14;
-		display_color_img( skinverwaltung_t::networksymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true );
+		g_simgraph->draw_color_img( skinverwaltung_t::networksymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true CLIP_NUM_DEFAULT);
 		if(  tooltip_check  &&  tooltip_xpos>=right_border  ) {
 			tooltip_text = translator::translate("Connected with server");
 			tooltip_check = false;
@@ -2036,7 +2072,7 @@ void win_display_flush(double konto)
 	// put pause icon
 	if(  wl->is_paused()  &&  skinverwaltung_t::pausesymbol  ) {
 		right_border -= 14;
-		display_color_img( skinverwaltung_t::pausesymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true );
+		g_simgraph->draw_color_img( skinverwaltung_t::pausesymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true CLIP_NUM_DEFAULT);
 		if(  tooltip_check  &&  tooltip_xpos>=right_border  ) {
 			tooltip_text = translator::translate("GAME PAUSED");
 			tooltip_check = false;
@@ -2046,7 +2082,7 @@ void win_display_flush(double konto)
 	// put fast forward icon
 	if(  wl->is_fast_forward()  &&  skinverwaltung_t::fastforwardsymbol  ) {
 		right_border -= 14;
-		display_color_img( skinverwaltung_t::fastforwardsymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true );
+		g_simgraph->draw_color_img( skinverwaltung_t::fastforwardsymbol->get_image_id(0), right_border, status_bar_icon_y, 0, false, true CLIP_NUM_DEFAULT);
 		if(  tooltip_check  &&  tooltip_xpos>=right_border  ) {
 			tooltip_text = translator::translate("Fast forward");
 			tooltip_check = false;
@@ -2096,8 +2132,9 @@ void win_display_flush(double konto)
 		}
 	}
 #endif
-	left_border += 4 + display_proportional_rgb(left_border, status_bar_text_y, time, ALIGN_LEFT, SYSCOL_STATUSBAR_TEXT, true);
-	right_border -= 4 + display_proportional_rgb(right_border, status_bar_text_y, info, ALIGN_RIGHT, SYSCOL_STATUSBAR_TEXT, true);
+
+	left_border  += 4 + g_simgraph->draw_text(left_border,  status_bar_text_y, time, ALIGN_LEFT,  SYSCOL_STATUSBAR_TEXT, true);
+	right_border -= 4 + g_simgraph->draw_text(right_border, status_bar_text_y, info, ALIGN_RIGHT, SYSCOL_STATUSBAR_TEXT, true);
 
 	/* Since the visual center jumps left and right with proportional fonts, we quantisze by 16 pixel
 	 */
@@ -2107,7 +2144,7 @@ void win_display_flush(double konto)
 	if(wl->get_active_player()) {
 		char buffer[256];
 		scr_coord_val textwidth_pl = 0;
-		textwidth_pl = D_H_SPACE + proportional_string_width(wl->get_active_player()->get_name());
+		textwidth_pl = D_H_SPACE + g_simgraph->calc_text_width(wl->get_active_player()->get_name());
 		if (status_show_compact) {
 			number_to_string_fit(buffer, konto, 0, 10);
 			strcat(buffer, "$");
@@ -2115,12 +2152,13 @@ void win_display_flush(double konto)
 		else {
 			money_to_string(buffer, konto);
 		}
-		scr_coord_val textwidth_mn = (proportional_string_width(buffer)+15) & 0xFFFFFFF0ul;
+
+		scr_coord_val textwidth_mn = (g_simgraph->calc_text_width(buffer) + 15) & 0xFFFFFFF0ul;
 		if (textwidth_mn + textwidth_pl < right_border - left_border) {
 			// everything fits
 			left_border += ( (right_border - left_border) - (textwidth_mn + textwidth_pl)  ) / 2;
-			left_border += D_H_SPACE + display_proportional_rgb(left_border, status_bar_text_y, wl->get_active_player()->get_name(), ALIGN_LEFT, PLAYER_FLAG | color_idx_to_rgb(wl->get_active_player()->get_player_color1() + env_t::gui_player_color_dark), true);
-			display_proportional_rgb(left_border, status_bar_text_y, buffer, ALIGN_LEFT, konto >= 0.0 ? MONEY_PLUS : MONEY_MINUS, true);
+			left_border += D_H_SPACE + g_simgraph->draw_text(left_border, status_bar_text_y, wl->get_active_player()->get_name(), ALIGN_LEFT, PLAYER_FLAG | g_simgraph->palette_lookup(wl->get_active_player()->get_player_color1() + env_t::gui_player_color_dark), true);
+			g_simgraph->draw_text(left_border, status_bar_text_y, buffer, ALIGN_LEFT, konto >= 0.0 ? MONEY_PLUS : MONEY_MINUS, true);
 		}
 		else {
 			// no space => only money
@@ -2128,10 +2166,10 @@ void win_display_flush(double konto)
 			scr_coord_val width_left = (right_border - left_border - textwidth_mn);
 			if (width_left > 50) {
 				scr_rect r(left_border, status_bar_text_y, width_left-D_H_SPACE, LINESPACE);
-				display_proportional_ellipsis_rgb(r, wl->get_active_player()->get_name(), ALIGN_LEFT, PLAYER_FLAG | color_idx_to_rgb(wl->get_active_player()->get_player_color1() + env_t::gui_player_color_dark), true);
+				g_simgraph->draw_text_ellipsis(r, wl->get_active_player()->get_name(), ALIGN_LEFT, PLAYER_FLAG | g_simgraph->palette_lookup(wl->get_active_player()->get_player_color1() + env_t::gui_player_color_dark), true);
 				left_border += width_left;
 				// normal color
-				display_proportional_rgb(left_border, status_bar_text_y, buffer, ALIGN_LEFT, konto >= 0.0 ? MONEY_PLUS : MONEY_MINUS, true);
+				g_simgraph->draw_text(left_border, status_bar_text_y, buffer, ALIGN_LEFT, konto >= 0.0 ? MONEY_PLUS : MONEY_MINUS, true);
 			}
 			else {
 				// just money in player color, no player name
@@ -2143,7 +2181,7 @@ void win_display_flush(double konto)
 					number_to_string_fit(buffer, konto, 0, 5);
 					strcat(buffer, "$");
 				}
-				display_proportional_rgb(left_border, status_bar_text_y, buffer, ALIGN_LEFT, konto >= 0.0 ? color_idx_to_rgb(wl->get_active_player()->get_player_color1() + env_t::gui_player_color_dark) : MONEY_MINUS, true);
+				g_simgraph->draw_text(left_border, status_bar_text_y, buffer, ALIGN_LEFT, konto >= 0.0 ? g_simgraph->palette_lookup(wl->get_active_player()->get_player_color1() + env_t::gui_player_color_dark) : MONEY_MINUS, true);
 			}
 		}
 	}
@@ -2168,7 +2206,7 @@ void win_redraw_world()
 
 bool win_change_zoom_factor(bool magnify)
 {
-	const bool result = magnify ? zoom_factor_up() : zoom_factor_down();
+	const bool result = magnify ? g_simgraph->zoom_factor_up() : g_simgraph->zoom_factor_down();
 
 	if(magnify  &&  wl->is_step_mode_normal()) {
 		wl->reset_timer();
@@ -2185,7 +2223,7 @@ void win_load_font(const char *fname, uint8 fontsize)
 	bool force_reload = fontsize != env_t::fontsize;
 	env_t::fontsize = fontsize;
 
-	if (display_load_font(fname, force_reload) ) {
+	if (g_simgraph->load_font(fname, force_reload) ) {
 		// successfull
 		gui_theme_t::themes_init( env_t::default_theme, false, false );
 
@@ -2196,7 +2234,7 @@ void win_load_font(const char *fname, uint8 fontsize)
 	}
 	else {
 		// restore old font
-		display_load_font(env_t::fontname.c_str(), true);
+		g_simgraph->load_font(env_t::fontname.c_str(), true);
 	}
 	win_redraw_world();
 }
@@ -2252,7 +2290,7 @@ void win_set_tooltip(scr_coord pos, const char *text, const void *const owner, c
 	}
 
 	if (text) {
-		const scr_size tt_size = scr_size(proportional_string_width(text), LINESPACE + 2);
+		const scr_size tt_size = scr_size(g_simgraph->calc_text_width(text), LINESPACE + 2);
 		win_clamp_xywh_position(NULL, pos, tt_size, true);
 		pos.y += LINESPACE / 2 + 1;
 	}
@@ -2274,7 +2312,9 @@ void win_set_static_tooltip(const char *text)
 // shows a modal dialoge
 void modal_dialogue(gui_frame_t* gui, ptrdiff_t magic, karte_t* welt, bool (*quit)(), bool dismissible)
 {
-	if (display_get_width() == 0) {
+	const scr_size screen = g_simgraph->get_screen_size();
+
+	if (screen.w == 0) {
 		dbg->error("modal_dialogue", "called without a display driver => nothing will be shown!");
 		env_t::quit_simutrans = true;
 		// cannot handle this!
@@ -2288,8 +2328,8 @@ void modal_dialogue(gui_frame_t* gui, ptrdiff_t magic, karte_t* welt, bool (*qui
 	event_t ev;
 	create_win(scr_coord(0,0), gui, w_info, magic);
 	scr_coord pos{
-		(display_get_width() - gui->get_windowsize().w) / 2,
-		(display_get_height() - gui->get_windowsize().h) / 2
+		(screen.w - gui->get_windowsize().w) / 2,
+		(screen.h - gui->get_windowsize().h) / 2
 	};
 	win_clamp_xywh_position(gui, pos, gui->get_windowsize(), true);
 	wins[wins[0].gui!=gui].pos = pos;
@@ -2367,9 +2407,10 @@ void modal_dialogue(gui_frame_t* gui, ptrdiff_t magic, karte_t* welt, bool (*qui
 		clear_random_mode(MODAL_RANDOM);
 	}
 	else {
-		display_show_pointer(true);
-		display_show_load_pointer(0);
-		display_fillbox_wh_rgb(0, 0, display_get_width(), display_get_height(), color_idx_to_rgb(COL_BLACK), true);
+		g_simgraph->set_cursor_visible(true);
+		g_simgraph->set_show_load_cursor(false);
+		g_simgraph->draw_rect(0, 0, screen.w, screen.h, g_simgraph->palette_lookup(COL_BLACK), true);
+
 		while (gui && win_is_open(gui) && !env_t::quit_simutrans && !quit()) {
 			// do not move, do not close it!
 
@@ -2388,16 +2429,16 @@ void modal_dialogue(gui_frame_t* gui, ptrdiff_t magic, karte_t* welt, bool (*qui
 				if (ev.ev_class == EVENT_SYSTEM) {
 					if (ev.ev_code == SYSTEM_RESIZE) {
 						// main window resized
-						simgraph_resize(ev.new_window_size);
+						g_simgraph->on_window_resized(ev.new_window_size);
 						scr_coord pos{
-							(display_get_width() - gui->get_windowsize().w) / 2,
-							(display_get_height() - gui->get_windowsize().h) / 2
+							(screen.w - gui->get_windowsize().w) / 2,
+							(screen.h - gui->get_windowsize().h) / 2
 						};
 						win_clamp_xywh_position(gui, pos, gui->get_windowsize(), true);
 						wins[wins[0].gui != gui].pos = pos;
 
 						dr_prepare_flush();
-						display_fillbox_wh_rgb(0, 0, ev.new_window_size.w, ev.new_window_size.h, color_idx_to_rgb(COL_BLACK), true);
+						g_simgraph->draw_rect(0, 0, ev.new_window_size.w, ev.new_window_size.h, g_simgraph->palette_lookup(COL_BLACK), true);
 						gui->draw(win_get_pos(gui), gui->get_windowsize());
 						dr_flush();
 					}
@@ -2420,9 +2461,9 @@ void modal_dialogue(gui_frame_t* gui, ptrdiff_t magic, karte_t* welt, bool (*qui
 				dr_sleep(50 - (end_time - frame_start_time));
 			}
 		}
-		display_show_load_pointer(1);
+		g_simgraph->set_show_load_cursor(true);
 		dr_prepare_flush();
-		display_fillbox_wh_rgb(0, 0, display_get_width(), display_get_height(), color_idx_to_rgb(COL_BLACK), true);
+		g_simgraph->draw_rect(0, 0, screen.w, screen.h, g_simgraph->palette_lookup(COL_BLACK), true);
 		dr_flush();
 	}
 
diff --git a/src/simutrans/gui/sprachen.cc b/src/simutrans/gui/sprachen.cc
index 3aebe1f62..a16c93422 100644
--- a/src/simutrans/gui/sprachen.cc
+++ b/src/simutrans/gui/sprachen.cc
@@ -67,7 +67,8 @@ void sprachengui_t::init_font_from_lang()
 	size_t len;
 	utf16 testfor_this_character = utf8_decoder_t::decode(new_world, len);
 
-	bool reload_font = !has_character(testfor_this_character);
+	bool reload_font = !g_simgraph->font_has_character(testfor_this_character);
+
 	if(reload_font) {
 		if (env_t::fontsize == 11) {
 			// can only use fixed default with current font size
@@ -89,7 +90,7 @@ void sprachengui_t::init_font_from_lang()
 				do {
 					std::string fname = FONT_PATH_X;
 					fname += prop_font_file_name;
-					ok = display_load_font(fname.c_str());
+					ok = g_simgraph->load_font(fname.c_str(), false);
 					f = strtok(NULL, ";");
 				} while (!ok && f);
 				dr_chdir(env_t::user_dir);
@@ -215,7 +216,7 @@ bool sprachengui_t::action_triggered( gui_action_creator_t *comp, value_t)
 				// we only show matching fonts for this language
 				const utf8 *new_world = (const utf8 *)translator::translate("Beenden");
 				size_t len;
-				if (!has_character(utf8_decoder_t::decode(new_world, len))) {
+				if (!g_simgraph->font_has_character(utf8_decoder_t::decode(new_world, len))) {
 					// load a matching font ...
 					create_win(new loadfont_frame_t(), w_info, magic_font);
 				}
diff --git a/src/simutrans/gui/tool_selector.cc b/src/simutrans/gui/tool_selector.cc
index cbffba0af..157a697f5 100644
--- a/src/simutrans/gui/tool_selector.cc
+++ b/src/simutrans/gui/tool_selector.cc
@@ -270,25 +270,26 @@ bool tool_selector_t::infowin_event(const event_t *ev)
 void tool_selector_t::draw(scr_coord pos, scr_size sz)
 {
 	player_t* player = welt->get_active_player();
+	const scr_size screen = g_simgraph->get_screen_size();
 
 	if (toolbar_id == 0) {
 		// checks for main menu (since it can change during changing layout)
 		if (env_t::menupos == MENU_TOP || env_t::menupos == MENU_BOTTOM) {
 			offset.y = 0;
 			allow_break = false;
-			tool_icon_width = (display_get_width() + env_t::iconsize.w - 1) / env_t::iconsize.w;
+			tool_icon_width = (screen.w + env_t::iconsize.w - 1) / env_t::iconsize.w;
 			tool_icon_height = 1; // only single row for title bar
 			set_windowsize(sz);
 			// check for too large values (after changing width etc.)
-			if (display_get_width() >= (int)tools.get_count() * env_t::iconsize.w) {
+			if (screen.w >= (int)tools.get_count() * env_t::iconsize.w) {
 				tool_icon_disp_start = 0;
 				offset.x = 0;
 			}
 			else {
 				scr_coord_val wx = (tools.get_count() - tool_icon_disp_start + 1) * env_t::iconsize.w + offset.x;
-				if (wx < display_get_width()) {
+				if (wx < screen.w) {
 					tool_icon_disp_start = tool_icon_disp_end < tool_icon_height ? 0 : tool_icon_disp_end - tool_icon_width;
-					offset.x = display_get_width() - (tools.get_count() - tool_icon_disp_start) * env_t::iconsize.w;
+					offset.x = screen.w - (tools.get_count() - tool_icon_disp_start) * env_t::iconsize.w;
 				}
 			}
 			has_prev_next = (int)tools.get_count() * env_t::iconsize.w > sz.w;
@@ -300,28 +301,29 @@ void tool_selector_t::draw(scr_coord pos, scr_size sz)
 			// only single column for title bar
 			scr_rect screen = win_get_max_window_area();
 			tool_icon_height = max(1, (screen.h - win_get_statusbar_height() + env_t::iconsize.h - 1) / env_t::iconsize.h);
-			set_windowsize(scr_size(env_t::iconsize.w, display_get_height() - win_get_statusbar_height()));
+			set_windowsize(scr_size(env_t::iconsize.w, screen.h - win_get_statusbar_height()));
 
-			if (display_get_height() >= (int)tools.get_count() * env_t::iconsize.h) {
+			if (screen.h >= (int)tools.get_count() * env_t::iconsize.h) {
 				tool_icon_disp_start = 0;
 				offset.y = 0;
 			}
 			else {
 				scr_coord_val hx = (tools.get_count() - tool_icon_disp_start + 1) * env_t::iconsize.h + offset.y;
-				if (hx < display_get_height()) {
+				if (hx < screen.h) {
 					tool_icon_disp_end = tools.get_count();
 					tool_icon_disp_start = tool_icon_disp_end < tool_icon_height ? 0 : tool_icon_disp_end - tool_icon_height;
-					offset.y = display_get_height() - (tools.get_count() - tool_icon_disp_start) * env_t::iconsize.h;
+					offset.y = screen.h - (tools.get_count() - tool_icon_disp_start) * env_t::iconsize.h;
 				}
 			}
 
 			has_prev_next = (int)tools.get_count() * env_t::iconsize.h > sz.h;
 		}
 	}
-	clip_dimension const p_cr = display_get_clip_wh();
+	clip_dimension const p_cr = g_simgraph->get_clip_rect(CLIP_NUM_DEFAULT_VALUE);
 	if (toolbar_id != 0) {
-		display_set_clip_wh(pos.x, pos.y, sz.w, sz.h);
+		g_simgraph->set_clip_rect(pos.x, pos.y, sz.w, sz.h CLIP_NUM_DEFAULT, false);
 	}
+
 	for(  uint i = tool_icon_disp_start;  i < tool_icon_disp_end;  i++  ) {
 		const image_id icon_img = tools[i].tool->get_icon(player);
 #if COLOUR_DEPTH != 0
@@ -339,23 +341,23 @@ void tool_selector_t::draw(scr_coord pos, scr_size sz)
 		if(  toolbar_id>0  &&  !(strstart((param==NULL)? "" : param, "-b"))  ) {
 			if(  skinverwaltung_t::toolbar_background  &&  skinverwaltung_t::toolbar_background->get_image_id(toolbar_id) != IMG_EMPTY  ) {
 				const image_id back_img = skinverwaltung_t::toolbar_background->get_image_id(toolbar_id);
-				display_fit_img_to_width( back_img, env_t::iconsize.w );
-				display_color_img( back_img, draw_pos.x, draw_pos.y, welt->get_active_player_nr(), false, true );
+				g_simgraph->fit_img_to_width( back_img, env_t::iconsize.w );
+				g_simgraph->draw_color_img( back_img, draw_pos.x, draw_pos.y, welt->get_active_player_nr(), false, true CLIP_NUM_DEFAULT);
 			}
 			else {
-				display_fillbox_wh_clip_rgb( draw_pos.x, draw_pos.y, env_t::iconsize.w, env_t::iconsize.h, color_idx_to_rgb(MN_GREY2), false );
+				g_simgraph->draw_rect_clipped(draw_pos.x, draw_pos.y, env_t::iconsize.w, env_t::iconsize.h, g_simgraph->palette_lookup(MN_GREY2), false CLIP_NUM_DEFAULT);
 			}
 		}
 
 		// if there's no image we simply skip, button will be transparent showing toolbar background
 		if(  icon_img != IMG_EMPTY  ) {
 			bool tool_dirty = dirty  ||  (tools[i].tool->is_selected() ^ tools[i].selected);
-			display_fit_img_to_width( icon_img, env_t::iconsize.w );
-			display_color_img(icon_img, draw_pos.x, draw_pos.y, player->get_player_nr(), false, tool_dirty);
+			g_simgraph->fit_img_to_width( icon_img, env_t::iconsize.w );
+			g_simgraph->draw_color_img(icon_img, draw_pos.x, draw_pos.y, player->get_player_nr(), false, tool_dirty CLIP_NUM_DEFAULT);
 			tools[i].tool->draw_after( draw_pos, tool_dirty);
 			if (!tools[i].tool->enabled) {
 				// grey out disbaled entries
-				display_img_blend(icon_img, draw_pos.x, draw_pos.y, TRANSPARENT75_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_WHITE), false, tool_dirty);
+				g_simgraph->draw_img_blend(icon_img, draw_pos.x, draw_pos.y, TRANSPARENT75_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_WHITE), false, tool_dirty);
 			}
 			// store whether tool was selected
 			tools[i].selected = tools[i].tool->is_selected();
@@ -363,27 +365,27 @@ void tool_selector_t::draw(scr_coord pos, scr_size sz)
 	}
 
 	if( is_dragging ) {
-		mark_rect_dirty_wc(pos.x, pos.y+D_TITLEBAR_HEIGHT, pos.x+sz.w, pos.y+sz.h+D_TITLEBAR_HEIGHT );
+		g_simgraph->mark_rect_dirty_wc(pos.x, pos.y+D_TITLEBAR_HEIGHT, pos.x+sz.w, pos.y+sz.h+D_TITLEBAR_HEIGHT );
 	}
 	else if(  dirty  &&  (tool_icon_disp_end-tool_icon_disp_start < tool_icon_width*tool_icon_height)  ) {
 		// mark empty space empty
-		mark_rect_dirty_wc(pos.x, pos.y, pos.x + tool_icon_width*env_t::iconsize.w, pos.y + tool_icon_height*env_t::iconsize.h);
+		g_simgraph->mark_rect_dirty_wc(pos.x, pos.y, pos.x + tool_icon_width*env_t::iconsize.w, pos.y + tool_icon_height*env_t::iconsize.h);
 	}
 	if (toolbar_id != 0) {
-		display_set_clip_wh(p_cr.x, p_cr.y, p_cr.w, p_cr.h);
+		g_simgraph->set_clip_rect(p_cr.x, p_cr.y, p_cr.w, p_cr.h CLIP_NUM_DEFAULT, false);
 	}
 
 	if(  offset.x != 0  &&  tool_icon_disp_start > 0  ) {
-		display_color_img(gui_theme_t::arrow_button_left_img[0], pos.x, pos.y + D_TITLEBAR_HEIGHT, 0, false, false);
+		g_simgraph->draw_color_img(gui_theme_t::arrow_button_left_img[0], pos.x, pos.y + D_TITLEBAR_HEIGHT, 0, false, false CLIP_NUM_DEFAULT);
 	}
 	if(  offset.y != 0  &&  tool_icon_disp_start > 0  ) {
-		display_color_img(gui_theme_t::arrow_button_up_img[0], pos.x, pos.y + D_TITLEBAR_HEIGHT, 0, false, false);
+		g_simgraph->draw_color_img(gui_theme_t::arrow_button_up_img[0], pos.x, pos.y + D_TITLEBAR_HEIGHT, 0, false, false CLIP_NUM_DEFAULT);
 	}
 	if(  tool_icon_height == 1  &&  (tool_icon_disp_start+tool_icon_width < tools.get_count()  ||  (-offset.x) < env_t::iconsize.w*tool_icon_width-get_windowsize().w)  ) {
-		display_color_img( gui_theme_t::arrow_button_right_img[0], pos.x+sz.w-D_ARROW_UP_WIDTH, pos.y+D_TITLEBAR_HEIGHT, 0, false, false );
+		g_simgraph->draw_color_img( gui_theme_t::arrow_button_right_img[0], pos.x+sz.w-D_ARROW_UP_WIDTH, pos.y+D_TITLEBAR_HEIGHT, 0, false, false CLIP_NUM_DEFAULT);
 	}
 	if(  tool_icon_width == 1  &&  (tool_icon_disp_start+tool_icon_height < tools.get_count()  ||  (-offset.y) < env_t::iconsize.h*tool_icon_height-get_windowsize().h)  ) {
-		display_color_img(gui_theme_t::arrow_button_down_img[0], pos.x+sz.w-D_ARROW_DOWN_WIDTH, pos.y+D_TITLEBAR_HEIGHT+sz.h-D_ARROW_DOWN_HEIGHT, 0, false, false);
+		g_simgraph->draw_color_img(gui_theme_t::arrow_button_down_img[0], pos.x+sz.w-D_ARROW_DOWN_WIDTH, pos.y+D_TITLEBAR_HEIGHT+sz.h-D_ARROW_DOWN_HEIGHT, 0, false, false CLIP_NUM_DEFAULT);
 	}
 
 	if(  !is_dragging  ) {
@@ -410,7 +412,6 @@ void tool_selector_t::draw(scr_coord pos, scr_size sz)
 }
 
 
-
 bool tool_selector_t::empty(player_t *player) const
 {
 	for(tool_data_t w : tools) {
diff --git a/src/simutrans/gui/vehiclelist_frame.cc b/src/simutrans/gui/vehiclelist_frame.cc
index 3f9a5644e..4403e83f1 100644
--- a/src/simutrans/gui/vehiclelist_frame.cc
+++ b/src/simutrans/gui/vehiclelist_frame.cc
@@ -39,20 +39,20 @@ vehiclelist_stats_t::vehiclelist_stats_t(const vehicle_desc_t *v) :
 	veh = v;
 
 	// width of image
-	scr_coord_val x, y, w, h;
 	const image_id image = veh->get_image_id( ribi_t::dir_south, veh->get_freight_type() );
-	display_get_base_image_offset(image, &x, &y, &w, &h );
-	if( w > img_width ) {
-		img_width = w + D_H_SPACE;
+	const scr_rect r = g_simgraph->get_base_image_offset(image);
+
+	if( r.w > img_width ) {
+		img_width = r.w + D_H_SPACE;
 	}
-	height = h;
+	height = r.h;
 
 	// name is the widest entry in column 1
-	name_width = proportional_string_width( translator::translate( veh->get_name(), world()->get_settings().get_name_language_id() ) );
+	name_width = g_simgraph->calc_text_width( translator::translate( veh->get_name(), world()->get_settings().get_name_language_id() ) );
 	if( veh->get_power() > 0 ) {
 		char str[ 256 ];
 		sprintf( str, " (%s)", translator::translate( vehicle_builder_t::engine_type_names[ veh->get_engine_type() + 1 ] ) );
-		name_width += proportional_string_width( str );
+		name_width += g_simgraph->calc_text_width( str );
 	}
 	scr_coord_val name_h = LINESPACE;
 
@@ -85,9 +85,9 @@ vehiclelist_stats_t::vehiclelist_stats_t(const vehicle_desc_t *v) :
 			part1.printf( translator::translate( "Power: %4d kW\n" ), veh->get_power() );
 		}
 	}
-	int text1w, text1h;
-	display_calc_proportional_multiline_string_len_width( text1w, text1h, part1);
-	col1_width = text1w + D_H_SPACE;
+
+	const scr_size text1_size = g_simgraph->calc_multiline_text_size(part1);
+	col1_width = text1_size.w + D_H_SPACE;
 
 	// column 2
 	part2.clear();
@@ -100,9 +100,9 @@ vehiclelist_stats_t::vehiclelist_stats_t(const vehicle_desc_t *v) :
 		part2.append( "\n" );
 		part2.printf( translator::translate( "Constructed by %s" ), copyright );
 	}
-	int text2w, text2h;
-	display_calc_proportional_multiline_string_len_width( text2w, text2h, part2);
-	col2_width = text2w;
+
+	const scr_size text2_size = g_simgraph->calc_multiline_text_size(part2);
+	col2_width = text2_size.w;
 
 	// we need to find out manually, if we have extra text to show
 	if (strlen(veh->get_name()) < 238) {
@@ -116,7 +116,7 @@ vehiclelist_stats_t::vehiclelist_stats_t(const vehicle_desc_t *v) :
 		}
 	}
 
-	height = max( height, max( text1h, text2h ) + name_h )+D_V_SPACE;
+	height = max( height, max( text1_size.h, text2_size.h ) + name_h ) + D_V_SPACE;
 }
 
 
@@ -127,24 +127,25 @@ void vehiclelist_stats_t::draw( scr_coord offset )
 
 	offset.x += D_MARGIN_LEFT;
 	offset.y += D_V_SPACE/2;
-	scr_coord_val x, y, w, h;
+
 	const image_id image = veh->get_image_id( ribi_t::dir_south, veh->get_freight_type() );
-	display_get_base_image_offset(image, &x, &y, &w, &h );
-	display_base_img(image, offset.x - x, offset.y - y, world()->get_active_player_nr(), false, true);
+	const scr_rect r = g_simgraph->get_base_image_offset(image);
+	g_simgraph->draw_base_img(image, offset.x - r.x, offset.y - r.y, world()->get_active_player_nr(), false, true CLIP_NUM_DEFAULT);
 
 	// first name
 	offset.x += img_width;
-	int dx = display_proportional_rgb(
+	int dx = g_simgraph->draw_text(
 		offset.x, offset.y,
 		translator::translate( veh->get_name(), world()->get_settings().get_name_language_id() ),
 		ALIGN_LEFT|DT_CLIP,
 		veh->is_future(month) ? SYSCOL_TEXT_HIGHLIGHT : (veh->is_available(month) ? SYSCOL_TEXT : gui_theme_t::gui_color_obsolete),
 		false
 	);
+
 	if( veh->get_power() > 0 ) {
 		char str[ 256 ];
 		sprintf( str, " (%s)", translator::translate( vehicle_builder_t::engine_type_names[ veh->get_engine_type() + 1 ] ) );
-		display_proportional_rgb( offset.x+dx, offset.y, str, ALIGN_LEFT|DT_CLIP, SYSCOL_TEXT, false );
+		g_simgraph->draw_text( offset.x+dx, offset.y, str, ALIGN_LEFT|DT_CLIP, SYSCOL_TEXT, false );
 	}
 
 	// maybe there are detailed text to the vehicle?
@@ -155,16 +156,18 @@ void vehiclelist_stats_t::draw( scr_coord offset )
 	}
 
 	// now the rest in two columns
-	display_multiline_text_rgb( offset.x, yyy, part1, SYSCOL_TEXT );
+	g_simgraph->draw_multiline_text( offset.x, yyy, part1, SYSCOL_TEXT );
 
-	display_multiline_text_rgb( offset.x + col1_width, yyy, part2, SYSCOL_TEXT );
+	g_simgraph->draw_multiline_text( offset.x + col1_width, yyy, part2, SYSCOL_TEXT );
 }
 
+
 const char *vehiclelist_stats_t::get_text() const
 {
 	return translator::translate( veh->get_name() );
 }
 
+
 bool vehiclelist_stats_t::compare(const gui_component_t *aa, const gui_component_t *bb)
 {
 	bool result = vehicle_builder_t::compare_vehicles( dynamic_cast<const vehiclelist_stats_t*>(aa)->veh, dynamic_cast<const vehiclelist_stats_t*>(bb)->veh, (vehicle_builder_t::sort_mode_t)vehiclelist_stats_t::sort_mode );
@@ -172,8 +175,6 @@ bool vehiclelist_stats_t::compare(const gui_component_t *aa, const gui_component
 }
 
 
-
-
 vehiclelist_frame_t::vehiclelist_frame_t() :
 	gui_frame_t( translator::translate("vh_title") ),
 	scrolly(gui_scrolled_list_t::windowskin, vehiclelist_stats_t::compare)
diff --git a/src/simutrans/gui/welt.cc b/src/simutrans/gui/welt.cc
index 2aa6b014c..e43af9a59 100644
--- a/src/simutrans/gui/welt.cc
+++ b/src/simutrans/gui/welt.cc
@@ -482,7 +482,7 @@ bool welt_gui_t::action_triggered( gui_action_creator_t *comp,value_t v)
 		load_relief_frame_t* lrf = new load_relief_frame_t(sets);
 		create_win(lrf, w_info, magic_load_t );
 
-		const scr_coord new_pos{ (display_get_width() - lrf->get_windowsize().w-10), env_t::iconsize.h };
+		const scr_coord new_pos{ (g_simgraph->get_screen_size().w - lrf->get_windowsize().w-10), env_t::iconsize.h };
 		win_set_pos(lrf, new_pos);
 		knr = sets->get_map_number(); // otherwise using cancel would not show the normal generated map again
 	}
@@ -518,7 +518,7 @@ bool welt_gui_t::action_triggered( gui_action_creator_t *comp,value_t v)
 		}
 		else {
 			climate_gui_t *cg = new climate_gui_t(sets);
-			const scr_coord_val xoff = min(win_get_pos(this).x + this->size.w, display_get_width() - cg->get_windowsize().w );
+			const scr_coord_val xoff = min(win_get_pos(this).x + this->size.w, g_simgraph->get_screen_size().w - cg->get_windowsize().w );
 			const scr_coord_val yoff = win_get_pos(this).y;
 			create_win({ xoff, yoff }, cg, w_info, magic_climate );
 			open_climate_gui.pressed = true;
diff --git a/src/simutrans/network/network_cmd_ingame.cc b/src/simutrans/network/network_cmd_ingame.cc
index 0981af9bb..5384a13f2 100644
--- a/src/simutrans/network/network_cmd_ingame.cc
+++ b/src/simutrans/network/network_cmd_ingame.cc
@@ -316,7 +316,7 @@ void nwc_chat_t::add_message(karte_t* welt) const
 {
 	cbuffer_t buf;  // Output which will be printed to chat window
 
-	FLAGGED_PIXVAL color = player_nr < PLAYER_UNOWNED  ? PLAYER_FLAG | player_nr :  color_idx_to_rgb(COL_WHITE);
+	FLAGGED_PIXVAL color = player_nr < PLAYER_UNOWNED  ? PLAYER_FLAG | player_nr :  g_simgraph->palette_lookup(COL_WHITE);
 	uint16 flag = message_t::chat;
 
 	if (  destination == NULL  ) {
diff --git a/src/simutrans/obj/baum.cc b/src/simutrans/obj/baum.cc
index 854a5d6d5..a0d24eb31 100644
--- a/src/simutrans/obj/baum.cc
+++ b/src/simutrans/obj/baum.cc
@@ -187,7 +187,7 @@ FLAGGED_PIXVAL baum_t::get_outline_colour() const
 void baum_t::recalc_outline_color()
 {
 	outline_color = (env_t::hide_trees  &&  env_t::hide_with_transparency) ?
-		(TRANSPARENT25_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_BLACK)) : 0;
+		(TRANSPARENT25_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_BLACK)) : 0;
 }
 
 
diff --git a/src/simutrans/obj/gebaeude.cc b/src/simutrans/obj/gebaeude.cc
index b615cdb32..752296b03 100644
--- a/src/simutrans/obj/gebaeude.cc
+++ b/src/simutrans/obj/gebaeude.cc
@@ -413,11 +413,11 @@ FLAGGED_PIXVAL gebaeude_t::get_outline_colour() const
 	FLAGGED_PIXVAL disp_colour = 0;
 	if(env_t::hide_buildings!=env_t::NOT_HIDE) {
 		if(is_city_building()) {
-			disp_colour = color_idx_to_rgb(colours[0]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
+			disp_colour = g_simgraph->palette_lookup(colours[0]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
 		}
 		else if (env_t::hide_buildings == env_t::ALL_HIDDEN_BUILDING && tile->get_desc()->get_type() < building_desc_t::others) {
 			// special building
-			disp_colour = color_idx_to_rgb(colours[tile->get_desc()->get_type()]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
+			disp_colour = g_simgraph->palette_lookup(colours[tile->get_desc()->get_type()]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
 		}
 	}
 	return disp_colour;
@@ -428,7 +428,7 @@ void gebaeude_t::display(int xpos, int ypos  CLIP_NUM_DEF) const
 {
 	const bool is_dirty = get_flag(obj_t::dirty);
 	uint8 owner_n = get_owner_nr();
-	const int raster_width = get_current_tile_raster_width();
+	const int raster_width = g_simgraph->get_current_tile_raster_width();
 	ypos += tile_raster_scale_y(get_yoff(), raster_width); // if there is a slope below
 
 	if (env_t::hide_buildings != 0 && env_t::hide_with_transparency && !zeige_baugrube) {
@@ -440,34 +440,34 @@ void gebaeude_t::display(int xpos, int ypos  CLIP_NUM_DEF) const
 		uint8 colours[] = { COL_BLACK, COL_YELLOW, COL_YELLOW, COL_PURPLE, COL_RED, COL_GREEN };
 		FLAGGED_PIXVAL disp_colour = 0;
 		if (is_city_building()) {
-			disp_colour = color_idx_to_rgb(colours[0]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
+			disp_colour = g_simgraph->palette_lookup(colours[0]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
 		}
 		else if (env_t::hide_buildings == env_t::ALL_HIDDEN_BUILDING && tile->get_desc()->get_type() < building_desc_t::others) {
 			// special building
-			disp_colour = color_idx_to_rgb(colours[tile->get_desc()->get_type()]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
+			disp_colour = g_simgraph->palette_lookup(colours[tile->get_desc()->get_type()]) | TRANSPARENT50_FLAG | OUTLINE_FLAG;
 		}
 
 		if (image_id ground = get_image()) {
 			if (owner_n != PLAYER_UNOWNED) {
 				if (obj_t::show_owner) {
-					display_blend(ground, xpos, ypos, owner_n, color_idx_to_rgb(welt->get_player(owner_n)->get_player_color1() + 2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+					g_simgraph->draw_blend(ground, xpos, ypos, owner_n, g_simgraph->palette_lookup(welt->get_player(owner_n)->get_player_color1() + 2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 				}
 				else {
-					display_color(ground, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
+					g_simgraph->draw_color(ground, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
 				}
 			}
 			else {
-				display_normal(ground, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_normal(ground, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
 			}
 		}
 
 		if (TRANSPARENT_FLAGS & disp_colour) {
 			// only transparent outline
-			display_blend(get_outline_image(), xpos, ypos, owner_n, disp_colour, 0, is_dirty  CLIP_NUM_PAR);
+			g_simgraph->draw_blend(get_outline_image(), xpos, ypos, owner_n, disp_colour, 0, is_dirty  CLIP_NUM_PAR);
 		}
 		else if (obj_t::get_flag(highlight)) {
 			// highlight this tile
-			display_blend(get_image(), xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+			g_simgraph->draw_blend(get_image(), xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 		}
 		// finish
 		return;
@@ -483,19 +483,19 @@ void gebaeude_t::display(int xpos, int ypos  CLIP_NUM_DEF) const
 
 			if (owner_n != PLAYER_UNOWNED) {
 				if (obj_t::show_owner) {
-					display_blend(image, xpos, ypos, owner_n, color_idx_to_rgb(welt->get_player(owner_n)->get_player_color1() + 2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+					g_simgraph->draw_blend(image, xpos, ypos, owner_n, g_simgraph->palette_lookup(welt->get_player(owner_n)->get_player_color1() + 2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 				}
 				else {
-					display_color(image, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
+					g_simgraph->draw_color(image, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
 				}
 			}
 			else {
-				display_normal(image, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_normal(image, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
 			}
 
 			if (obj_t::get_flag(highlight)) {
 				// highlight this tile
-				display_blend(image, xpos, start_ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_blend(image, xpos, start_ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 			}
 
 			// this obj has another image on top (e.g. skyscraper)
@@ -1165,7 +1165,7 @@ void gebaeude_t::mark_images_dirty() const
 	else {
 		img = tile->get_background( anim_frame, 0, season ) ;
 		for (int i = 0; img != IMG_EMPTY; ) {
-			mark_image_dirty(img, -(i * get_tile_raster_width()));
+			mark_image_dirty(img, -(i * g_simgraph->get_tile_raster_width()));
 			img = tile->get_background(anim_frame, ++i, season);
 		}
 	}
diff --git a/src/simutrans/obj/roadsign.cc b/src/simutrans/obj/roadsign.cc
index 7f76e4266..6426bec36 100644
--- a/src/simutrans/obj/roadsign.cc
+++ b/src/simutrans/obj/roadsign.cc
@@ -546,20 +546,20 @@ void roadsign_t::display_after(int xpos, int ypos, bool ) const
 #endif
 {
 	if(  foreground_image != IMG_EMPTY  ) {
-		const int raster_width = get_current_tile_raster_width();
+		const int raster_width = g_simgraph->get_current_tile_raster_width();
 		xpos += tile_raster_scale_x( after_xoffset, raster_width );
 		ypos += tile_raster_scale_y( after_yoffset, raster_width );
 		// draw with owner
 		if(  get_owner_nr() != PLAYER_UNOWNED  ) {
 			if(  obj_t::show_owner  ) {
-				display_blend( foreground_image, xpos, ypos, 0, color_idx_to_rgb(get_owner()->get_player_color1()+2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, get_flag(obj_t::dirty)  CLIP_NUM_PAR);
+				g_simgraph->draw_blend( foreground_image, xpos, ypos, 0, g_simgraph->palette_lookup(get_owner()->get_player_color1()+2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, get_flag(obj_t::dirty)  CLIP_NUM_PAR);
 			}
 			else {
-				display_color( foreground_image, xpos, ypos, get_owner_nr(), true, get_flag(obj_t::dirty)  CLIP_NUM_PAR);
+				g_simgraph->draw_color( foreground_image, xpos, ypos, get_owner_nr(), true, get_flag(obj_t::dirty)  CLIP_NUM_PAR);
 			}
 		}
 		else {
-			display_normal( foreground_image, xpos, ypos, 0, true, get_flag(obj_t::dirty)  CLIP_NUM_PAR);
+			g_simgraph->draw_normal( foreground_image, xpos, ypos, 0, true, get_flag(obj_t::dirty)  CLIP_NUM_PAR);
 		}
 	}
 }
diff --git a/src/simutrans/obj/simobj.cc b/src/simutrans/obj/simobj.cc
index cc7689d20..00228d877 100644
--- a/src/simutrans/obj/simobj.cc
+++ b/src/simutrans/obj/simobj.cc
@@ -196,7 +196,7 @@ void obj_t::display(int xpos, int ypos  CLIP_NUM_DEF) const
 	image_id image = get_image();
 	image_id const outline_image = get_outline_image();
 	if(  image!=IMG_EMPTY  ||  outline_image!=IMG_EMPTY  ) {
-		const int raster_width = get_current_tile_raster_width();
+		const int raster_width = g_simgraph->get_current_tile_raster_width();
 		const bool is_dirty = get_flag(obj_t::dirty);
 
 		if (vehicle_base_t const* const v = obj_cast<vehicle_base_t>(this)) {
@@ -208,14 +208,14 @@ void obj_t::display(int xpos, int ypos  CLIP_NUM_DEF) const
 
 		if(  owner_n != PLAYER_UNOWNED  ) {
 			if(  obj_t::show_owner  ) {
-				display_blend( image, xpos, ypos, owner_n, color_idx_to_rgb(welt->get_player(owner_n)->get_player_color1()+2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_blend( image, xpos, ypos, owner_n, g_simgraph->palette_lookup(welt->get_player(owner_n)->get_player_color1()+2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 			}
 			else {
-				display_color( image, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_color( image, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
 			}
 		}
 		else {
-			display_normal( image, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
+			g_simgraph->draw_normal( image, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
 		}
 
 		if(  outline_image != IMG_EMPTY  ) {
@@ -223,16 +223,16 @@ void obj_t::display(int xpos, int ypos  CLIP_NUM_DEF) const
 			const FLAGGED_PIXVAL transparent = get_outline_colour();
 			if(  TRANSPARENT_FLAGS&transparent  ) {
 				// only transparent outline
-				display_blend( get_outline_image(), xpos, ypos, owner_n, transparent, 0, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_blend( get_outline_image(), xpos, ypos, owner_n, transparent, 0, is_dirty  CLIP_NUM_PAR);
 			}
 			else if(  obj_t::get_flag( highlight )  ) {
 				// highlight this tile
-				display_blend( image, xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_blend( image, xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 			}
 		}
 		else if(  obj_t::get_flag( highlight )  ) {
 			// highlight this tile
-			display_blend( get_image(), xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+			g_simgraph->draw_blend( get_image(), xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 		}
 	}
 }
@@ -257,7 +257,7 @@ void obj_t::display_after(int xpos, int ypos, bool) const
 {
 	image_id image = get_front_image();
 	if(  image != IMG_EMPTY  ) {
-		const int raster_width = get_current_tile_raster_width();
+		const int raster_width = g_simgraph->get_current_tile_raster_width();
 		const bool is_dirty = get_flag( obj_t::dirty );
 
 		xpos += tile_raster_scale_x( get_xoff(), raster_width );
@@ -265,22 +265,22 @@ void obj_t::display_after(int xpos, int ypos, bool) const
 
 		if(  owner_n != PLAYER_UNOWNED  ) {
 			if(  obj_t::show_owner  ) {
-				display_blend( image, xpos, ypos, owner_n, color_idx_to_rgb(welt->get_player(owner_n)->get_player_color1()+2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_blend( image, xpos, ypos, owner_n, g_simgraph->palette_lookup(welt->get_player(owner_n)->get_player_color1()+2) | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 			}
 			else if(  obj_t::get_flag( highlight )  ) {
 				// highlight this tile
-				display_blend( image, xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_blend( image, xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 			}
 			else {
-				display_color( image, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
+				g_simgraph->draw_color( image, xpos, ypos, owner_n, true, is_dirty  CLIP_NUM_PAR);
 			}
 		}
 		else if(  obj_t::get_flag( highlight )  ) {
 			// highlight this tile
-			display_blend( image, xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
+			g_simgraph->draw_blend( image, xpos, ypos, owner_n, SYSCOL_OBJECT_HIGHLIGHT | OUTLINE_FLAG | TRANSPARENT75_FLAG, 0, is_dirty  CLIP_NUM_PAR);
 		}
 		else {
-			display_normal( image, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
+			g_simgraph->draw_normal( image, xpos, ypos, 0, true, is_dirty  CLIP_NUM_PAR);
 		}
 	}
 }
@@ -293,12 +293,12 @@ void obj_t::display_after(int xpos, int ypos, bool) const
 void obj_t::mark_image_dirty(image_id image, sint16 yoff) const
 {
 	if(  image != IMG_EMPTY  ) {
-		const sint16 rasterweite = get_tile_raster_width();
+		const sint16 rasterweite = g_simgraph->get_tile_raster_width();
 		int xpos=0, ypos=0;
 		if(  is_moving()  ) {
 			vehicle_base_t const* const v = obj_cast<vehicle_base_t>(this);
 			// vehicles need finer steps to appear smoother
-			v->get_screen_offset( xpos, ypos, get_tile_raster_width() );
+			v->get_screen_offset( xpos, ypos, g_simgraph->get_tile_raster_width() );
 		}
 
 		viewport_t *vp = welt->get_viewport();
@@ -306,15 +306,16 @@ void obj_t::mark_image_dirty(image_id image, sint16 yoff) const
 		// xpos, ypos, yoff are already in pixel units, no scaling needed
 
 		// mark the region after the image as dirty
-		display_mark_img_dirty( image, scr_pos.x + xpos, scr_pos.y + ypos + yoff);
+		g_simgraph->mark_img_dirty(image, scr_pos.x + xpos, scr_pos.y + ypos + yoff);
 
 		// too close to border => set dirty to be sure (smoke, skyscrapers, birds, or the like)
-		scr_coord_val xbild = 0, ybild = 0, wbild = 0, hbild = 0;
-		display_get_image_offset( image, &xbild, &ybild, &wbild, &hbild );
-		const sint16 distance_to_border = 3 - (yoff+get_yoff()+ybild)/(rasterweite/4);
+		const scr_rect r = g_simgraph->get_image_offset(image);
+		const sint16 distance_to_border = 3 - (yoff+get_yoff()+r.y)/(rasterweite/4);
 		if(  pos.x <= distance_to_border  ||  pos.y <= distance_to_border  ) {
 			// but only if the image is actually visible ...
-			if(   scr_pos.x+xbild+wbild >= 0  &&  xpos <= display_get_width()  &&   scr_pos.y+ybild+hbild >= 0  &&  ypos+ybild < display_get_height()  ) {
+			const scr_size screen = g_simgraph->get_screen_size();
+
+			if(   scr_pos.x+r.x+r.w >= 0  &&  xpos <= screen.w  &&   scr_pos.y+r.y+r.h >= 0  &&  ypos+r.y < screen.h  ) {
 				welt->set_background_dirty();
 			}
 		}
diff --git a/src/simutrans/obj/way/schiene.cc b/src/simutrans/obj/way/schiene.cc
index e5d30b0ed..493f6ce9c 100644
--- a/src/simutrans/obj/way/schiene.cc
+++ b/src/simutrans/obj/way/schiene.cc
@@ -174,10 +174,10 @@ void schiene_t::rdwr(loadsave_t *file)
 FLAGGED_PIXVAL schiene_t::get_outline_colour() const
 {
 	if (env_t::show_single_ways  &&  ribi_t::is_single(get_ribi_unmasked())) {
-		return TRANSPARENT75_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_RED);
+		return TRANSPARENT75_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_RED);
 	}
 	if (show_reservations  &&  reserved.is_bound()) {
-		return TRANSPARENT75_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_RED);
+		return TRANSPARENT75_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_RED);
 	}
 
 	return 0;
diff --git a/src/simutrans/obj/way/weg.cc b/src/simutrans/obj/way/weg.cc
index ab6aac947..b8844cea0 100644
--- a/src/simutrans/obj/way/weg.cc
+++ b/src/simutrans/obj/way/weg.cc
@@ -674,7 +674,7 @@ const char *weg_t::get_removal_error(const player_t *player)
 FLAGGED_PIXVAL weg_t::get_outline_colour() const
 {
 	if (env_t::show_single_ways  &&  ribi_t::is_single(ribi)) {
-		return TRANSPARENT75_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_RED);
+		return TRANSPARENT75_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_RED);
 	}
 
 	return 0;
diff --git a/src/simutrans/obj/wolke.cc b/src/simutrans/obj/wolke.cc
index 7c1840f44..7c76fab47 100644
--- a/src/simutrans/obj/wolke.cc
+++ b/src/simutrans/obj/wolke.cc
@@ -68,7 +68,7 @@ image_id wolke_t::get_front_image() const
 
 sint16 wolke_t::calc_yoff() const
 {
-	return tile_raster_scale_y( base_y_off - (((long)insta_zeit * uplift * OBJECT_OFFSET_STEPS) >> 16), get_current_tile_raster_width() );
+	return tile_raster_scale_y( base_y_off - (((long)insta_zeit * uplift * OBJECT_OFFSET_STEPS) >> 16), g_simgraph->get_current_tile_raster_width() );
 }
 
 
diff --git a/src/simutrans/player/simplay.cc b/src/simutrans/player/simplay.cc
index 4293f7041..b8227b869 100644
--- a/src/simutrans/player/simplay.cc
+++ b/src/simutrans/player/simplay.cc
@@ -120,7 +120,8 @@ sint64 player_t::add_maintenance(sint64 change, waytype_t const wt)
 void player_t::add_money_message(const sint64 amount, const koord pos)
 {
 	if(amount != 0  &&  player_nr != 1) {
-		if(  koord_distance(welt->get_viewport()->get_world_position(),pos)<2*(uint32)(display_get_width()/get_tile_raster_width())+3  ) {
+		const scr_size screen = g_simgraph->get_screen_size();
+		if(  koord_distance(welt->get_viewport()->get_world_position(),pos)<2*(uint32)(screen.w / g_simgraph->get_tile_raster_width())+3  ) {
 			// only display, if near the screen ...
 			add_message(amount, pos);
 
@@ -220,9 +221,9 @@ void player_t::display_messages()
 
 	for(income_message_t* const m : messages) {
 
-		const scr_coord scr_pos = vp->get_screen_coord(koord3d(m->pos,welt->lookup_hgt(m->pos)),koord(0,m->alter >> 4)) + scr_coord((get_tile_raster_width()-display_calc_proportional_string_len_width(m->str, 0x7FFF))/2,0);
+		const scr_coord scr_pos = vp->get_screen_coord(koord3d(m->pos,welt->lookup_hgt(m->pos)),koord(0,m->alter >> 4)) + scr_coord((g_simgraph->get_tile_raster_width()-g_simgraph->calc_text_width_n(m->str, 0x7FFF))/2,0);
 
-		display_shadow_proportional_rgb( scr_pos.x, scr_pos.y, PLAYER_FLAG|color_idx_to_rgb(player_color_1+3), color_idx_to_rgb(COL_BLACK), m->str, true);
+		g_simgraph->draw_text_shadowed( scr_pos.x, scr_pos.y, PLAYER_FLAG|g_simgraph->palette_lookup(player_color_1+3), g_simgraph->palette_lookup(COL_BLACK), m->str, true);
 		if(  m->pos.x < 3  ||  m->pos.y < 3  ) {
 			// very close to border => renew background
 			welt->set_background_dirty();
@@ -267,7 +268,9 @@ void player_t::set_player_color(uint8 col1, uint8 col2)
 {
 	player_color_1 = col1;
 	player_color_2 = col2;
-	display_set_player_color_scheme( player_nr, col1, col2 );
+
+	g_simgraph->set_player_color_scheme(player_nr, col1, col2);
+
 	// update player window
 	if (ki_kontroll_t* frame = dynamic_cast<ki_kontroll_t*>(win_get_magic(magic_ki_kontroll_t))) {
 		frame->update_data();
@@ -299,7 +302,7 @@ bool player_t::new_month()
 			if(  welt->get_active_player_nr()==player_nr  &&  !env_t::networkmode  ) {
 				if(  finance->get_netwealth() < 0 ) {
 					destroy_all_win(true);
-					create_win({ display_get_width()/2-128, 40 }, new news_img("Bankrott:\n\nDu bist bankrott.\n"), w_info, magic_none);
+					create_win({ g_simgraph->get_screen_size().w/2-128, 40 }, new news_img("Bankrott:\n\nDu bist bankrott.\n"), w_info, magic_none);
 					ticker::add_msg( translator::translate("Bankrott:\n\nDu bist bankrott.\n"), koord3d::invalid, PLAYER_FLAG | player_nr );
 					welt->stop(false);
 				}
@@ -766,7 +769,9 @@ DBG_DEBUG("player_t::rdwr()","player %i: loading %i halts.",welt->sp2num( this )
 void player_t::finish_rd()
 {
 	simlinemgmt.finish_rd();
-	display_set_player_color_scheme( player_nr, player_color_1, player_color_2 );
+
+	g_simgraph->set_player_color_scheme(player_nr, player_color_1, player_color_2);
+
 	// recalculate vehicle value
 	calc_assets();
 
diff --git a/src/simutrans/simcolor.h b/src/simutrans/simcolor.h
index c3632e4f0..8a6ef77bb 100644
--- a/src/simutrans/simcolor.h
+++ b/src/simutrans/simcolor.h
@@ -68,8 +68,8 @@ typedef unsigned int FLAGGED_PIXVAL;
 #define COL_DARK_BROWN      178
 
 // message colors
-#define CITY_KI             color_idx_to_rgb(209)
-#define NEW_VEHICLE         color_idx_to_rgb(COL_PURPLE)
+#define CITY_KI             g_simgraph->palette_lookup(209)
+#define NEW_VEHICLE         g_simgraph->palette_lookup(COL_PURPLE)
 
 // by niels
 #define COL_GREY1           208
@@ -80,15 +80,15 @@ typedef unsigned int FLAGGED_PIXVAL;
 #define COL_GREY6           15
 
 // Way colours for the map
-#define COL_ROAD            color_idx_to_rgb(COL_GREY1)
-#define COL_RAIL            color_idx_to_rgb(185)
-#define COL_CANAL           color_idx_to_rgb(23)
-#define COL_MONORAIL        color_idx_to_rgb(COL_ORANGE)
-#define COL_RUNWAY          color_idx_to_rgb(28)
-#define COL_POWERLINE       color_idx_to_rgb(COL_LIGHT_TURQUOISE)
-#define COL_HALT            color_idx_to_rgb(COL_RED)
-#define COL_BUILDING        color_idx_to_rgb(COL_GREY3)
-#define COL_VEHICLE         color_idx_to_rgb(COL_YELLOW)
+#define COL_ROAD            g_simgraph->palette_lookup(COL_GREY1)
+#define COL_RAIL            g_simgraph->palette_lookup(185)
+#define COL_CANAL           g_simgraph->palette_lookup(23)
+#define COL_MONORAIL        g_simgraph->palette_lookup(COL_ORANGE)
+#define COL_RUNWAY          g_simgraph->palette_lookup(28)
+#define COL_POWERLINE       g_simgraph->palette_lookup(COL_LIGHT_TURQUOISE)
+#define COL_HALT            g_simgraph->palette_lookup(COL_RED)
+#define COL_BUILDING        g_simgraph->palette_lookup(COL_GREY3)
+#define COL_VEHICLE         g_simgraph->palette_lookup(COL_YELLOW)
 
 // used in many dialogues graphs
 #define COL_REVENUE         142
diff --git a/src/simutrans/simconvoi.cc b/src/simutrans/simconvoi.cc
index 0c18540a2..a8b796a0f 100644
--- a/src/simutrans/simconvoi.cc
+++ b/src/simutrans/simconvoi.cc
@@ -3626,7 +3626,7 @@ PIXVAL convoi_t::get_status_color() const
 	}
 	else if (state == WAITING_FOR_CLEARANCE_ONE_MONTH || state == CAN_START_ONE_MONTH || get_state() == NO_ROUTE) {
 		// stuck or no route
-		return color_idx_to_rgb(COL_ORANGE);
+		return g_simgraph->palette_lookup(COL_ORANGE);
 	}
 	else if(financial_history[0][CONVOI_PROFIT]+financial_history[1][CONVOI_PROFIT]<0) {
 		// ok, not performing best
diff --git a/src/simutrans/simfab.cc b/src/simutrans/simfab.cc
index 408826c29..e2324dd2c 100644
--- a/src/simutrans/simfab.cc
+++ b/src/simutrans/simfab.cc
@@ -3366,13 +3366,13 @@ void fabrik_t::display_status(sint16 xpos, sint16 ypos)
 	const sint16 count = input.get_count()+output.get_count();
 
 	ypos += -D_WAITINGBAR_WIDTH - LINESPACE/6;
-	xpos -= (count * D_WAITINGBAR_WIDTH - get_tile_raster_width()) / 2;
+	xpos -= (count * D_WAITINGBAR_WIDTH - g_simgraph->get_tile_raster_width()) / 2;
 
 	if( input.get_count() ) {
 		if(  currently_producing  ) {
-			display_ddd_box_clip_rgb(xpos-2,  ypos-1, D_WAITINGBAR_WIDTH*input.get_count()+4, 6, color_idx_to_rgb(10), color_idx_to_rgb(12));
+			g_simgraph->draw_box3d_clipped(xpos-2,  ypos-1, D_WAITINGBAR_WIDTH*input.get_count()+4, 6, g_simgraph->palette_lookup(10), g_simgraph->palette_lookup(12));
 		}
-		display_fillbox_wh_clip_rgb(xpos-1, ypos, D_WAITINGBAR_WIDTH*input.get_count()+2, 4, color_idx_to_rgb(150), true);
+		g_simgraph->draw_rect_clipped(xpos-1, ypos, D_WAITINGBAR_WIDTH*input.get_count()+2, 4, g_simgraph->palette_lookup(150), true CLIP_NUM_DEFAULT);
 
 		for(uint32 i=0; i < input.get_count(); i++) {
 			ware_production_t const& goods = input[i];
@@ -3389,13 +3389,13 @@ void fabrik_t::display_status(sint16 xpos, sint16 ypos)
 				const uint16 v = min(25, (uint16)(25 * stock_quantity / storage_capacity)) + 2;
 
 				if (currently_producing) {
-					display_fillbox_wh_clip_rgb(xpos, ypos - v - 1, 1, v, color_idx_to_rgb(COL_GREY4), true);
-					display_fillbox_wh_clip_rgb(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, true);
-					display_fillbox_wh_clip_rgb(xpos + D_WAITINGBAR_WIDTH - 1, ypos - v - 1, 1, v, color_idx_to_rgb(COL_GREY1), true);
+					g_simgraph->draw_rect_clipped(xpos, ypos - v - 1, 1, v, g_simgraph->palette_lookup(COL_GREY4), true CLIP_NUM_DEFAULT);
+					g_simgraph->draw_rect_clipped(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, true CLIP_NUM_DEFAULT);
+					g_simgraph->draw_rect_clipped(xpos + D_WAITINGBAR_WIDTH - 1, ypos - v - 1, 1, v, g_simgraph->palette_lookup(COL_GREY1), true CLIP_NUM_DEFAULT);
 				}
 				else {
-					display_blend_wh_rgb(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, 60);
-					mark_rect_dirty_wc(xpos + 1, ypos - v - 1, xpos + D_WAITINGBAR_WIDTH - 1, ypos - 1);
+					g_simgraph->tint_rect(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, 60);
+					g_simgraph->mark_rect_dirty_wc(xpos + 1, ypos - v - 1, xpos + D_WAITINGBAR_WIDTH - 1, ypos - 1);
 				}
 			}
 
@@ -3406,9 +3406,9 @@ void fabrik_t::display_status(sint16 xpos, sint16 ypos)
 
 	if( output.get_count() ) {
 		if(  currently_producing  ) {
-			display_ddd_box_clip_rgb(xpos-2,  ypos-1, D_WAITINGBAR_WIDTH*output.get_count()+4, 6, color_idx_to_rgb(10), color_idx_to_rgb(12));
+			g_simgraph->draw_box3d_clipped(xpos-2,  ypos-1, D_WAITINGBAR_WIDTH*output.get_count()+4, 6, g_simgraph->palette_lookup(10), g_simgraph->palette_lookup(12));
 		}
-		display_fillbox_wh_clip_rgb(xpos-1, ypos, D_WAITINGBAR_WIDTH*output.get_count()+2, 4, color_idx_to_rgb(COL_ORANGE), true);
+		g_simgraph->draw_rect_clipped(xpos-1, ypos, D_WAITINGBAR_WIDTH*output.get_count()+2, 4, g_simgraph->palette_lookup(COL_ORANGE), true CLIP_NUM_DEFAULT);
 
 		for(uint32 i=0; i < output.get_count(); i++) {
 			ware_production_t const& goods = output[i];
@@ -3424,13 +3424,13 @@ void fabrik_t::display_status(sint16 xpos, sint16 ypos)
 
 				// the blended bars are too faint for me
 				if (currently_producing) {
-					display_fillbox_wh_clip_rgb(xpos, ypos - v - 1, 1, v, color_idx_to_rgb(COL_GREY4), true);
-					display_fillbox_wh_clip_rgb(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, true);
-					display_fillbox_wh_clip_rgb(xpos + D_WAITINGBAR_WIDTH - 1, ypos - v - 1, 1, v, color_idx_to_rgb(COL_GREY1), true);
+					g_simgraph->draw_rect_clipped(xpos, ypos - v - 1, 1, v, g_simgraph->palette_lookup(COL_GREY4), true CLIP_NUM_DEFAULT);
+					g_simgraph->draw_rect_clipped(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, true CLIP_NUM_DEFAULT);
+					g_simgraph->draw_rect_clipped(xpos + D_WAITINGBAR_WIDTH - 1, ypos - v - 1, 1, v, g_simgraph->palette_lookup(COL_GREY1), true CLIP_NUM_DEFAULT);
 				}
 				else {
-					display_blend_wh_rgb(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, 60);
-					mark_rect_dirty_wc(xpos + 1, ypos - v - 1, xpos + D_WAITINGBAR_WIDTH - 1, ypos - 1);
+					g_simgraph->tint_rect(xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, goods_color, 60);
+					g_simgraph->mark_rect_dirty_wc(xpos + 1, ypos - v - 1, xpos + D_WAITINGBAR_WIDTH - 1, ypos - 1);
 				}
 			}
 
diff --git a/src/simutrans/simhalt.cc b/src/simutrans/simhalt.cc
index 7953b5cf8..6a8452a7f 100644
--- a/src/simutrans/simhalt.cc
+++ b/src/simutrans/simhalt.cc
@@ -467,7 +467,7 @@ haltestelle_t::haltestelle_t(loadsave_t* file)
 	halt_served_this_step = new vector_tpl<halthandle_t>[goods_manager_t::get_max_catg_index()];
 
 	status_color = SYSCOL_TEXT_UNUSED;
-	last_status_color = color_idx_to_rgb(COL_PURPLE);
+	last_status_color = g_simgraph->palette_lookup(COL_PURPLE);
 	last_bar_count = 0;
 
 	reconnect_counter = welt->get_schedule_counter()-1;
@@ -507,7 +507,7 @@ haltestelle_t::haltestelle_t(koord k, player_t* player)
 	halt_served_this_step = new vector_tpl<halthandle_t>[goods_manager_t::get_max_catg_index()];
 
 	status_color = SYSCOL_TEXT_UNUSED;
-	last_status_color = color_idx_to_rgb(COL_PURPLE);
+	last_status_color = g_simgraph->palette_lookup(COL_PURPLE);
 	last_bar_count = 0;
 
 	init_financial_history();
@@ -1054,7 +1054,7 @@ bool haltestelle_t::step(uint8 what, sint16 &units_remaining)
  */
 void haltestelle_t::new_month()
 {
-	if(  welt->get_active_player()==owner  &&  status_color==color_idx_to_rgb(COL_RED)  ) {
+	if(  welt->get_active_player()==owner  &&  status_color==g_simgraph->palette_lookup(COL_RED)  ) {
 		cbuffer_t buf;
 		buf.printf( translator::translate("%s\nis crowded."), get_name() );
 		welt->get_message()->add_message(buf, get_basis_pos3d(),message_t::full|message_t::EXPIRE_AFTER_ONE_MONTH_MSG, PLAYER_FLAG|owner->get_player_nr(), IMG_EMPTY );
@@ -3065,7 +3065,7 @@ void haltestelle_t::init_financial_history()
  */
 void haltestelle_t::recalc_status()
 {
-	status_color = color_idx_to_rgb(financial_history[0][HALT_CONVOIS_ARRIVED] > 0 ? COL_GREEN : COL_YELLOW);
+	status_color = g_simgraph->palette_lookup(financial_history[0][HALT_CONVOIS_ARRIVED] > 0 ? COL_GREEN : COL_YELLOW);
 
 	// since the status is ordered ...
 	uint8 status_bits = 0;
@@ -3098,7 +3098,7 @@ void haltestelle_t::recalc_status()
 	}
 
 	// now for all goods
-	if(status_color!=color_idx_to_rgb(COL_RED)  &&  get_ware_enabled()) {
+	if(status_color!=g_simgraph->palette_lookup(COL_RED)  &&  get_ware_enabled()) {
 		const uint8  count = goods_manager_t::get_count();
 		const uint32 max_ware = get_capacity(2);
 		for(  uint32 i = 3;  i < count;  i++  ) {
@@ -3114,10 +3114,10 @@ void haltestelle_t::recalc_status()
 
 	// take the worst color for status
 	if(  status_bits  ) {
-		status_color = color_idx_to_rgb(status_bits&2 ? COL_RED : COL_ORANGE);
+		status_color = g_simgraph->palette_lookup(status_bits&2 ? COL_RED : COL_ORANGE);
 	}
 	else {
-		status_color = color_idx_to_rgb((financial_history[0][HALT_WAITING]+financial_history[0][HALT_DEPARTED] == 0) ? COL_YELLOW : COL_GREEN);
+		status_color = g_simgraph->palette_lookup((financial_history[0][HALT_WAITING]+financial_history[0][HALT_DEPARTED] == 0) ? COL_YELLOW : COL_GREEN);
 	}
 
 	financial_history[0][HALT_WAITING] = total_sum;
@@ -3150,8 +3150,8 @@ void haltestelle_t::display_status(sint16 xpos, sint16 ypos)
 				max_bar_height = last_bar_height[i];
 			}
 		}
-		const scr_coord_val x = xpos - (last_bar_count * D_WAITINGBAR_WIDTH - get_tile_raster_width()) / 2;
-		mark_rect_dirty_wc( x - 1 - D_WAITINGBAR_WIDTH, ypos, x + last_bar_count * D_WAITINGBAR_WIDTH + 12 - 2, ypos - 11 );
+		const scr_coord_val x = xpos - (last_bar_count * D_WAITINGBAR_WIDTH - g_simgraph->get_tile_raster_width()) / 2;
+		g_simgraph->mark_rect_dirty_wc( x - 1 - D_WAITINGBAR_WIDTH, ypos, x + last_bar_count * D_WAITINGBAR_WIDTH + 12 - 2, ypos - 11 );
 
 		// reset bar heights for new count
 		last_bar_height.clear();
@@ -3162,7 +3162,7 @@ void haltestelle_t::display_status(sint16 xpos, sint16 ypos)
 		last_bar_count = count;
 	}
 
-	xpos -= (count * D_WAITINGBAR_WIDTH - get_tile_raster_width()) / 2;
+	xpos -= (count * D_WAITINGBAR_WIDTH - g_simgraph->get_tile_raster_width()) / 2;
 	const int x = xpos;
 
 	sint16 bar_height_index = 0;
@@ -3188,25 +3188,25 @@ void haltestelle_t::display_status(sint16 xpos, sint16 ypos)
 				v = (v / 4) + 2;
 			}
 
-			display_fillbox_wh_clip_rgb( xpos, ypos - v - 1, 1, v, color_idx_to_rgb( COL_GREY4 ), false );
-			display_fillbox_wh_clip_rgb( xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, wtyp->get_color(), false );
-			display_fillbox_wh_clip_rgb( xpos + D_WAITINGBAR_WIDTH - 1, ypos - v - 1, 1, v, color_idx_to_rgb( COL_GREY1 ), false );
+			g_simgraph->draw_rect_clipped( xpos, ypos - v - 1, 1, v, g_simgraph->palette_lookup( COL_GREY4 ), false CLIP_NUM_DEFAULT);
+			g_simgraph->draw_rect_clipped( xpos + 1, ypos - v - 1, D_WAITINGBAR_WIDTH - 2, v, wtyp->get_color(), false CLIP_NUM_DEFAULT);
+			g_simgraph->draw_rect_clipped( xpos + D_WAITINGBAR_WIDTH - 1, ypos - v - 1, 1, v, g_simgraph->palette_lookup( COL_GREY1 ), false CLIP_NUM_DEFAULT);
 
 			// show up arrow for capped values
 			if(  sum > max_capacity  ) {
-				display_fillbox_wh_clip_rgb( xpos + (D_WAITINGBAR_WIDTH / 2) - 1, ypos - v - 6, 2, 4, color_idx_to_rgb( COL_WHITE ), false );
-				display_fillbox_wh_clip_rgb( xpos + (D_WAITINGBAR_WIDTH / 2) - 2, ypos - v - 5, 4, 1, color_idx_to_rgb( COL_WHITE ), false );
+				g_simgraph->draw_rect_clipped( xpos + (D_WAITINGBAR_WIDTH / 2) - 1, ypos - v - 6, 2, 4, g_simgraph->palette_lookup( COL_WHITE ), false CLIP_NUM_DEFAULT);
+				g_simgraph->draw_rect_clipped( xpos + (D_WAITINGBAR_WIDTH / 2) - 2, ypos - v - 5, 4, 1, g_simgraph->palette_lookup( COL_WHITE ), false CLIP_NUM_DEFAULT);
 				v += 5; // for marking dirty
 			}
 
 			if(  last_bar_height[bar_height_index] != (scr_coord_val)v  ) {
 				if(  (scr_coord_val)v > last_bar_height[bar_height_index]  ) {
 					// bar will be longer, mark new height dirty
-					mark_rect_dirty_wc( xpos, ypos - v - 1, xpos + D_WAITINGBAR_WIDTH, ypos - 1 );
+					g_simgraph->mark_rect_dirty_wc( xpos, ypos - v - 1, xpos + D_WAITINGBAR_WIDTH, ypos - 1 );
 				}
 				else {
 					// bar will be shorter, mark old height dirty
-					mark_rect_dirty_wc( xpos, ypos - last_bar_height[ bar_height_index ] - 1, xpos + D_WAITINGBAR_WIDTH, ypos - 1 );
+					g_simgraph->mark_rect_dirty_wc( xpos, ypos - last_bar_height[ bar_height_index ] - 1, xpos + D_WAITINGBAR_WIDTH, ypos - 1 );
 				}
 				last_bar_height[bar_height_index] = v;
 			}
@@ -3222,7 +3222,7 @@ void haltestelle_t::display_status(sint16 xpos, sint16 ypos)
 		last_status_color = get_status_farbe();
 		dirty = true;
 	}
-	display_fillbox_wh_clip_rgb( x - 1 - 4, ypos, count * D_WAITINGBAR_WIDTH + 12 - 2, D_WAITINGBAR_WIDTH, get_status_farbe(), dirty );
+	g_simgraph->draw_rect_clipped( x - 1 - 4, ypos, count * D_WAITINGBAR_WIDTH + 12 - 2, D_WAITINGBAR_WIDTH, get_status_farbe(), dirty CLIP_NUM_DEFAULT);
 }
 
 
diff --git a/src/simutrans/siminteraction.cc b/src/simutrans/siminteraction.cc
index 119d5387c..32e10b619 100644
--- a/src/simutrans/siminteraction.cc
+++ b/src/simutrans/siminteraction.cc
@@ -211,7 +211,7 @@ void interaction_t::interactive_event( const event_t &ev )
 		}
 	}
 
-	if(  !is_dragging  &&  IS_LEFTRELEASE(&ev)  &&  ev.mouse_pos.y < display_get_height() -16 -(TICKER_HEIGHT*ticker::empty())  ) {
+	if(  !is_dragging  &&  IS_LEFTRELEASE(&ev)  &&  ev.mouse_pos.y < g_simgraph->get_screen_size().h -16 -(TICKER_HEIGHT*ticker::empty())  ) {
 
 		DBG_MESSAGE("interaction_t::interactive_event(event_t &ev)", "calling a tool");
 
@@ -314,10 +314,10 @@ bool interaction_t::process_event( event_t &ev )
 
 	// Handle map drag with right-click
 	if(IS_RIGHTCLICK(&ev)) {
-		display_show_pointer(false);
+		g_simgraph->set_cursor_visible(false);
 	}
 	else if(IS_RIGHTRELEASE(&ev)) {
-		display_show_pointer(true);
+		g_simgraph->set_cursor_visible(true);
 	}
 	else if(IS_RIGHTDRAG(&ev)) {
 		// unset following
@@ -328,9 +328,9 @@ bool interaction_t::process_event( event_t &ev )
 	else if(  IS_LEFTDRAG(&ev)  &&  IS_LEFT_BUTTON_PRESSED(&ev)  &&  (is_world_dragging  ||  (!world->get_tool(world->get_active_player_nr())->move_has_effects()  &&  !IS_CONTROL_PRESSED(&ev))  )  ) {
 		/* ok, we have a general tool selected, and we have a left drag or left release event with an actual difference
 		 * => move the map, if we are beyond a threshold */
-		if(  is_world_dragging  ||  abs(ev.click_pos.x-ev.mouse_pos.x)+abs(ev.click_pos.y-ev.mouse_pos.y)>=max(1,(env_t::scroll_threshold* get_tile_raster_width())/get_base_tile_raster_width())  ) {
+		if(  is_world_dragging  ||  abs(ev.click_pos.x-ev.mouse_pos.x)+abs(ev.click_pos.y-ev.mouse_pos.y)>=max(1,(env_t::scroll_threshold * g_simgraph->get_tile_raster_width()) / g_simgraph->get_base_tile_raster_width())  ) {
 			if (!is_world_dragging) {
-				display_show_pointer(false);
+				g_simgraph->set_cursor_visible(false);
 				is_world_dragging = true;
 			}
 			world->get_viewport()->set_follow_convoi(convoihandle_t());
@@ -343,7 +343,7 @@ bool interaction_t::process_event( event_t &ev )
 	if( !IS_LEFT_BUTTON_PRESSED(&ev)  &&  is_world_dragging  ) {
 		// show the mouse and swallow this event if we were dragging before
 		ev.ev_code = IGNORE_EVENT;
-		display_show_pointer(true);
+		g_simgraph->set_cursor_visible(true);
 		is_world_dragging = false;
 	}
 
diff --git a/src/simutrans/simloadingscreen.cc b/src/simutrans/simloadingscreen.cc
index 14865f015..40ae57c46 100644
--- a/src/simutrans/simloadingscreen.cc
+++ b/src/simutrans/simloadingscreen.cc
@@ -27,13 +27,14 @@ loadingscreen_t::loadingscreen_t( const char *w, uint32 max_p, bool logo, bool c
 	last_bar_len = -1;
 	show_logo = logo;
 
-	if(  !is_display_init()  ||  continueflag  ) {
+	if(  !g_simgraph->is_display_init()  ||  continueflag  ) {
 		return;
 	}
 
 	// darkens the current screen
-	display_blend_wh_rgb(0, 0, display_get_width(), display_get_height(), color_idx_to_rgb(COL_BLACK), 50 );
-	mark_screen_dirty();
+	const scr_size screen = g_simgraph->get_screen_size();
+	g_simgraph->tint_rect(0, 0, screen.w, screen.h, g_simgraph->palette_lookup(COL_BLACK), 50 );
+	g_simgraph->mark_screen_dirty();
 
 	display_logo();
 }
@@ -43,19 +44,20 @@ loadingscreen_t::loadingscreen_t( const char *w, uint32 max_p, bool logo, bool c
 void loadingscreen_t::display_logo()
 {
 	if(  show_logo  &&  skinverwaltung_t::biglogosymbol  ) {
+		const scr_size screen = g_simgraph->get_screen_size();
 		const image_t *image0 = skinverwaltung_t::biglogosymbol->get_image(0);
 		const int w = image0->w;
 		const int h = image0->h + image0->y;
-		int x = display_get_width()/2-w;
-		int y = display_get_height()/4-w;
+		int x = screen.w/2-w;
+		int y = screen.h/4-w;
 		if(y<0) {
 			y = 1;
 		}
 
-		display_color_img(skinverwaltung_t::biglogosymbol->get_image_id(0), x, y, 0, false, true);
-		display_color_img(skinverwaltung_t::biglogosymbol->get_image_id(1), x+w, y, 0, false, true);
-		display_color_img(skinverwaltung_t::biglogosymbol->get_image_id(2), x, y+h, 0, false, true);
-		display_color_img(skinverwaltung_t::biglogosymbol->get_image_id(3), x+w, y+h, 0, false, true);
+		g_simgraph->draw_color_img(skinverwaltung_t::biglogosymbol->get_image_id(0), x,   y,   0, false, true CLIP_NUM_DEFAULT);
+		g_simgraph->draw_color_img(skinverwaltung_t::biglogosymbol->get_image_id(1), x+w, y,   0, false, true CLIP_NUM_DEFAULT);
+		g_simgraph->draw_color_img(skinverwaltung_t::biglogosymbol->get_image_id(2), x,   y+h, 0, false, true CLIP_NUM_DEFAULT);
+		g_simgraph->draw_color_img(skinverwaltung_t::biglogosymbol->get_image_id(3), x+w, y+h, 0, false, true CLIP_NUM_DEFAULT);
 	}
 }
 
@@ -63,10 +65,11 @@ void loadingscreen_t::display_logo()
 // show everything but the logo
 void loadingscreen_t::display()
 {
-	const int width = display_get_width();
-	const int half_width = width>>1;
-	const int quarter_width = width>>2;
-	const int half_height = display_get_height()>>1;
+	const scr_size screen = g_simgraph->get_screen_size();
+	const int half_width    = screen.w / 2;
+	const int quarter_width = screen.w / 4;
+	const int half_height   = screen.h / 2;
+
 	scr_coord_val const bar_height = max(LINESPACE + 10, 20);
 	scr_coord_val const bar_y = half_height - bar_height / 2 + 1;
 	scr_coord_val const bar_text_y = half_height - LINESPACE / 2 + 1;
@@ -79,21 +82,21 @@ void loadingscreen_t::display()
 		dr_prepare_flush();
 
 		if(  info  ) {
-			display_proportional_rgb( half_width, bar_y - LINESPACE - 2, info, ALIGN_CENTER_H, color_idx_to_rgb(COL_WHITE), true );
+			g_simgraph->draw_text( half_width, bar_y - LINESPACE - 2, info, ALIGN_CENTER_H, g_simgraph->palette_lookup(COL_WHITE), true );
 		}
 
 		// outline
-		display_ddd_box_rgb( quarter_width-2, bar_y, half_width+4, bar_height, color_idx_to_rgb(COL_GREY6), color_idx_to_rgb(COL_GREY4), true );
-		display_ddd_box_rgb( quarter_width-1, bar_y + 1, half_width+2, bar_height - 2, color_idx_to_rgb(COL_GREY4), color_idx_to_rgb(COL_GREY6), true );
+		g_simgraph->draw_box3d(quarter_width-2, bar_y,     half_width+4, bar_height,     g_simgraph->palette_lookup(COL_GREY6), g_simgraph->palette_lookup(COL_GREY4), true);
+		g_simgraph->draw_box3d(quarter_width-1, bar_y + 1, half_width+2, bar_height - 2, g_simgraph->palette_lookup(COL_GREY4), g_simgraph->palette_lookup(COL_GREY6), true);
 
 		// inner
-		display_fillbox_wh_rgb( quarter_width, bar_y + 2, half_width, bar_height - 4, SYSCOL_LOADINGBAR_INNER, true);
+		g_simgraph->draw_rect( quarter_width, bar_y + 2, half_width, bar_height - 4, SYSCOL_LOADINGBAR_INNER, true);
 
 		// progress
-		display_fillbox_wh_rgb( quarter_width, bar_y + 4, bar_len,  bar_height - 8, SYSCOL_LOADINGBAR_PROGRESS, true );
+		g_simgraph->draw_rect( quarter_width, bar_y + 4, bar_len,  bar_height - 8, SYSCOL_LOADINGBAR_PROGRESS, true );
 
 		if(  what  ) {
-			display_proportional_rgb( half_width, bar_text_y, what, ALIGN_CENTER_H, SYSCOL_TEXT_HIGHLIGHT, false );
+			g_simgraph->draw_text( half_width, bar_text_y, what, ALIGN_CENTER_H, SYSCOL_TEXT_HIGHLIGHT, false );
 		}
 
 		dr_flush();
@@ -103,7 +106,7 @@ void loadingscreen_t::display()
 
 void loadingscreen_t::set_progress( uint32 progress )
 {
-	if(!is_display_init()  &&  (progress != this->progress  ||  progress == 0)  ) {
+	if (!g_simgraph->is_display_init()  &&  (progress != this->progress  ||  progress == 0)  ) {
 		return;
 	}
 
@@ -114,8 +117,8 @@ void loadingscreen_t::set_progress( uint32 progress )
 	if(  ev->ev_class == EVENT_SYSTEM  ) {
 		if(  ev->ev_code == SYSTEM_RESIZE  ) {
 			// main window resized
-			simgraph_resize( ev->new_window_size );
-			display_fillbox_wh_rgb( 0, 0, ev->mouse_pos.x, ev->mouse_pos.y, color_idx_to_rgb(COL_BLACK), true );
+			g_simgraph->on_window_resized( ev->new_window_size );
+			g_simgraph->draw_rect( 0, 0, ev->mouse_pos.x, ev->mouse_pos.y, g_simgraph->palette_lookup(COL_BLACK), true );
 			display_logo();
 			// queue the event anyway, so the viewport is correctly updated on world resume (screen will be resized again).
 			queued_events.append(ev);
@@ -150,11 +153,12 @@ void loadingscreen_t::set_progress( uint32 progress )
 
 loadingscreen_t::~loadingscreen_t()
 {
-	if(is_display_init()) {
+	if (g_simgraph->is_display_init()) {
 		win_redraw_world();
-		mark_screen_dirty();
+		g_simgraph->mark_screen_dirty();
 		ticker::set_redraw_all(true);
 	}
+
 	while(  !queued_events.empty()  ) {
 		queue_event( queued_events.remove_first() );
 	}
diff --git a/src/simutrans/simmain.cc b/src/simutrans/simmain.cc
index 3fff1bd4e..48c25712e 100644
--- a/src/simutrans/simmain.cc
+++ b/src/simutrans/simmain.cc
@@ -159,24 +159,24 @@ static void show_times(karte_t *welt, main_view_t *view)
 
 	image_id img = ground_desc_t::outside->get_image(0,0);
 
-	display_color_img(img, 120, 100, 1, 0, 1);
+	g_simgraph->draw_color_img(img, 120, 100, 1, 0, 1 CLIP_NUM_DEFAULT);
 	uint32 ms = dr_time();
 	for (i = 0;  i < 6000000;  i++) {
-		display_img_aux( img, 50, 50, 1, 0, true  CLIP_NUM_DEFAULT);
+		g_simgraph->draw_img_aux( img, 50, 50, 1, 0, true  CLIP_NUM_DEFAULT);
 	}
 	dbg->message("show_times()", "display_img() %i iterations took %li ms", i, dr_time() - ms );
 
 	image_id player_img = skinverwaltung_t::color_options->get_image_id(0);
 	ms = dr_time();
 	for (i = 0;  i < 1000000;  i++) {
-		display_color_img( player_img, 120, 100, i%15, 0, 1);
+		g_simgraph->draw_color_img( player_img, 120, 100, i%15, 0, 1 CLIP_NUM_DEFAULT);
 	}
 	dbg->message("show_times()", "display_color_img() with recolor %i iterations took %li ms", i, dr_time() - ms );
 
 	ms = dr_time();
 	for (i = 0;  i < 100000;  i++) {
-		display_color_img( img, 120, 100, 0, 1, 1);
-		display_color_img( player_img, 160, 150, 16, 1, 1);
+		g_simgraph->draw_color_img( img, 120, 100, 0, 1, 1 CLIP_NUM_DEFAULT);
+		g_simgraph->draw_color_img( player_img, 160, 150, 16, 1, 1 CLIP_NUM_DEFAULT);
 	}
 	dbg->message("show_times()", "display_color_img() 3x %i iterations took %li ms", i, dr_time() - ms );
 
@@ -191,13 +191,13 @@ static void show_times(karte_t *welt, main_view_t *view)
 
 	ms = dr_time();
 	for (i = 0;  i < 300000;  i++) {
-		display_text_proportional_len_clip_rgb(100, 120, "Dies ist ein kurzer Textetxt ...", 0, 0, false, -1);
+		g_simgraph->draw_text_clipped_n(100, 120, "Dies ist ein kurzer Textetxt ...", 0, 0, false, -1 CLIP_NUM_DEFAULT);
 	}
 	dbg->message("show_times()", "display_text_proportional_len_clip_rgb() %i iterations took %li ms", i, dr_time() - ms );
 
 	ms = dr_time();
 	for (i = 0;  i < 300000;  i++) {
-		display_fillbox_wh_rgb(100, 120, 300, 50, 0, false);
+		g_simgraph->draw_rect(100, 120, 300, 50, 0, false);
 	}
 	dbg->message("show_times()", "display_fillbox_wh_rgb() %i iterations took %li ms", i, dr_time() - ms );
 
@@ -255,7 +255,7 @@ static void show_times(karte_t *welt, main_view_t *view)
 static bool never_quit() { return false; }
 static bool no_language() { return translator::get_language()!=-1; }
 static utf16 testfor_this_character = 0;
-static bool no_font() { return has_character(testfor_this_character); }
+static bool no_font() { return g_simgraph->font_has_character(testfor_this_character); }
 #if COLOUR_DEPTH != 0
 static bool empty_objfilename() { return !env_t::pak_name.empty() ||  pakinstaller_t::finish_install; }
 static bool finish_install() { return pakinstaller_t::finish_install; }
@@ -316,7 +316,7 @@ static sint16 ask_objfilename()
  */
 static void ask_language()
 {
-	if(  display_get_width()==0  ) {
+	if(  g_simgraph->get_screen_size().w==0  ) {
 		// only console available ... => choose english for the moment
 		dbg->warning( "ask_language", "No language selected, will use english!" );
 		translator::set_language( "en" );
@@ -921,15 +921,27 @@ int simu_main(int argc, char** argv)
 		}
 	}
 
+	simgraph_type_t preferred_renderer_type =
+#if COLOUR_DEPTH == 0
+		SIMGRAPH_TYPE_NULL;
+#else
+		SIMGRAPH_TYPE_SOFTWARE;
+#endif
+
+	g_simgraph = simgraph_select(preferred_renderer_type);
+
 	DBG_MESSAGE("simu_main()", "simgraph_init disp_width=%d, disp_height=%d, fullscreen=%d", disp_width, disp_height, fullscreen);
-	if (!simgraph_init(scr_size(disp_width, disp_height), fullscreen)) {
+	if (!g_simgraph || !g_simgraph->init(scr_size(disp_width, disp_height), fullscreen)) {
 		dbg->error("simu_main()", "Failed to initialize graphics system.");
 		return EXIT_FAILURE;
 	}
-	DBG_MESSAGE("simu_main()", ".. results in disp_width=%d, disp_height=%d", display_get_width(), display_get_height());
+
+	const scr_size screen = g_simgraph->get_screen_size();
+	DBG_MESSAGE("simu_main()", ".. results in disp_width=%d, disp_height=%d", screen.w, screen.h);
+
 	// now that the graphics system has already started
 	// the saved colours can be converted to the system format
-	env_t_rgb_to_system_colors();
+	g_simgraph->env_t_rgb_to_system_colors();
 
 	// parse colours now that the graphics system has started
 	// default simuconf.tab
@@ -1000,7 +1012,7 @@ int simu_main(int argc, char** argv)
 	dr_chdir( env_t::base_dir );
 
 	// The loading screen needs to be initialized
-	display_show_pointer(1);
+	g_simgraph->set_cursor_visible(true);
 
 	// if no object files given, we ask the user
 	int retries=0;
@@ -1009,7 +1021,7 @@ int simu_main(int argc, char** argv)
 			retries++;
 		}
 		if(  env_t::quit_simutrans  ) {
-			simgraph_exit();
+			g_simgraph->exit();
 			return EXIT_SUCCESS;
 		}
 		else if (env_t::pak_name.empty()) {
@@ -1026,7 +1038,7 @@ int simu_main(int argc, char** argv)
 			"\n"
 			"Please install a pak set and select it using the '-objects'\n"
 			"command line parameter or the 'pak_file_path' simuconf.tab entry.");
-		simgraph_exit();
+		g_simgraph->exit();
 		return EXIT_FAILURE;
 	}
 #endif
@@ -1044,7 +1056,7 @@ int simu_main(int argc, char** argv)
 				env_t::pak_dir.c_str());
 
 			dr_fatal_notify(errmsg);
-			simgraph_exit();
+			g_simgraph->exit();
 			return EXIT_FAILURE;
 		}
 		fclose(f);
@@ -1257,7 +1269,7 @@ int simu_main(int argc, char** argv)
 		const utf8 *new_world = (const utf8 *)translator::translate("Beenden");
 		size_t len;
 		testfor_this_character = utf8_decoder_t::decode(new_world,len);
-		if (!has_character(testfor_this_character)) {
+		if (!g_simgraph->font_has_character(testfor_this_character)) {
 			// not valid => show font selector
 			loadfont_frame_t* sel = new loadfont_frame_t();
 			destroy_all_win(true); // since eventually the successful load message is still there ....
@@ -1636,8 +1648,8 @@ int simu_main(int argc, char** argv)
 		display_set_pointer(skinverwaltung_t::mouse_cursor->get_image_id(0));
 	}
 #endif
-	display_show_pointer(true);
-	display_show_load_pointer(0);
+	g_simgraph->set_cursor_visible(true);
+	g_simgraph->set_show_load_cursor(false);
 
 	welt->set_dirty();
 
@@ -1731,7 +1743,7 @@ int simu_main(int argc, char** argv)
 	remove_port_forwarding( env_t::server );
 	network_core_shutdown();
 
-	simgraph_exit();
+	g_simgraph->exit();
 
 	close_midi();
 
diff --git a/src/simutrans/simmesg.cc b/src/simutrans/simmesg.cc
index 4a2ee1cd7..cc6968ecf 100644
--- a/src/simutrans/simmesg.cc
+++ b/src/simutrans/simmesg.cc
@@ -66,7 +66,7 @@ void message_node_t::rdwr(loadsave_t *file)
 		// color was 16bit, with 0x8000 indicating player colors
 		uint16 c = color & PLAYER_FLAG ? 0x8000 + (color&(~PLAYER_FLAG)) : MN_GREY0;
 		file->rdwr_short(c);
-		color = c & 0x8000 ? PLAYER_FLAG + (c&(~0x8000)) : color_idx_to_rgb(c);
+		color = c & 0x8000 ? PLAYER_FLAG + (c&(~0x8000)) : g_simgraph->palette_lookup(c);
 	}
 	else {
 		file->rdwr_long( color );
@@ -84,7 +84,7 @@ PIXVAL message_node_t::get_player_color(karte_t *welt) const
 	FLAGGED_PIXVAL colorval = color;
 	if(  color&PLAYER_FLAG  ) {
 		player_t *player = welt->get_player(color&(~PLAYER_FLAG));
-		colorval = player ? PLAYER_FLAG+color_idx_to_rgb(player->get_player_color1()+env_t::gui_player_color_dark) : color_idx_to_rgb(MN_GREY0);
+		colorval = player ? PLAYER_FLAG+g_simgraph->palette_lookup(player->get_player_color1()+env_t::gui_player_color_dark) : g_simgraph->palette_lookup(MN_GREY0);
 	}
 	return (PIXVAL)colorval;
 }
diff --git a/src/simutrans/simticker.cc b/src/simutrans/simticker.cc
index 793f456d5..1154fe09c 100644
--- a/src/simutrans/simticker.cc
+++ b/src/simutrans/simticker.cc
@@ -64,7 +64,7 @@ void ticker::add_msg_node(const message_node_t& msg)
 
 	if(count==0) {
 		redraw_all = true;
-		next_pos = display_get_width();
+		next_pos = g_simgraph->get_screen_size().w;
 	}
 
 	const char* txt = msg.msg;
@@ -97,7 +97,7 @@ void ticker::add_msg_node(const message_node_t& msg)
 		n.msg[i++] = 0;
 
 		n.xpos = next_pos;
-		n.w = proportional_string_width(n.msg);
+		n.w = g_simgraph->calc_text_width(n.msg);
 
 		next_pos += n.w + X_SPACING;
 		list.append(n);
@@ -124,14 +124,14 @@ void ticker::add_msg(const char* txt, koord3d pos, FLAGGED_PIXVAL color, int typ
 void ticker::update()
 {
 	const int dx = X_DIST;
-	const int display_width = display_get_width();
+	const scr_size screen = g_simgraph->get_screen_size();
 
 	for(node & n : list) {
 		n.xpos -= dx;
 	}
 
 	dx_since_last_draw += dx;
-	next_pos = std::max(next_pos - dx, display_width);
+	next_pos = std::max(next_pos - dx, screen.w);
 
 	// remove old news
 	while (!list.empty()  &&  list.front().xpos + list.front().w < 0) {
@@ -146,7 +146,8 @@ void ticker::update()
 
 void ticker::draw()
 {
-	const int start_y = env_t::menupos == MENU_BOTTOM ? win_get_statusbar_height() : display_get_height() - TICKER_HEIGHT - win_get_statusbar_height();
+	const scr_size screen = g_simgraph->get_screen_size();
+	const int start_y = env_t::menupos == MENU_BOTTOM ? win_get_statusbar_height() : screen.h - TICKER_HEIGHT - win_get_statusbar_height();
 	if (redraw_all) {
 		redraw();
 		return;
@@ -155,28 +156,29 @@ void ticker::draw()
 		// ticker not visible
 
 		// mark everything at the bottom as dirty to clear also tooltips and compass
-		mark_rect_dirty_wc(0, env_t::menupos == MENU_BOTTOM ? 0 : start_y - 128, display_get_width(), start_y + 128 + TICKER_HEIGHT);
+		g_simgraph->mark_rect_dirty_wc(0, env_t::menupos == MENU_BOTTOM ? 0 : start_y - 128, screen.w, start_y + 128 + TICKER_HEIGHT);
 		return;
 	}
 	if (dx_since_last_draw <=0) {
 		return;
 	}
 
-	const int width = display_get_width();
-	if (width <= 0) {
+	if (screen.w <= 0) {
 		return;
 	}
+
 	// do partial redraw
-	display_scroll_band( start_y, dx_since_last_draw, TICKER_HEIGHT );
+	g_simgraph->move_scroll_band(start_y, dx_since_last_draw, TICKER_HEIGHT);
+
+	g_simgraph->draw_rect(screen.w-dx_since_last_draw, start_y, dx_since_last_draw, TICKER_HEIGHT, SYSCOL_TICKER_BACKGROUND, true);
 
-	display_fillbox_wh_rgb(width-dx_since_last_draw, start_y, dx_since_last_draw, TICKER_HEIGHT, SYSCOL_TICKER_BACKGROUND, true);
+	g_simgraph->mark_rect_dirty_wc(0, start_y, screen.w, start_y + TICKER_HEIGHT);
 
-	mark_rect_dirty_wc(0, start_y, width, start_y + TICKER_HEIGHT);
 	// ok, ready for the text
-	PUSH_CLIP( width-dx_since_last_draw, start_y, dx_since_last_draw, TICKER_HEIGHT );
+	PUSH_CLIP( screen.w-dx_since_last_draw, start_y, dx_since_last_draw, TICKER_HEIGHT );
 	for(node & n : list) {
-		if (n.xpos < width) {
-			display_proportional_clip_rgb(n.xpos, start_y + TICKER_V_SPACE, n.msg, ALIGN_LEFT, n.get_player_color(welt), true);
+		if (n.xpos < screen.w) {
+			g_simgraph->draw_text_clipped(n.xpos, start_y + TICKER_V_SPACE, n.msg, ALIGN_LEFT, n.get_player_color(welt), true);
 		}
 	}
 	POP_CLIP();
@@ -187,24 +189,23 @@ void ticker::draw()
 
 void ticker::redraw()
 {
+	const scr_size screen = g_simgraph->get_screen_size();
 	set_redraw_all(false);
 	dx_since_last_draw = 0;
-	const int start_y = env_t::menupos == MENU_BOTTOM ? win_get_statusbar_height() : display_get_height() - TICKER_HEIGHT - win_get_statusbar_height();
+	const int start_y = env_t::menupos == MENU_BOTTOM ? win_get_statusbar_height() : screen.h - TICKER_HEIGHT - win_get_statusbar_height();
 
 	if (list.empty()) {
 		// mark everything at the bottom as dirty to clear also tooltips and compass
-		mark_rect_dirty_wc(0, env_t::menupos == MENU_BOTTOM ? 0 : start_y - 128, display_get_width(), start_y + 128 + TICKER_HEIGHT);
+		g_simgraph->mark_rect_dirty_wc(0, env_t::menupos == MENU_BOTTOM ? 0 : start_y - 128, screen.h, start_y + 128 + TICKER_HEIGHT);
 		world()->set_background_dirty();
 		return;
 	}
 
-	const int width = display_get_width();
-
 	// just draw the ticker in its colour ... (to be sure ... )
-	display_fillbox_wh_rgb(0, start_y, width, TICKER_HEIGHT, SYSCOL_TICKER_BACKGROUND, true);
+	g_simgraph->draw_rect(0, start_y, screen.w, TICKER_HEIGHT, SYSCOL_TICKER_BACKGROUND, true);
 	for(node & n : list) {
-		if (n.xpos < width) {
-			display_proportional_clip_rgb(n.xpos, start_y + TICKER_V_SPACE, n.msg, ALIGN_LEFT, n.color, true);
+		if (n.xpos < screen.w) {
+			g_simgraph->draw_text_clipped(n.xpos, start_y + TICKER_V_SPACE, n.msg, ALIGN_LEFT, n.color, true);
 		}
 	}
 }
diff --git a/src/simutrans/sys/simsys_s2.cc b/src/simutrans/sys/simsys_s2.cc
index f59920f25..b9de55805 100644
--- a/src/simutrans/sys/simsys_s2.cc
+++ b/src/simutrans/sys/simsys_s2.cc
@@ -478,8 +478,8 @@ int dr_os_open(const scr_size window_size, sint16 fs)
 	assert(tex_h <= screen->h);
 	assert(tex_w <= tex_pitch);
 
-	display_set_actual_width( tex_w );
-	display_set_height( tex_h );
+	g_simgraph->set_screen_actual_width( tex_w );
+	g_simgraph->set_screen_height( tex_h );
 	return tex_pitch;
 }
 
@@ -528,7 +528,7 @@ int dr_textur_resize(unsigned short** const textur, int tex_w, int const tex_h)
 	assert(tex_h <= screen->h);
 	assert(tex_w <= tex_pitch);
 
-	display_set_actual_width( tex_w );
+	g_simgraph->set_screen_actual_width( tex_w );
 	return tex_pitch;
 }
 
@@ -566,12 +566,13 @@ void dr_prepare_flush()
 
 void dr_flush()
 {
-	display_flush_buffer();
+	g_simgraph->flush_framebuffer();
 	if(  !use_dirty_tiles  ) {
 		SDL_UpdateTexture( screen_tx, NULL, screen->pixels, screen->pitch );
 	}
 
-	SDL_Rect rSrc  = { 0, 0, display_get_width(), display_get_height()  };
+	const scr_rect screen = g_simgraph->get_screen_size();
+	SDL_Rect rSrc  = { 0, 0, screen.w, screen.h  };
 	SDL_RenderCopy( renderer, screen_tx, &rSrc, NULL );
 
 	SDL_RenderPresent( renderer );
@@ -784,13 +785,15 @@ static void internal_GetEvents()
 		case SDL_FINGERMOTION:
 			// move whatever
 			if(  screen  &&  previous_multifinger_touch==0  &&  FirstFingerId==event.tfinger.fingerId) {
+				const scr_size screen_size = g_simgraph->get_screen_size();
+
 				if (dLastDist == 0.0) {
 					// not yet a finger down event before => we send one
 					dLastDist = 1e-99;
 					sys_event.type = SIM_MOUSE_BUTTONS;
 					sys_event.code = SIM_MOUSE_LEFTBUTTON;
-					sys_event.mx = event.tfinger.x * display_get_width();
-					sys_event.my = event.tfinger.y * display_get_height();
+					sys_event.mx = event.tfinger.x * screen_size.w;
+					sys_event.my = event.tfinger.y * screen_size.h;
 					previous_multifinger_touch = 0;
 	DBG_MESSAGE("SDL_FINGERMOTION", "SIM_MOUSE_LEFTBUTTON at %i,%i", sys_event.mx, sys_event.my);
 				}
@@ -798,8 +801,8 @@ static void internal_GetEvents()
 
 					sys_event.type = SIM_MOUSE_MOVE;
 					sys_event.code = SIM_MOUSE_MOVED;
-					sys_event.mx = event.tfinger.x * display_get_width();
-					sys_event.my = event.tfinger.y * display_get_height();
+					sys_event.mx = event.tfinger.x * screen_size.w;
+					sys_event.my = event.tfinger.y * screen_size.h;
 	DBG_MESSAGE("SDL_FINGERMOTION", "SIM_MOUSE_MOVED at %i,%i", sys_event.mx, sys_event.my);
 				}
 				sys_event.mb = MOUSE_LEFTBUTTON;
@@ -811,6 +814,8 @@ static void internal_GetEvents()
 		case SDL_FINGERUP:
 			if (screen  &&  in_finger_handling) {
 				if (FirstFingerId==event.tfinger.fingerId  ||  SDL_GetNumTouchFingers(event.tfinger.touchId)==0) {
+					const scr_size screen_size = g_simgraph->get_screen_size();
+
 					if(!previous_multifinger_touch) {
 						if (dLastDist == 0.0) {
 							dLastDist = 1e-99;
@@ -819,8 +824,9 @@ static void internal_GetEvents()
 							sys_event.code = SIM_MOUSE_LEFTBUTTON;
 							sys_event.mb = MOUSE_LEFTBUTTON;
 							sys_event.key_mod = ModifierKeys();
-							last_mx = sys_event.mx = event.tfinger.x * display_get_width();
-							last_my = sys_event.my = event.tfinger.y * display_get_height();
+							last_mx = sys_event.mx = event.tfinger.x * screen_size.w;
+							last_my = sys_event.my = event.tfinger.y * screen_size.h;
+
 							// not yet moved -> set click origin or click will be at last position ...
 							set_click_xy(sys_event.mx, sys_event.my);
 
@@ -831,8 +837,8 @@ static void internal_GetEvents()
 							sys_event.type = SIM_MOUSE_BUTTONS;
 							sys_event.code = SIM_MOUSE_LEFTUP;
 							sys_event.mb = 0;
-							sys_event.mx = (event.tfinger.x + event.tfinger.dx) * display_get_width();
-							sys_event.my = (event.tfinger.y + event.tfinger.dy) * display_get_height();
+							sys_event.mx = (event.tfinger.x + event.tfinger.dx) * screen_size.w;
+							sys_event.my = (event.tfinger.y + event.tfinger.dy) * screen_size.h;
 							sys_event.key_mod = ModifierKeys();
 		DBG_MESSAGE("SDL_FINGERUP", "SIM_MOUSE_LEFTUP at %i,%i", sys_event.mx, sys_event.my);
 						}
diff --git a/src/simutrans/sys/simsys_w.cc b/src/simutrans/sys/simsys_w.cc
index a1ffc9429..316e8cbaf 100644
--- a/src/simutrans/sys/simsys_w.cc
+++ b/src/simutrans/sys/simsys_w.cc
@@ -346,7 +346,7 @@ DWORD WINAPI dr_flush_screen(LPVOID /*lpParam*/)
 		// wait for finish of thread
 		EnterCriticalSection( &redraw_underway );
 		hdc = GetDC(hwnd);
-		display_flush_buffer();
+		g_simgraph->flush_framebuffer();
 		ReleaseDC(hwnd, hdc);
 		hdc = NULL;
 		LeaveCriticalSection( &redraw_underway );
@@ -374,7 +374,7 @@ void dr_flush()
 #else
 	assert(hdc==NULL);
 	hdc = GetDC(hwnd);
-	display_flush_buffer();
+	g_simgraph->flush_framebuffer();
 	ReleaseDC(hwnd, hdc);
 	hdc = NULL;
 #endif
diff --git a/src/simutrans/tool/simmenu.cc b/src/simutrans/tool/simmenu.cc
index abe8768f3..4d736d7c2 100644
--- a/src/simutrans/tool/simmenu.cc
+++ b/src/simutrans/tool/simmenu.cc
@@ -1019,7 +1019,7 @@ void tool_t::draw_after(scr_coord pos, bool dirty) const
 	// default action: grey corner if selected
 	image_id id = get_icon(welt->get_active_player());
 	if (id != IMG_EMPTY && is_selected()) {
-		display_img_blend(id, pos.x, pos.y, TRANSPARENT50_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_BLACK), false, dirty);
+		g_simgraph->draw_img_blend(id, pos.x, pos.y, TRANSPARENT50_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_BLACK), false, dirty);
 	}
 }
 
@@ -1215,9 +1215,11 @@ bool toolbar_t::init(player_t* player)
 				}
 			}
 			// open toolbar centered at top or bottom position (bottom, when menubar at bottom)
-			scr_coord_val w = display_get_width() - (env_t::menupos == MENU_LEFT ? env_t::iconsize.w : 0) - (env_t::menupos == MENU_RIGHT ? env_t::iconsize.w : 0);
+			const scr_size screen = g_simgraph->get_screen_size();
+
+			scr_coord_val w = screen.w - (env_t::menupos == MENU_LEFT ? env_t::iconsize.w : 0) - (env_t::menupos == MENU_RIGHT ? env_t::iconsize.w : 0);
 			scr_coord_val x = (w - tool_selector->get_windowsize().w) / 2 + (env_t::menupos == MENU_LEFT ? env_t::iconsize.w : 0);
-			scr_coord_val y = (env_t::menupos == MENU_BOTTOM ? display_get_height() - tool_selector->get_windowsize().h - env_t::iconsize.h : 0);
+			scr_coord_val y = (env_t::menupos == MENU_BOTTOM ? screen.h - tool_selector->get_windowsize().h - env_t::iconsize.h : 0);
 			create_win({ x, y }, tool_selector, w_do_not_delete, magic_toolbar + toolbar_tool.index_of(this));
 		}
 		else {
@@ -1442,11 +1444,12 @@ const char* two_click_tool_t::move(player_t* player, uint16 buttonstate, koord3d
 			return error;
 		}
 		if (value & 2) {
-			display_show_load_pointer(true);
+			g_simgraph->set_show_load_cursor(true);
 			mark_tiles(player, start, pos);
-			display_show_load_pointer(false);
+			g_simgraph->set_show_load_cursor(false);
 		}
 	}
+
 	return "";
 }
 
@@ -1491,6 +1494,7 @@ void two_click_tool_t::cleanup(bool delete_start_marker)
 			assert(!welt->lookup(pos));
 		}
 	}
+
 	// delete tooltip.
 	win_set_static_tooltip(NULL);
 }
diff --git a/src/simutrans/tool/simtool-dialogs.h b/src/simutrans/tool/simtool-dialogs.h
index e63bded1f..1311f0729 100644
--- a/src/simutrans/tool/simtool-dialogs.h
+++ b/src/simutrans/tool/simtool-dialogs.h
@@ -654,7 +654,7 @@ public:
 	{
 		if (icon != IMG_EMPTY) {
 			if (is_selected()) {
-				display_img_blend(icon, pos.x, pos.y, TRANSPARENT50_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_BLACK), false, dirty);
+				g_simgraph->draw_img_blend(icon, pos.x, pos.y, TRANSPARENT50_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_BLACK), false, dirty);
 			}
 			uint16 unread_count = env_t::chat_unread_public + env_t::chat_unread_company + env_t::chat_unread_whisper;
 			if (unread_count > 99) {
@@ -663,12 +663,12 @@ public:
 			if (unread_count) {
 				char str[16];
 				sprintf(str, "%i", unread_count);
-				scr_coord_val txt_width = proportional_string_width(str);
+				scr_coord_val txt_width = g_simgraph->calc_text_width(str);
 				scr_coord_val width = max(LINEASCENT, txt_width + 2);
 				scr_coord_val xoff = env_t::iconsize.w - width - 1;
 				scr_coord_val yoff = env_t::iconsize.h - LINESPACE - 1;
-				display_filled_roundbox_clip(pos.x + xoff, pos.y + yoff, width, LINESPACE, color_idx_to_rgb(COL_RED + 1), dirty);
-				display_proportional_rgb(pos.x + xoff + D_GET_CENTER_ALIGN_OFFSET(txt_width, width), pos.y + yoff + 1, str, ALIGN_LEFT, color_idx_to_rgb(COL_WHITE), dirty);
+				g_simgraph->draw_rounded_rect_clipped(pos.x + xoff, pos.y + yoff, width, LINESPACE, g_simgraph->palette_lookup(COL_RED + 1), dirty);
+				g_simgraph->draw_text(pos.x + xoff + D_GET_CENTER_ALIGN_OFFSET(txt_width, width), pos.y + yoff + 1, str, ALIGN_LEFT, g_simgraph->palette_lookup(COL_WHITE), dirty);
 			}
 		}
 	}
diff --git a/src/simutrans/tool/simtool.cc b/src/simutrans/tool/simtool.cc
index 4169d1399..3d8131e7b 100644
--- a/src/simutrans/tool/simtool.cc
+++ b/src/simutrans/tool/simtool.cc
@@ -5214,10 +5214,10 @@ void tool_build_roadsign_t::get_values(player_t *player, uint8 &spacing, bool &r
 void tool_build_roadsign_t::draw_after(scr_coord k, bool dirty) const
 {
 	if(  icon!=IMG_EMPTY  &&  is_selected()  ) {
-		display_img_blend( icon, k.x, k.y, TRANSPARENT50_FLAG|OUTLINE_FLAG|color_idx_to_rgb(COL_BLACK), false, dirty );
+		g_simgraph->draw_img_blend(icon, k.x, k.y, TRANSPARENT50_FLAG|OUTLINE_FLAG|g_simgraph->palette_lookup(COL_BLACK), false, dirty );
 		char level_str[16];
 		sprintf(level_str, "%i", signal[welt->get_active_player_nr()].spacing);
-		display_proportional_rgb( k.x+4, k.y+4, level_str, ALIGN_LEFT, color_idx_to_rgb(COL_YELLOW), true );
+		g_simgraph->draw_text( k.x+4, k.y+4, level_str, ALIGN_LEFT, g_simgraph->palette_lookup(COL_YELLOW), true );
 	}
 }
 
@@ -7477,12 +7477,12 @@ bool tool_show_underground_t::is_selected() const
 void tool_show_underground_t::draw_after(scr_coord k, bool dirty) const
 {
 	if(  icon!=IMG_EMPTY  &&  is_selected()  ) {
-		display_img_blend( icon, k.x, k.y, TRANSPARENT50_FLAG|OUTLINE_FLAG|color_idx_to_rgb(COL_BLACK), false, dirty );
+		g_simgraph->draw_img_blend( icon, k.x, k.y, TRANSPARENT50_FLAG|OUTLINE_FLAG|g_simgraph->palette_lookup(COL_BLACK), false, dirty );
 		// additionally show level in sliced mode
 		if(  default_param!=NULL  &&  grund_t::underground_mode==grund_t::ugm_level  ) {
 			char level_str[16];
 			sprintf( level_str, "%i", grund_t::underground_level );
-			display_proportional_rgb( k.x+4, k.y+4, level_str, ALIGN_LEFT, color_idx_to_rgb(COL_YELLOW), true );
+			g_simgraph->draw_text( k.x+4, k.y+4, level_str, ALIGN_LEFT, g_simgraph->palette_lookup(COL_YELLOW), true );
 		}
 	}
 }
@@ -7492,7 +7492,7 @@ void tool_rotate90_t::draw_after(scr_coord pos, bool dirty) const
 {
 	if(  !env_t::networkmode  ) {
 		if(  skinverwaltung_t::compass_map  ) {
-			display_img_aligned( skinverwaltung_t::compass_map->get_image_id( welt->get_settings().get_rotation()+4 ), scr_rect(pos,env_t::iconsize), ALIGN_CENTER_V|ALIGN_CENTER_H, false );
+			g_simgraph->draw_img_aligned( skinverwaltung_t::compass_map->get_image_id( welt->get_settings().get_rotation()+4 ), scr_rect(pos,env_t::iconsize), ALIGN_CENTER_V|ALIGN_CENTER_H, false );
 		}
 		tool_t::draw_after( pos, dirty );
 	}
@@ -7540,14 +7540,14 @@ bool tool_toggle_reservation_t::is_selected() const
 bool tool_screenshot_t::init( player_t * )
 {
 	bool ok;
-	const scr_rect screen_area = scr_rect(0, 0, display_get_width(), display_get_height());
+	const scr_rect screen_area = { { 0, 0 }, g_simgraph->get_screen_size() };
 	const gui_frame_t *topwin = win_get_top();
 
 	if(  is_ctrl_pressed()  &&  topwin != NULL  ) {
-		ok = display_snapshot( scr_rect(win_get_pos(topwin), topwin->get_windowsize()) );
+		ok = g_simgraph->take_screenshot(scr_rect(win_get_pos(topwin), topwin->get_windowsize()));
 	}
 	else {
-		ok = display_snapshot( screen_area );
+		ok = g_simgraph->take_screenshot(screen_area);
 	}
 
 	if (ok) {
@@ -8616,7 +8616,7 @@ const char* tool_add_message_t::work(player_t* player, koord3d pos )
 			return "";
 		}
 		welt->get_message()->add_message( text+1, pos, type,
-								player == NULL || ( (type & message_t::PLAYER_MSG) != 0)  ? color_idx_to_rgb(COL_BLACK) : PLAYER_FLAG|player->get_player_nr(), IMG_EMPTY );
+								player == NULL || ( (type & message_t::PLAYER_MSG) != 0)  ? g_simgraph->palette_lookup(COL_BLACK) : PLAYER_FLAG|player->get_player_nr(), IMG_EMPTY );
 
 	}
 	return NULL;
diff --git a/src/simutrans/utils/log.cc b/src/simutrans/utils/log.cc
index 96e99c221..e3eb5d8cf 100644
--- a/src/simutrans/utils/log.cc
+++ b/src/simutrans/utils/log.cc
@@ -355,14 +355,15 @@ void log_t::custom_fatal(char *buffer)
 
 	env_t::verbose_debug = log_t::LEVEL_FATAL; // no more window concerning messages
 
-	if(is_display_init()) {
+	if (g_simgraph->is_display_init()) {
 		// show notification
 		destroy_all_win( true );
 
 		strcat( buffer, "PRESS ANY KEY\n" );
 		fatal_news* sel = new fatal_news(buffer);
 
-		scr_coord xy( display_get_width()/2 - sel->get_windowsize().w/2, display_get_height()/2 - sel->get_windowsize().h/2 );
+		const scr_size screen = g_simgraph->get_screen_size();
+		scr_coord xy( screen.w/2 - sel->get_windowsize().w/2, screen.h/2 - sel->get_windowsize().h/2 );
 		event_t ev;
 
 		create_win( xy, sel, w_info, magic_none );
diff --git a/src/simutrans/vehicle/air_vehicle.cc b/src/simutrans/vehicle/air_vehicle.cc
index ccdf69986..5cbb40dfe 100644
--- a/src/simutrans/vehicle/air_vehicle.cc
+++ b/src/simutrans/vehicle/air_vehicle.cc
@@ -730,7 +730,7 @@ air_vehicle_t::air_vehicle_t(koord3d pos, const vehicle_desc_t* desc, player_t*
 air_vehicle_t::~air_vehicle_t()
 {
 	// mark aircraft (after_image) dirty, since we have no "real" image
-	const int raster_width = get_current_tile_raster_width();
+	const int raster_width = g_simgraph->get_current_tile_raster_width();
 	sint16 yoff = tile_raster_scale_y(-flying_height-get_hoff()-2, raster_width);
 
 	mark_image_dirty( image, yoff);
@@ -986,7 +986,7 @@ void air_vehicle_t::display_after(int xpos_org, int ypos_org, bool is_global) co
 	if(  image != IMG_EMPTY  &&  !is_on_ground()  ) {
 		int xpos = xpos_org, ypos = ypos_org;
 
-		const int raster_width = get_current_tile_raster_width();
+		const int raster_width = g_simgraph->get_current_tile_raster_width();
 		const sint16 z = get_pos().z;
 		if(  z + flying_height/TILE_HEIGHT_STEP - 1 > grund_t::underground_level  ) {
 			return;
@@ -1005,21 +1005,21 @@ void air_vehicle_t::display_after(int xpos_org, int ypos_org, bool is_global) co
 		xpos += tile_raster_scale_x(get_xoff(), raster_width);
 		get_screen_offset( xpos, ypos, raster_width );
 
-		display_swap_clip_wh(CLIP_NUM_VAR);
+		g_simgraph->swap_clip_rect(CLIP_NUM_VAR);
 		// will be dirty
 		// the aircraft!!!
-		display_color( image, xpos, ypos, get_owner_nr(), true, true/*get_flag(obj_t::dirty)*/  CLIP_NUM_PAR);
+		g_simgraph->draw_color( image, xpos, ypos, get_owner_nr(), true, true/*get_flag(obj_t::dirty)*/  CLIP_NUM_PAR);
 #ifndef MULTI_THREAD
 		vehicle_t::display_after( xpos_org, ypos_org - tile_raster_scale_y( current_flughohe - hoff - 2, raster_width ), is_global );
 #endif
-		display_swap_clip_wh(CLIP_NUM_VAR);
+		g_simgraph->swap_clip_rect(CLIP_NUM_VAR);
 	}
 #ifdef MULTI_THREAD
 }
 void air_vehicle_t::display_overlay(int xpos_org, int ypos_org) const
 {
 	if(  image != IMG_EMPTY  &&  !is_on_ground()  ) {
-		const int raster_width = get_current_tile_raster_width();
+		const int raster_width = g_simgraph->get_current_tile_raster_width();
 		const sint16 z = get_pos().z;
 		if(  z + flying_height/TILE_HEIGHT_STEP - 1 > grund_t::underground_level  ) {
 			return;
diff --git a/src/simutrans/vehicle/air_vehicle.h b/src/simutrans/vehicle/air_vehicle.h
index 407075b02..64c3837bb 100644
--- a/src/simutrans/vehicle/air_vehicle.h
+++ b/src/simutrans/vehicle/air_vehicle.h
@@ -102,7 +102,7 @@ public:
 	image_id get_outline_image() const OVERRIDE {return !is_on_ground() ? image : IMG_EMPTY;}
 
 	// shadow has black color (when flying)
-	FLAGGED_PIXVAL get_outline_colour() const OVERRIDE {return !is_on_ground() ? TRANSPARENT75_FLAG | OUTLINE_FLAG | color_idx_to_rgb(COL_BLACK) : 0;}
+	FLAGGED_PIXVAL get_outline_colour() const OVERRIDE {return !is_on_ground() ? TRANSPARENT75_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(COL_BLACK) : 0;}
 
 #ifdef MULTI_THREAD
 	// this draws the "real" aircrafts (when flying)
diff --git a/src/simutrans/vehicle/simroadtraffic.cc b/src/simutrans/vehicle/simroadtraffic.cc
index dd5b453fa..220190a1c 100644
--- a/src/simutrans/vehicle/simroadtraffic.cc
+++ b/src/simutrans/vehicle/simroadtraffic.cc
@@ -370,7 +370,7 @@ sync_result private_car_t::sync_step(uint32 delta_t)
 			else {
 				if(  ms_traffic_jam > welt->ticks_per_world_month  &&  old_ms_traffic_jam<=welt->ticks_per_world_month  ) {
 					// message after two month, reset waiting timer
-					welt->get_message()->add_message( translator::translate("To heavy traffic\nresults in traffic jam.\n"), get_pos(), message_t::traffic_jams|message_t::EXPIRE_AFTER_ONE_MONTH_MSG, color_idx_to_rgb(COL_ORANGE) );
+					welt->get_message()->add_message( translator::translate("To heavy traffic\nresults in traffic jam.\n"), get_pos(), message_t::traffic_jams|message_t::EXPIRE_AFTER_ONE_MONTH_MSG, g_simgraph->palette_lookup(COL_ORANGE) );
 				}
 			}
 		}
diff --git a/src/simutrans/vehicle/vehicle.cc b/src/simutrans/vehicle/vehicle.cc
index 05bf58e8e..3b6f833ab 100644
--- a/src/simutrans/vehicle/vehicle.cc
+++ b/src/simutrans/vehicle/vehicle.cc
@@ -1165,7 +1165,7 @@ void vehicle_t::display_after(int xpos, int ypos, bool is_global) const
 			case convoi_t::CAN_START_ONE_MONTH:
 				if(  state>=3  ) {
 					snprintf( tooltip_text, lengthof(tooltip_text), "%s (%s)", translator::translate("Waiting for clearance!"), cnv->get_schedule()->get_current_entry().pos.get_str() );
-					color = color_idx_to_rgb(COL_YELLOW);
+					color = g_simgraph->palette_lookup(COL_YELLOW);
 				}
 				break;
 
@@ -1184,7 +1184,7 @@ void vehicle_t::display_after(int xpos, int ypos, bool is_global) const
 					else {
 						sprintf( tooltip_text, translator::translate( "Loading (%i->%i%%)!" ), cnv->get_loading_level(), cnv->get_loading_limit() );
 					}
-					color = color_idx_to_rgb(COL_YELLOW);
+					color = g_simgraph->palette_lookup(COL_YELLOW);
 				}
 				break;
 
@@ -1192,7 +1192,7 @@ void vehicle_t::display_after(int xpos, int ypos, bool is_global) const
 //			case convoi_t::ROUTING_1:
 				if(  state>=3  ) {
 					tstrncpy( tooltip_text, translator::translate("Schedule changing!"), lengthof(tooltip_text) );
-					color = color_idx_to_rgb(COL_YELLOW);
+					color = g_simgraph->palette_lookup(COL_YELLOW);
 				}
 				break;
 
@@ -1201,11 +1201,11 @@ void vehicle_t::display_after(int xpos, int ypos, bool is_global) const
 					grund_t const* const gr = welt->lookup(cnv->get_route()->back());
 					if(  gr  &&  gr->get_depot()  ) {
 						tstrncpy( tooltip_text, translator::translate("go home"), lengthof(tooltip_text) );
-						color = color_idx_to_rgb(COL_GREEN);
+						color = g_simgraph->palette_lookup(COL_GREEN);
 					}
 					else if(  cnv->get_no_load()  ) {
 						tstrncpy( tooltip_text, translator::translate("no load"), lengthof(tooltip_text) );
-						color = color_idx_to_rgb(COL_GREEN);
+						color = g_simgraph->palette_lookup(COL_GREEN);
 					}
 				}
 				break;
@@ -1213,25 +1213,25 @@ void vehicle_t::display_after(int xpos, int ypos, bool is_global) const
 			case convoi_t::LEAVING_DEPOT:
 				if(  state>=2  ) {
 					tstrncpy( tooltip_text, translator::translate("Leaving depot!"), lengthof(tooltip_text) );
-					color = color_idx_to_rgb(COL_GREEN);
+					color = g_simgraph->palette_lookup(COL_GREEN);
 				}
 				break;
 
 			case convoi_t::WAITING_FOR_CLEARANCE_TWO_MONTHS:
 			case convoi_t::CAN_START_TWO_MONTHS:
 				snprintf( tooltip_text, lengthof(tooltip_text), "%s (%s)", translator::translate("clf_chk_stucked"), cnv->get_schedule()->get_current_entry().pos.get_str() );
-				color = color_idx_to_rgb(COL_ORANGE);
+				color = g_simgraph->palette_lookup(COL_ORANGE);
 				break;
 
 			case convoi_t::NO_ROUTE:
 				tstrncpy( tooltip_text, translator::translate("clf_chk_noroute"), lengthof(tooltip_text) );
-				color = color_idx_to_rgb(COL_RED);
+				color = g_simgraph->palette_lookup(COL_RED);
 				break;
 		}
 
 		if(  env_t::show_vehicle_states == 2  &&  !tooltip_text[ 0 ]  ) {
 			// show line name or simply convoi name
-			color = color_idx_to_rgb( cnv->get_owner()->get_player_color1() + 7 );
+			color = g_simgraph->palette_lookup( cnv->get_owner()->get_player_color1() + 7 );
 			if(  cnv->get_line().is_bound()  ) {
 				snprintf( tooltip_text, lengthof( tooltip_text ), "%s - %s", cnv->get_line()->get_name(), cnv->get_name() );
 			}
@@ -1242,12 +1242,13 @@ void vehicle_t::display_after(int xpos, int ypos, bool is_global) const
 
 		// something to show?
 		if(  tooltip_text[0]  ) {
-			const int raster_width = get_current_tile_raster_width();
+			const int raster_width = g_simgraph->get_current_tile_raster_width();
 			get_screen_offset( xpos, ypos, raster_width );
 			xpos += tile_raster_scale_x(get_xoff(), raster_width);
 			ypos += tile_raster_scale_y(get_yoff(), raster_width)+14;
-			if(ypos>LINESPACE+32  &&  ypos+LINESPACE<display_get_clip_wh().yy) {
-				display_ddd_proportional_clip( xpos, ypos, color, color_idx_to_rgb(COL_BLACK), tooltip_text, true );
+
+			if(ypos>LINESPACE+32  &&  ypos+LINESPACE < g_simgraph->get_clip_rect(CLIP_NUM_DEFAULT_VALUE).yy) {
+				g_simgraph->draw_textbox3d_clipped( xpos, ypos, color, g_simgraph->palette_lookup(COL_BLACK), tooltip_text, true CLIP_NUM_DEFAULT);
 			}
 		}
 	}
diff --git a/src/simutrans/world/simcity.cc b/src/simutrans/world/simcity.cc
index 4b0c6c556..4e1671347 100644
--- a/src/simutrans/world/simcity.cc
+++ b/src/simutrans/world/simcity.cc
@@ -1922,7 +1922,7 @@ void stadt_t::step_passagiere()
 				city_history_month[0][history_type + HIST_OFFSET_WALKED] += pax_left_to_do;
 
 				// probably not a good idea to mark them as player only cares about remote traffic
-				//merke_passagier_ziel(dest_pos, color_idx_to_rgb(COL_YELLOW));
+				//merke_passagier_ziel(dest_pos, g_simgraph->palette_lookup(COL_YELLOW));
 			}
 			else if(  route_result==haltestelle_t::ROUTE_OVERCROWDED  ) {
 				// overcrowded routes cause unhappiness to be logged
diff --git a/src/simutrans/world/simplan.cc b/src/simutrans/world/simplan.cc
index 90aed59e4..9a99a095f 100644
--- a/src/simutrans/world/simplan.cc
+++ b/src/simutrans/world/simplan.cc
@@ -483,7 +483,7 @@ void planquadrat_t::display_obj(const sint16 xpos, const sint16 ypos, const sint
 		// clip everything at the next tile above
 		if(  i < ground_size  ) {
 
-			clip_dimension p_cr = display_get_clip_wh( CLIP_NUM_VAR );
+			clip_dimension p_cr = g_simgraph->get_clip_rect( CLIP_NUM_VAR );
 
 			for(  uint8 j = i;  j < ground_size;  j++  ) {
 				const sint8 h = data.some[j]->get_hoehe();
@@ -501,13 +501,14 @@ void planquadrat_t::display_obj(const sint16 xpos, const sint16 ypos, const sint
 					// something on top: clip horizontally to prevent trees etc shining trough bridges
 					const sint16 yh = ypos - tile_raster_scale_y( (h + corner_nw(data.some[j]->get_grund_hang()) - h0) * TILE_HEIGHT_STEP, raster_tile_width ) + ((3 * raster_tile_width) >> 2);
 					if(  yh >= p_cr.y  ) {
-						display_push_clip_wh(p_cr.x, yh, p_cr.w, p_cr.h + p_cr.y - yh  CLIP_NUM_PAR  );
+						g_simgraph->push_clip_rect(p_cr.x, yh, p_cr.w, p_cr.h + p_cr.y - yh  CLIP_NUM_PAR  );
 					}
 					break;
 				}
 			}
+
 			gr0->display_obj_all( xpos, ypos, raster_tile_width, is_global  CLIP_NUM_PAR );
-			display_pop_clip_wh(CLIP_NUM_VAR);
+			g_simgraph->pop_clip_rect(CLIP_NUM_VAR);
 		}
 		else {
 			gr0->display_obj_all( xpos, ypos, raster_tile_width, is_global  CLIP_NUM_PAR );
@@ -585,22 +586,22 @@ void planquadrat_t::display_overlay(const sint16 xpos, const sint16 ypos) const
 		if(gb) {
 			fabrik_t* fab=gb->get_fabrik();
 			if(fab) {
-				FLAGGED_PIXVAL status = color_idx_to_rgb(COL_RED);
+				FLAGGED_PIXVAL status = g_simgraph->palette_lookup(COL_RED);
 				if(fab->get_desc()->is_electricity_producer()) {
-					status = color_idx_to_rgb(COL_LIGHT_BLUE);
+					status = g_simgraph->palette_lookup(COL_LIGHT_BLUE);
 					if(fab->is_transformer_connected()) {
-						status = color_idx_to_rgb(COL_LIGHT_TURQUOISE);
+						status = g_simgraph->palette_lookup(COL_LIGHT_TURQUOISE);
 					}
 				}
 				else {
 					if(fab->is_transformer_connected()) {
-						status = color_idx_to_rgb(COL_ORANGE);
+						status = g_simgraph->palette_lookup(COL_ORANGE);
 					}
 					if(fab->get_prodfactor_electric()>0) {
-						status = color_idx_to_rgb(COL_GREEN);
+						status = g_simgraph->palette_lookup(COL_GREEN);
 					}
 				}
-				display_img_blend( overlay_img(gr), xpos, ypos, status | OUTLINE_FLAG | TRANSPARENT50_FLAG, 0, true);
+				g_simgraph->draw_img_blend( overlay_img(gr), xpos, ypos, status | OUTLINE_FLAG | TRANSPARENT50_FLAG, 0, true);
 			}
 		}
 	}
@@ -614,8 +615,8 @@ void planquadrat_t::display_overlay(const sint16 xpos, const sint16 ypos) const
 			image_id img = overlay_img(gr);
 
 			for(int halt_count = 0; halt_count < halt_list_count; halt_count++) {
-				const FLAGGED_PIXVAL transparent = PLAYER_FLAG | OUTLINE_FLAG | color_idx_to_rgb(halt_list[halt_count]->get_owner()->get_player_color1() + 4);
-				display_img_blend( img, xpos, ypos, transparent | TRANSPARENT25_FLAG, 0, 0);
+				const FLAGGED_PIXVAL transparent = PLAYER_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(halt_list[halt_count]->get_owner()->get_player_color1() + 4);
+				g_simgraph->draw_img_blend( img, xpos, ypos, transparent | TRANSPARENT25_FLAG, 0, 0);
 			}
 /*
 // unfortunately, too expensive for display
@@ -623,7 +624,7 @@ void planquadrat_t::display_overlay(const sint16 xpos, const sint16 ypos) const
 			// doesn't affect the colour displayed [since blend(col1,blend(col2,screen)) != blend(col2,blend(col1,screen))]
 			for(int player_count = 0; player_count<MAX_PLAYER_COUNT; player_count++) {
 				player_t *display_player = welt->get_player(player_count);
-				const FLAGGED_PIXVAL transparent = PLAYER_FLAG | OUTLINE_FLAG | color_idx_to_rgb(display_player->get_player_color1() * 4 + 4);
+				const FLAGGED_PIXVAL transparent = PLAYER_FLAG | OUTLINE_FLAG | g_simgraph->palette_lookup(display_player->get_player_color1() * 4 + 4);
 				for(int halt_count = 0; halt_count < halt_list_count; halt_count++) {
 					if(halt_list[halt_count]->get_owner() == display_player) {
 						display_img_blend( img, xpos, ypos, transparent | TRANSPARENT25_FLAG, 0, 0);
@@ -633,7 +634,7 @@ void planquadrat_t::display_overlay(const sint16 xpos, const sint16 ypos) const
 	*/
 		}
 		else {
-			const sint16 raster_tile_width = get_tile_raster_width();
+			const sint16 raster_tile_width = g_simgraph->get_tile_raster_width();
 			// opaque boxes (
 			const sint16 r=raster_tile_width/8;
 			const sint16 x=xpos+raster_tile_width/2-r;
@@ -642,14 +643,14 @@ void planquadrat_t::display_overlay(const sint16 xpos, const sint16 ypos) const
 			const sint16 off = (raster_tile_width>>5);
 			// suitable start search
 			for (size_t h = halt_list_count; h-- != 0;) {
-				display_fillbox_wh_clip_rgb(x - h * off, y + h * off, r, r, PLAYER_FLAG | color_idx_to_rgb(halt_list[h]->get_owner()->get_player_color1() + 4), kartenboden_dirty);
+				g_simgraph->draw_rect_clipped(x - h * off, y + h * off, r, r, PLAYER_FLAG | g_simgraph->palette_lookup(halt_list[h]->get_owner()->get_player_color1() + 4), kartenboden_dirty CLIP_NUM_DEFAULT);
 			}
 		}
 	}
 
 	gr->display_overlay( xpos, ypos );
 	if(  ground_size > 1  ) {
-		const sint16 raster_tile_width = get_tile_raster_width();
+		const sint16 raster_tile_width = g_simgraph->get_tile_raster_width();
 		const sint8 h0 = gr->get_disp_height();
 		for(  uint8 i = 1;  i < ground_size;  i++  ) {
 			grund_t* gr = data.some[i];
diff --git a/src/simutrans/world/simworld.cc b/src/simutrans/world/simworld.cc
index 0b80d8d42..9ced89028 100644
--- a/src/simutrans/world/simworld.cc
+++ b/src/simutrans/world/simworld.cc
@@ -1217,8 +1217,9 @@ void karte_t::init(settings_t* const sets, sint8 const* const h_field)
 	for(  uint i=0;  i<MAX_PLAYER_COUNT;  i++  ) {
 		selected_tool[i] = tool_t::general_tool[TOOL_QUERY];
 	}
-	if(is_display_init()) {
-		display_show_pointer(false);
+
+	if (g_simgraph->is_display_init()) {
+		g_simgraph->set_cursor_visible(false);
 	}
 	viewport->change_world_position( koord(0,0), 0, 0 );
 
@@ -1341,8 +1342,8 @@ DBG_DEBUG("karte_t::init()","built timeline");
 	simloops = 60;
 	reset_timer();
 
-	if(is_display_init()) {
-		display_show_pointer(true);
+	if(g_simgraph->is_display_init()) {
+		g_simgraph->set_cursor_visible(true);
 	}
 	mute_sound(false);
 }
@@ -1697,8 +1698,8 @@ void karte_t::enlarge_map(settings_t const* sets, sint8 const* const h_field)
 		mute_sound(true);
 		minimap_t::is_visible = false;
 
-		if(is_display_init()) {
-			display_show_pointer(false);
+		if (g_simgraph->is_display_init()) {
+			g_simgraph->set_cursor_visible(false);
 		}
 
 // Copy old values:
@@ -1975,8 +1976,8 @@ void karte_t::enlarge_map(settings_t const* sets, sint8 const* const h_field)
 	clear_random_mode( MAP_CREATE_RANDOM );
 
 	if ( !new_world ) {
-		if(is_display_init()) {
-			display_show_pointer(true);
+		if (g_simgraph->is_display_init()) {
+			g_simgraph->set_cursor_visible(true);
 		}
 		mute_sound(false);
 
@@ -2699,10 +2700,10 @@ void karte_t::display(uint32 delta_t)
 		vehicle_t const& v       = *follow_convoi->front();
 		koord3d   const  new_pos = v.get_pos();
 		if(new_pos!=koord3d::invalid) {
-			const sint16 rw = get_tile_raster_width();
+			const sint16 rw = g_simgraph->get_tile_raster_width();
 			int new_xoff = 0;
 			int new_yoff = 0;
-			v.get_screen_offset( new_xoff, new_yoff, get_tile_raster_width() );
+			v.get_screen_offset( new_xoff, new_yoff, g_simgraph->get_tile_raster_width() );
 			new_xoff -= tile_raster_scale_x(-v.get_xoff(), rw);
 			new_yoff -= tile_raster_scale_y(-v.get_yoff(), rw) + tile_raster_scale_y(new_pos.z * TILE_HEIGHT_STEP, rw);
 			viewport->change_world_position( new_pos.get_2d(), -new_xoff, -new_yoff );
@@ -2767,7 +2768,7 @@ void karte_t::update_frame_sleep_time()
 			simloops = (10000*32l)/(last_step_nr[last_step]-last_step_nr[steps%32]);
 		}
 		// (de-)activate faster redraw
-		env_t::simple_drawing = (env_t::simple_drawing_normal >= get_tile_raster_width());
+		env_t::simple_drawing = (env_t::simple_drawing_normal >= g_simgraph->get_tile_raster_width());
 
 		// calculate and activate fast redraw ..
 		if(  realFPS > (env_t::fps*17/16)  ) {
@@ -2778,11 +2779,11 @@ void karte_t::update_frame_sleep_time()
 		}
 		else if(  realFPS < env_t::fps*16/2  ) {
 			// activate simple redraw
-			env_t::simple_drawing_normal = max( env_t::simple_drawing_normal, get_tile_raster_width()+1 );
+			env_t::simple_drawing_normal = max( env_t::simple_drawing_normal, g_simgraph->get_tile_raster_width()+1 );
 		}
 		else if(  realFPS < (env_t::fps*15)  )  {
 			// increase fast tile redraw by one if below current tile size
-			if(  env_t::simple_drawing_normal <= (get_tile_raster_width()*3)/2  ) {
+			if(  env_t::simple_drawing_normal <= (g_simgraph->get_tile_raster_width()*3)/2  ) {
 				env_t::simple_drawing_normal ++;
 			}
 		}
@@ -2792,7 +2793,7 @@ void karte_t::update_frame_sleep_time()
 				env_t::simple_drawing_normal --;
 			}
 		}
-		env_t::simple_drawing = (env_t::simple_drawing_normal >= get_tile_raster_width());
+		env_t::simple_drawing = (env_t::simple_drawing_normal >= g_simgraph->get_tile_raster_width());
 
 		// way too slow => try to increase time ...
 		if(  frame_end_time-last_interaction > 100  ) {
@@ -2800,8 +2801,8 @@ void karte_t::update_frame_sleep_time()
 				idle_time >>= 1;
 				set_frame_time( 1+get_frame_time() );
 				// more than 1s since last zoom => check if zoom out is a way to improve it
-				if(  frame_end_time-last_interaction > 5000  &&  get_current_tile_raster_width() < 32  &&  realFPS <= 80  ) {
-					zoom_factor_up();
+				if(  frame_end_time-last_interaction > 5000  &&  g_simgraph->get_current_tile_raster_width() < 32  &&  realFPS <= (5*16)  ) {
+					g_simgraph->zoom_factor_up();
 					viewport->metrics_updated();
 					set_dirty();
 					last_interaction = frame_end_time-1000;
@@ -2849,7 +2850,7 @@ void karte_t::update_frame_sleep_time()
 			increase_frame_time();
 		}
 		// (de-)activate faster redraw
-		env_t::simple_drawing = env_t::simple_drawing_fast_forward  ||  (env_t::simple_drawing_normal >= get_tile_raster_width());
+		env_t::simple_drawing = env_t::simple_drawing_fast_forward  ||  (env_t::simple_drawing_normal >= g_simgraph->get_tile_raster_width());
 	}
 }
 
@@ -3560,7 +3561,7 @@ void karte_t::save(const char *filename, bool autosave, const char *version_str,
 	std::string savename = filename;
 	savename[savename.length()-1] = '_';
 
-	display_show_load_pointer( true );
+	g_simgraph->set_show_load_cursor(true);
 	const loadsave_t::mode_t mode = autosave ? loadsave_t::autosave_mode : loadsave_t::save_mode;
 	const int save_level = autosave ? loadsave_t::autosave_level : loadsave_t::save_level;
 
@@ -3586,7 +3587,7 @@ void karte_t::save(const char *filename, bool autosave, const char *version_str,
 		}
 		reset_interaction();
 	}
-	display_show_load_pointer( false );
+	g_simgraph->set_show_load_cursor(false);
 }
 
 
@@ -3814,7 +3815,7 @@ bool karte_t::load(const char *filename)
 	bool restore_player_nr = false;
 	bool server_reload_pwd_hashes = false;
 	mute_sound(true);
-	display_show_load_pointer(true);
+	g_simgraph->set_show_load_cursor(true);
 	loadsave_t file;
 
 	// clear hash table with missing paks (may cause some small memory loss though)
@@ -3835,7 +3836,7 @@ bool karte_t::load(const char *filename)
 		const char *err = network_connect(filename+4, this);
 		if(err) {
 			create_win( new news_img(err), w_info, magic_none );
-			display_show_load_pointer(false);
+			g_simgraph->set_show_load_cursor(false);
 			step_mode = NORMAL;
 			return false;
 		}
@@ -3974,7 +3975,7 @@ bool karte_t::load(const char *filename)
 		set_tool( tool_t::general_tool[TOOL_QUERY], get_active_player() );
 	}
 	settings.set_filename(filename);
-	display_show_load_pointer(false);
+	g_simgraph->set_show_load_cursor(false);
 	return ok;
 }
 
@@ -5590,7 +5591,7 @@ void karte_t::remove_player(uint8 player_nr)
 			active_player_nr = PLAYER_HUMAN_NR;
 			active_player = players[PLAYER_HUMAN_NR];
 			if(  !env_t::server  ) {
-				const scr_coord pos{ display_get_width()/2-128, 40 };
+				const scr_coord pos{ g_simgraph->get_screen_size().w/2 - 128, 40 };
 				create_win( pos, new news_img("Bankrott:\n\nDu bist bankrott.\n"), w_info, magic_none);
 			}
 		}
@@ -6382,7 +6383,7 @@ bool karte_t::interactive(uint32 quit_month)
 	}
 
 	intr_enable();
-	display_show_pointer(true);
+	g_simgraph->set_show_load_cursor(true);
 	return finish_loop;
 #undef LRAND
 }
@@ -6531,7 +6532,7 @@ void karte_t::network_disconnect()
 	step_mode = NORMAL;
 	reset_timer();
 	clear_command_queue();
-	create_win({ display_get_width()/2-128, 40 }, new news_img("Lost synchronisation\nwith server."), w_info, magic_none);
+	create_win({ g_simgraph->get_screen_size().w/2 - 128, 40 }, new news_img("Lost synchronisation\nwith server."), w_info, magic_none);
 	ticker::add_msg( translator::translate("Lost synchronisation\nwith server."), koord3d::invalid, SYSCOL_TEXT );
 	last_active_player_nr = active_player_nr;
 	finish_loop = true; // kick me out to main screen
