summaryrefslogtreecommitdiff
path: root/graphics.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics.c')
-rw-r--r--graphics.c401
1 files changed, 401 insertions, 0 deletions
diff --git a/graphics.c b/graphics.c
new file mode 100644
index 00000000..8787e05e
--- /dev/null
+++ b/graphics.c
@@ -0,0 +1,401 @@
+#include <glib.h>
+#include "string.h"
+#include "draw_info.h"
+#include "graphics.h"
+#include "map_data.h"
+#include "coord.h"
+#include "param.h" /* FIXME */
+#include "block.h" /* FIXME */
+#include "poly.h"
+#include "town.h"
+#include "street.h"
+#include "transform.h"
+#include "container.h"
+
+
+#define GC_BACKGROUND 0
+#define GC_WOOD 1
+#define GC_TOWN_FILL 2
+#define GC_TOWN_LINE 3
+#define GC_WATER_FILL 4
+#define GC_WATER_LINE 5
+#define GC_RAIL 6
+#define GC_TEXT_FG 7
+#define GC_TEXT_BG 8
+#define GC_BLACK 9
+#define GC_STREET_SMALL 10
+#define GC_STREET_SMALL_B 11
+#define GC_PARK 12
+#define GC_BUILDING 13
+#define GC_BUILDING_2 14
+#define GC_STREET_MID 15
+#define GC_STREET_MID_B 16
+#define GC_STREET_BIG 17
+#define GC_STREET_BIG_B 18
+#define GC_STREET_BIG2 19
+#define GC_STREET_BIG2_B 20
+#define GC_STREET_BIG2_L 21
+#define GC_STREET_NO_PASS 22
+#define GC_STREET_ROUTE 23
+#define GC_LAST 24
+
+
+int color[][3]={
+ {0xffff, 0xefef, 0xb7b7},
+ {0x8e8e, 0xc7c7, 0x8d8d},
+ {0xffff, 0xc8c8, 0x9595},
+ {0xebeb, 0xb4b4, 0x8181},
+ {0x8282, 0xc8c8, 0xeaea},
+ {0x5050, 0x9696, 0xb8b8},
+ {0x8080, 0x8080, 0x8080},
+ {0x0, 0x0, 0x0},
+ {0xffff, 0xffff, 0xffff},
+ {0x0, 0x0, 0x0},
+ {0xffff, 0xffff, 0xffff},
+ {0xe0e0, 0xe0e0, 0xe0e0},
+ {0x7c7c, 0xc3c3, 0x3434},
+ {0xe6e6, 0xe6e6, 0xe6e6},
+ {0xffff, 0x6666, 0x6666},
+ {0xffff, 0xffff, 0x0a0a},
+ {0xe0e0, 0xe0e0, 0xe0e0},
+ {0xffff, 0x0000, 0x0000},
+ {0x0000, 0x0000, 0x0000},
+ {0xffff, 0xffff, 0x0a0a},
+ {0xffff, 0x0000, 0x0000},
+ {0xffff, 0x0000, 0x0000},
+ {0xe0e0, 0xe0e0, 0xffff},
+ {0x0000, 0x0000, 0xa0a0},
+};
+
+void
+container_init_gra(struct container *co)
+{
+ struct graphics *gra=co->gra;
+ int i;
+
+ gra->font=g_new0(struct graphics_font *,3);
+ gra->font[0]=gra->font_new(gra,140);
+ gra->font[1]=gra->font_new(gra,200);
+ gra->font[2]=gra->font_new(gra,300);
+ gra->gc=g_new0(struct graphics_gc *, GC_LAST);
+ for (i = 0 ; i < GC_LAST ; i++) {
+ gra->gc[i]=gra->gc_new(gra);
+ gra->gc_set_background(gra->gc[i], color[0][0], color[0][1], color[0][2]);
+ gra->gc_set_foreground(gra->gc[i], color[i][0], color[i][1], color[i][2]);
+ }
+ gra->gc_set_background(gra->gc[GC_TEXT_BG], color[7][0], color[7][1], color[7][2]);
+}
+
+void
+graphics_get_view(struct container *co, long *x, long *y, unsigned long *scale)
+{
+ struct transformation *t=co->trans;
+ if (x) *x=t->center.x;
+ if (y) *y=t->center.y;
+ if (scale) *scale=t->scale;
+}
+
+void
+graphics_set_view(struct container *co, long *x, long *y, unsigned long *scale)
+{
+ struct transformation *t=co->trans;
+ if (x) t->center.x=*x;
+ if (y) t->center.y=*y;
+ if (scale) t->scale=*scale;
+ graphics_redraw(co);
+}
+
+void
+graphics_draw(struct map_data *mdata, int file, struct container *co, int display, int limit, int limit2,
+ void(*func)(struct block_info *, unsigned char *, unsigned char *, void *))
+{
+ struct draw_info info;
+ info.co=co;
+ info.display=display;
+ info.limit=limit;
+ map_data_foreach(mdata, file, co->trans, limit2, func, &info);
+}
+
+void
+graphics_redraw(struct container *co)
+{
+ int scale=transform_get_scale(co->trans);
+ int i,slimit=255,tlimit=255,plimit=255;
+ int bw[4],w[4],t[4];
+ struct display_list **disp=co->disp;
+ struct graphics *gra=co->gra;
+
+#if 0
+ printf("scale=%d center=0x%lx,0x%lx mercator scale=%f\n", scale, co->trans->center.x, co->trans->center.y, transform_scale(co->trans->center.y));
+#endif
+
+ display_free(co->disp, display_end);
+
+ transform_setup_source_rect(co->trans);
+
+ gra->draw_mode(gra, draw_mode_begin);
+ for (i = 0 ; i < data_window_type_end; i++) {
+ data_window_begin(co->data_window[i]);
+ }
+ gra->gc_set_linewidth(gra->gc[GC_RAIL], 3);
+
+ bw[0]=0;
+ bw[1]=0;
+ bw[2]=0;
+ bw[3]=0;
+ w[0]=1;
+ w[1]=1;
+ w[2]=1;
+ w[3]=1;
+ t[0]=0xf;
+ t[1]=0xf;
+ t[2]=0xf;
+ t[3]=0xf;
+ if (scale < 2) {
+ tlimit=0xff;
+ slimit=0xff;
+ bw[0]=17;
+ w[0]=15;
+ bw[1]=19;
+ w[1]=17;
+ bw[2]=19;
+ w[2]=17;
+ bw[3]=21;
+ w[3]=17;
+ } else if (scale < 4) {
+ tlimit=0xff;
+ slimit=0xff;
+ bw[0]=11;
+ w[0]=9;
+ bw[1]=13;
+ w[1]=11;
+ bw[2]=13;
+ w[2]=11;
+ bw[3]=15;
+ w[3]=11;
+ } else if (scale < 8) {
+ tlimit=0xff;
+ slimit=0xff;
+ bw[0]=5;
+ w[0]=3;
+ bw[1]=11;
+ w[1]=9;
+ bw[2]=11;
+ w[2]=9;
+ bw[3]=13;
+ w[3]=9;
+ t[0]=0xa;
+ t[1]=0xf;
+ } else if (scale < 16) {
+ tlimit=0xff;
+ slimit=0xff;
+ bw[1]=9;
+ w[1]=7;
+ bw[2]=9;
+ w[2]=7;
+ bw[3]=11;
+ w[3]=7;
+ t[0]=0x9;
+ t[1]=0xe;
+ } else if (scale < 32) {
+ tlimit=0xff;
+ slimit=0xff;
+ bw[1]=5;
+ w[1]=3;
+ bw[2]=5;
+ w[2]=3;
+ bw[3]=5;
+ w[3]=3;
+ t[0]=0x8;
+ t[1]=0xb;
+ } else if (scale < 64) {
+ tlimit=0xf;
+ slimit=0x6;
+ bw[1]=5;
+ w[1]=3;
+ bw[2]=5;
+ w[2]=3;
+ bw[3]=5;
+ w[3]=3;
+ t[0]=0x8;
+ t[1]=0xa;
+ } else if (scale < 128) {
+ tlimit=0xc;
+ slimit=0x6;
+ plimit=0x1e;
+ w[1]=3;
+ w[2]=3;
+ bw[3]=5;
+ w[3]=3;
+ t[0]=0x7;
+ t[1]=0xa;
+ } else if (scale < 256) {
+ tlimit=0xb;
+ slimit=0x5;
+ plimit=0x1a;
+ w[2]=3;
+ bw[3]=5;
+ w[3]=3;
+ t[0]=0x7;
+ t[1]=0x8;
+ } else if (scale < 512) {
+ tlimit=0x9;
+ slimit=0x5;
+ plimit=0x14;
+ w[1]=0;
+ w[2]=1;
+ bw[3]=3;
+ w[3]=1;
+ t[0]=0x4;
+ t[1]=0x7;
+ } else if (scale < 1024) {
+ tlimit=0x8;
+ slimit=0x4;
+ slimit=0x4;
+ plimit=0x11;
+ w[1]=0;
+ w[2]=1;
+ bw[3]=3;
+ w[3]=1;
+ t[0]=0x3;
+ t[1]=0x5;
+ } else if (scale < 2048) {
+ tlimit=0x5;
+ slimit=0x3;
+ plimit=0x10;
+ bw[3]=3;
+ w[3]=1;
+ t[0]=0x2;
+ t[1]=0x4;
+ } else if (scale < 4096) {
+ bw[3]=3;
+ w[3]=1;
+ tlimit=0x4;
+ slimit=0x2;
+ plimit=0xf;
+ t[0]=0x2;
+ t[1]=0x3;
+ } else if (scale < 8192) {
+ bw[3]=3;
+ w[3]=1;
+ tlimit=0x3;
+ slimit=0x2;
+ plimit=0xf;
+ t[0]=0x1;
+ t[1]=0x2;
+ } else {
+ bw[3]=3;
+ w[3]=1;
+ tlimit=0x2;
+ slimit=0x2;
+ plimit=0xf;
+ t[0]=0x1;
+ t[1]=0x4;
+ }
+ gra->gc_set_linewidth(gra->gc[GC_STREET_SMALL], w[0]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_NO_PASS], w[0]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_SMALL_B], bw[0]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_MID], w[1]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_MID_B], bw[1]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_BIG], w[2]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_BIG_B], bw[2]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_BIG2], w[3]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_BIG2_B], bw[3]);
+ gra->gc_set_linewidth(gra->gc[GC_STREET_ROUTE], w[3]+7+w[3]/2);
+
+ profile_timer(NULL);
+ graphics_draw(co->map_data, file_border_ply, co, display_rail, plimit, 48, poly_draw_block);
+ graphics_draw(co->map_data, file_woodland_ply, co, display_wood, plimit, 48, poly_draw_block);
+ graphics_draw(co->map_data, file_other_ply, co, display_other, plimit, 48, poly_draw_block);
+ graphics_draw(co->map_data, file_town_twn, co, display_town, tlimit, 48, town_draw_block);
+ graphics_draw(co->map_data, file_water_ply, co, display_water, plimit, 48, poly_draw_block);
+ graphics_draw(co->map_data, file_sea_ply, co, display_sea, plimit, 48, poly_draw_block);
+ /* todo height, tunnel, bridge, street_bti ??? */
+#if 0
+ graphics_draw(co->map_data, file_height_ply, co, display_other1, plimit, 48, poly_draw_block);
+#endif
+ if (scale < 256) {
+ graphics_draw(co->map_data, file_rail_ply, co, display_rail, plimit, 48, poly_draw_block);
+ }
+ profile_timer("map_draw");
+ plugin_call_draw(co);
+ profile_timer("plugin");
+#if 0
+ draw_poly(map, &co->d_tunnel_ply, "Tunnel", 0, 11, plimit);
+#endif
+ graphics_draw(co->map_data, file_street_str, co, display_street, slimit, 7, street_draw_block);
+
+ display_draw(disp[display_sea], gra, gra->gc[GC_WATER_FILL], NULL);
+ display_draw(disp[display_wood], gra, gra->gc[GC_WOOD], NULL);
+ display_draw(disp[display_other], gra, gra->gc[GC_TOWN_FILL], gra->gc[GC_TOWN_LINE]);
+ display_draw(disp[display_other1], gra, gra->gc[GC_BUILDING], NULL);
+ display_draw(disp[display_other2], gra, gra->gc[GC_BUILDING_2], NULL);
+ display_draw(disp[display_other3], gra, gra->gc[GC_PARK], NULL);
+ display_draw(disp[display_water], gra, gra->gc[GC_WATER_FILL], gra->gc[GC_WATER_LINE]);
+ display_draw(disp[display_rail], gra, gra->gc[GC_RAIL], NULL);
+ street_route_draw(co);
+ display_draw(disp[display_street_route], gra, gra->gc[GC_STREET_ROUTE], NULL);
+ if (bw[0]) {
+ display_draw(disp[display_street_no_pass], gra, gra->gc[GC_STREET_SMALL_B], NULL);
+ display_draw(disp[display_street], gra, gra->gc[GC_STREET_SMALL_B], NULL);
+ }
+ if (bw[1])
+ display_draw(disp[display_street1], gra, gra->gc[GC_STREET_MID_B], NULL);
+ if (bw[2])
+ display_draw(disp[display_street2], gra, gra->gc[GC_STREET_BIG_B], NULL);
+ if (bw[3])
+ display_draw(disp[display_street3], gra, gra->gc[GC_STREET_BIG2_B], NULL);
+ if (w[0]) {
+ display_draw(disp[display_street_no_pass], gra, gra->gc[GC_STREET_NO_PASS], NULL);
+ display_draw(disp[display_street], gra, gra->gc[GC_STREET_SMALL], NULL);
+ }
+ if (w[1])
+ display_draw(disp[display_street1], gra, gra->gc[GC_STREET_MID], gra->gc[GC_BLACK]);
+ display_draw(disp[display_street2], gra, gra->gc[GC_STREET_BIG], gra->gc[GC_BLACK]);
+ display_draw(disp[display_street3], gra, gra->gc[GC_STREET_BIG2], gra->gc[GC_BLACK]);
+ if (w[3] > 1)
+ display_draw(disp[display_street3], gra, gra->gc[GC_STREET_BIG2_L], NULL);
+
+ display_draw(disp[display_poi], gra, gra->gc[GC_BLACK], NULL);
+
+
+ profile_timer("display_draw");
+
+ if (scale < 2) {
+ display_labels(disp[display_street], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[1]);
+ display_labels(disp[display_street1], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[1]);
+ }
+ else {
+ display_labels(disp[display_street], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[0]);
+ display_labels(disp[display_street1], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[0]);
+ }
+ display_labels(disp[display_street2], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[0]);
+ display_labels(disp[display_street3], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[0]);
+
+ for (i = display_town+t[1] ; i < display_town+0x10 ; i++)
+ display_labels(disp[i], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[0]);
+ for (i = display_town+t[0] ; i < display_town+t[1] ; i++)
+ display_labels(disp[i], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[1]);
+ for (i = display_town ; i < display_town+t[0] ; i++)
+ display_labels(disp[i], gra, gra->gc[GC_TEXT_FG], gra->gc[GC_TEXT_BG], gra->font[2]);
+
+ for (i = display_town ; i < display_town+0x10 ; i++)
+ display_draw(disp[i], gra, gra->gc[GC_BLACK], NULL);
+ display_draw(disp[display_bti], gra, gra->gc[GC_BLACK], NULL);
+ profile_timer("labels");
+ gra->draw_mode(gra, draw_mode_end);
+ for (i = 0 ; i < data_window_type_end; i++) {
+ data_window_end(co->data_window[i]);
+ }
+#if 0
+ map_scrollbars_update(map);
+#endif
+}
+
+void
+graphics_resize(struct container *co, int w, int h)
+{
+ co->trans->width=w;
+ co->trans->height=h;
+ graphics_redraw(co);
+}