1 // This isn't compilable as-is, as it was extracted from a working
2 // integration-in-a-game and makes reference to symbols from that game.
3 
4 #include <assert.h>
5 #include <ctype.h>
6 #include "game.h"
7 #include "SDL.h"
8 #include "stb_tilemap_editor.h"
9 
10 extern void editor_draw_tile(int x, int y, unsigned short tile, int mode, float *props);
11 extern void editor_draw_rect(int x0, int y0, int x1, int y1, unsigned char r, unsigned char g, unsigned char b);
12 
13 static int is_platform(short *tiles);
14 static unsigned int prop_type(int n, short *tiles);
15 static char *prop_name(int n, short *tiles);
16 static float prop_range(int n, short *tiles, int is_max);
17 static int allow_link(short *src, short *dest);
18 
19 #define STBTE_MAX_PROPERTIES  8
20 
21 #define STBTE_PROP_TYPE(n, tiledata, p) prop_type(n,tiledata)
22 #define STBTE_PROP_NAME(n, tiledata, p) prop_name(n,tiledata)
23 #define STBTE_PROP_MIN(n, tiledata, p)  prop_range(n,tiledata,0)
24 #define STBTE_PROP_MAX(n, tiledata, p)  prop_range(n,tiledata,1)
25 #define STBTE_PROP_FLOAT_SCALE(n,td,p)  (0.1)
26 
27 #define STBTE_ALLOW_LINK(srctile, srcprop, desttile, destprop) \
28            allow_link(srctile, desttile)
29 
30 #define STBTE_LINK_COLOR(srctile, srcprop, desttile, destprop) \
31           (is_platform(srctile) ? 0xff80ff : 0x808040)
32 
33 #define STBTE_DRAW_RECT(x0,y0,x1,y1,c)           \
34           editor_draw_rect(x0,y0,x1,y1,(c)>>16,((c)>>8)&255,(c)&255)
35 
36 #define STBTE_DRAW_TILE(x,y,id,highlight,props)  \
37           editor_draw_tile(x,y,id,highlight,props)
38 
39 
40 
41 #define STB_TILEMAP_EDITOR_IMPLEMENTATION
42 #include "stb_tilemap_editor.h"
43 
44 stbte_tilemap *edit_map;
45 
editor_key(enum stbte_action act)46 void editor_key(enum stbte_action act)
47 {
48    stbte_action(edit_map, act);
49 }
50 
editor_process_sdl_event(SDL_Event * e)51 void editor_process_sdl_event(SDL_Event *e)
52 {
53    switch (e->type) {
54       case SDL_MOUSEMOTION:
55       case SDL_MOUSEBUTTONDOWN:
56       case SDL_MOUSEBUTTONUP:
57       case SDL_MOUSEWHEEL:
58          stbte_mouse_sdl(edit_map, e, 1.0f/editor_scale,1.0f/editor_scale,0,0);
59          break;
60 
61       case SDL_KEYDOWN:
62          if (in_editor) {
63             switch (e->key.keysym.sym) {
64                case SDLK_RIGHT: editor_key(STBTE_scroll_right); break;
65                case SDLK_LEFT : editor_key(STBTE_scroll_left ); break;
66                case SDLK_UP   : editor_key(STBTE_scroll_up   ); break;
67                case SDLK_DOWN : editor_key(STBTE_scroll_down ); break;
68             }
69             switch (e->key.keysym.scancode) {
70                case SDL_SCANCODE_S: editor_key(STBTE_tool_select); break;
71                case SDL_SCANCODE_B: editor_key(STBTE_tool_brush ); break;
72                case SDL_SCANCODE_E: editor_key(STBTE_tool_erase ); break;
73                case SDL_SCANCODE_R: editor_key(STBTE_tool_rectangle ); break;
74                case SDL_SCANCODE_I: editor_key(STBTE_tool_eyedropper); break;
75                case SDL_SCANCODE_L: editor_key(STBTE_tool_link);       break;
76                case SDL_SCANCODE_G: editor_key(STBTE_act_toggle_grid); break;
77             }
78             if ((e->key.keysym.mod & KMOD_CTRL) && !(e->key.keysym.mod & ~KMOD_CTRL)) {
79                switch (e->key.keysym.scancode) {
80                   case SDL_SCANCODE_X: editor_key(STBTE_act_cut  ); break;
81                   case SDL_SCANCODE_C: editor_key(STBTE_act_copy ); break;
82                   case SDL_SCANCODE_V: editor_key(STBTE_act_paste); break;
83                   case SDL_SCANCODE_Z: editor_key(STBTE_act_undo ); break;
84                   case SDL_SCANCODE_Y: editor_key(STBTE_act_redo ); break;
85                }
86             }
87          }
88          break;
89    }
90 }
91 
editor_init(void)92 void editor_init(void)
93 {
94    int i;
95    edit_map = stbte_create_map(20,14, 8, 16,16, 100);
96 
97    stbte_set_background_tile(edit_map, T_empty);
98 
99    for (i=0; i < T__num_types; ++i) {
100       if (i != T_reserved1 && i != T_entry && i != T_doorframe)
101          stbte_define_tile(edit_map, 0+i, 1, "Background");
102    }
103    stbte_define_tile(edit_map, 256+O_player   , 8, "Char");
104    stbte_define_tile(edit_map, 256+O_robot    , 8, "Char");
105    for (i=O_lockeddoor; i < O__num_types-2; ++i)
106       if (i == O_platform || i == O_vplatform)
107          stbte_define_tile(edit_map, 256+i, 4, "Object");
108       else
109          stbte_define_tile(edit_map, 256+i, 2, "Object");
110 
111    //stbte_set_layername(edit_map, 0, "background");
112    //stbte_set_layername(edit_map, 1, "objects");
113    //stbte_set_layername(edit_map, 2, "platforms");
114    //stbte_set_layername(edit_map, 3, "characters");
115 }
116 
is_platform(short * tiles)117 static int is_platform(short *tiles)
118 {
119    // platforms are only on layer #2
120    return tiles[2] == 256 + O_platform || tiles[2] == 256 + O_vplatform;
121 }
122 
is_object(short * tiles)123 static int is_object(short *tiles)
124 {
125    return (tiles[1] >= 256 || tiles[2] >= 256 || tiles[3] >= 256);
126 }
127 
prop_type(int n,short * tiles)128 static unsigned int prop_type(int n, short *tiles)
129 {
130    if (is_platform(tiles)) {
131       static unsigned int platform_types[STBTE_MAX_PROPERTIES] = {
132          STBTE_PROP_bool,  // phantom
133          STBTE_PROP_int,   // x_adjust
134          STBTE_PROP_int,   // y_adjust
135          STBTE_PROP_float, // width
136          STBTE_PROP_float, // lspeed
137          STBTE_PROP_float, // rspeed
138          STBTE_PROP_bool,  // autoreturn
139          STBTE_PROP_bool,  // one-shot
140          // remainder get 0, means 'no property in this slot'
141       };
142       return platform_types[n];
143    } else if (is_object(tiles)) {
144       if (n == 0)
145          return STBTE_PROP_bool;
146    }
147    return 0;
148 }
149 
prop_name(int n,short * tiles)150 static char *prop_name(int n, short *tiles)
151 {
152    if (is_platform(tiles)) {
153       static char *platform_vars[STBTE_MAX_PROPERTIES] = {
154          "phantom",
155          "x_adjust",
156          "y_adjust",
157          "width",
158          "lspeed",
159          "rspeed",
160          "autoreturn",
161          "one-shot",
162       };
163       return platform_vars[n];
164    }
165    return "phantom";
166 }
167 
prop_range(int n,short * tiles,int is_max)168 static float prop_range(int n, short *tiles, int is_max)
169 {
170    if (is_platform(tiles)) {
171       static float ranges[8][2] = {
172          {   0,  1 }, // phantom-flag, range is ignored
173          { -15, 15 }, // x_adjust
174          { -15, 15 }, // y_adjust
175          {   0,  6 }, // width
176          {   0, 10 }, // lspeed
177          {   0, 10 }, // rspeed
178          {   0,  1 }, // autoreturn, range is ignored
179          {   0,  1 }, // one-shot, range is ignored
180       };
181       return ranges[n][is_max];
182    }
183    return 0;
184 }
185 
allow_link(short * src,short * dest)186 static int allow_link(short *src, short *dest)
187 {
188    if (is_platform(src))
189       return dest[1] == 256+O_lever;
190    if (src[1] == 256+O_endpoint)
191       return is_platform(dest);
192    return 0;
193 }
194