rename LICENSE to COPYING and add a more complete LICENSE file.
[rofl0r-openDOW.git] / utils / mapdesigner.c
blob802bf86b20366c8b4c7d66573a1087cae3ebc7b0
1 #include "../map.h"
2 #include "../palpic.h"
3 #include <assert.h>
4 #include <stdio.h>
6 #include <SDL/SDL.h>
7 //RcB: LINK "-lSDL"
8 #include "../sdl_rgb.h"
9 #include "../vec2f.h"
11 #include "../sprites/bg_urban.c"
12 #include "../sprites/bg_forest.c"
13 #include "../sprites/bg_desert.c"
14 #include "../sprites/map_urban.c"
15 #include "../sprites/map_forest.c"
16 #include "../sprites/map_desert.c"
18 #define SCALE 2
19 #define BORDER_W 4
20 #define BORDER_H 4
22 #define STARTX (BORDER_W*SCALE)
23 #define STARTY (BORDER_H*SCALE)
24 #define ENDX (STARTX+192*SCALE)
25 #define ENDY (STARTY+192*SCALE)
27 #define BRUSH_STARTX (STARTX + 192*SCALE + BORDER_W*SCALE)
28 #define BRUSH_STARTY (STARTY)
29 #define BRUSH_ENDX (BRUSH_STARTX + 64*SCALE)
30 #define BRUSH_ENDY (BRUSH_STARTY + 32*6*SCALE)
32 #define BRUSHFG_STARTX (BRUSH_STARTX + 64*SCALE + BORDER_W*SCALE)
33 #define BRUSHFG_STARTY (BRUSH_STARTY)
34 #define BRUSHFG_ENDX (BRUSHFG_STARTX + 14*16*SCALE)
35 #define BRUSHFG_ENDY (BRUSHFG_STARTY + 15*16*SCALE)
37 #define VMODE_W (BRUSHFG_ENDX + BORDER_W*SCALE)
38 #define VMODE_H (BRUSHFG_ENDY + BORDER_H*SCALE)
40 struct map map;
41 struct map_screen mapscreen;
42 SDL_Surface *surface;
43 struct vo_desc video;
45 static void init_video() {
46 SDL_Init(SDL_INIT_VIDEO);
47 surface = SDL_SetVideoMode(VMODE_W, VMODE_H, 32, SDL_RESIZABLE | SDL_HWPALETTE);
48 video.mem = surface->pixels;
49 video.pitch = surface->pitch;
50 video.width = VMODE_W;
51 video.height = VMODE_H;
54 const struct palpic *fg_sprites;
55 const struct palpic *bg_sprites;
56 int fullscreen_active;
57 int grid_enabled;
58 int bonus_layer_activated;
59 struct map_fglayer bonuslayer;
60 int walltag_mode;
62 void paint_map() {
63 int bg_x, bg_y, x, y;
64 int w, h;
65 w = palpic_getspritewidth(bg_sprites);
66 h = palpic_getspriteheight(bg_sprites);
67 for(y= 0, bg_y = 0; bg_y < 192/h; bg_y++, y+=h*SCALE)
68 for(x = 0, bg_x = 0; bg_x < 192/w; bg_x++, x+=w*SCALE) {
69 blit_sprite(STARTX + x, STARTY + y, &video, SCALE, bg_sprites, mapscreen.bg.bg[bg_y][bg_x], 0);
72 w = palpic_getspritewidth(fg_sprites);
73 h = palpic_getspriteheight(fg_sprites);
74 for(y= 0, bg_y = 0; bg_y < 192/h; bg_y++, y+=h*SCALE)
75 for(x = 0, bg_x = 0; bg_x < 192/w; bg_x++, x+=w*SCALE) {
76 blit_sprite(STARTX + x,STARTY + y, &video, SCALE, fg_sprites, mapscreen.fg.fg[bg_y][bg_x], 0);
78 if(bonus_layer_activated) {
79 for(y= 0, bg_y = 0; bg_y < 192/h; bg_y++, y+=h*SCALE)
80 for(x = 0, bg_x = 0; bg_x < 192/w; bg_x++, x+=w*SCALE) {
81 blit_sprite(STARTX + x,STARTY + y, &video, SCALE, fg_sprites, bonuslayer.fg[bg_y][bg_x], 0);
86 void paint_brushes() {
87 int bg_x, bg_y, x, y;
88 int w, h, c;
89 w = palpic_getspritewidth(bg_sprites);
90 h = palpic_getspriteheight(bg_sprites);
91 c = palpic_getspritecount(bg_sprites);
92 for(y = 0, bg_y = 0; y < c; y++, bg_y += h*SCALE)
93 blit_sprite(BRUSH_STARTX, BRUSH_STARTY + bg_y,
94 &video,
95 SCALE, bg_sprites, y, 0);
97 w = palpic_getspritewidth(fg_sprites);
98 h = palpic_getspriteheight(fg_sprites);
99 c = palpic_getspritecount(fg_sprites);
101 for(y= 0; y < c/14; y++)
102 for(x = 0, x = 0; x < 14; x++) {
103 blit_sprite(BRUSHFG_STARTX + x*w*SCALE, BRUSHFG_STARTY + y*h*SCALE,
104 &video,
105 SCALE, fg_sprites, y*14+x, 0);
110 static void draw_grid(int x_pos, int y_pos, int w, int h, int x_count, int y_count, sdl_rgb_t hcol, sdl_rgb_t vcol) {
111 int x,y;
112 sdl_rgb_t *pix = (sdl_rgb_t*) surface->pixels;
113 unsigned pitch = surface->pitch / 4;
114 unsigned max_off = VMODE_H*VMODE_W;
115 unsigned off;
116 /* horizontal */
117 for(y = 0; y <= y_count * h * SCALE; y += h*SCALE) for(x = 0; x <= w * x_count * SCALE; x++) {
118 off = (y_pos + y) * pitch + x + x_pos;
119 if(off >= max_off) break;
120 pix[off] = hcol;
122 /*vertical*/
123 for(y = 0; y <= y_count * h * SCALE; y++) for(x = 0; x <= w * x_count * SCALE; x += w*SCALE) {
124 off = (y_pos + y) * pitch + x + x_pos;
125 if(off >= max_off) break;
126 pix[off] = vcol;
130 static void paint_grids() {
131 #define VIOLET SRGB(255,0,255)
132 #define WHITE SRGB(255,255,255)
133 #define BLUE SRGB(0,0,255)
134 #define BLACK SRGB(0,0,0)
135 draw_grid(STARTX, STARTY, 16, 16, 12, 12, BLACK, BLACK);
136 draw_grid(STARTX, STARTY, 64, 32, 3, 6, WHITE, WHITE);
137 draw_grid(BRUSH_STARTX, BRUSH_STARTY, 64, 32, 1, palpic_getspritecount(bg_sprites), BLUE, WHITE);
138 draw_grid(BRUSHFG_STARTX, BRUSHFG_STARTY, 16, 16, 14, palpic_getspritecount(fg_sprites)/14, VIOLET, WHITE);
141 enum cursor_type { CT_NONE = 0, CT_BG, CT_FG };
142 struct cursor {
143 enum cursor_type ct;
144 vec2f pos;
145 uint8_t spriteno;
146 } cursor;
147 #define mousepos cursor.pos
149 static void paint_cursor() {
150 if(cursor.ct == CT_NONE) return;
151 const struct palpic *p = cursor.ct == CT_BG ? bg_sprites : fg_sprites;
153 blit_sprite(cursor.pos.x, cursor.pos.y,
154 &video, SCALE,
155 p, cursor.spriteno, 0);
156 draw_grid(cursor.pos.x, cursor.pos.y, palpic_getspritewidth(p), palpic_getspriteheight(p), 1, 1, WHITE, WHITE);
159 static void update_screen() {
160 SDL_UpdateRect(surface, 0, 0, VMODE_W, VMODE_H);
163 static void clear() {
164 uint_fast16_t x, w = VMODE_W;
165 uint_fast16_t y, h = VMODE_H;
166 sdl_rgb_t *pix, *ptr = pix = (sdl_rgb_t*) surface->pixels;
167 uint_fast32_t pitch = surface->pitch / 4, inc = pitch - VMODE_W;
168 for(y=0;y<h;y++) {
169 for(x=0;x<w;x++) *ptr++ = SRGB(0,0,0);
170 ptr+=inc;
174 void redraw() {
175 clear();
176 paint_map();
177 paint_brushes();
178 paint_grids();
179 paint_cursor();
180 update_screen();
182 void tick(int force) { redraw(); SDL_Delay(20);}
184 typedef struct {
185 vec2f topleft;
186 vec2f bottomright;
187 } rect;
189 #define point_in_rect(POINT_PTR, RECT_PTR) ((POINT_PTR)->x >= (RECT_PTR)->topleft.x && \
190 (POINT_PTR)->x <= (RECT_PTR)->bottomright.x && \
191 (POINT_PTR)->y >= (RECT_PTR)->topleft.y && \
192 (POINT_PTR)->y <= (RECT_PTR)->bottomright.y )
194 #ifndef IN_KDEVELOP_PARSER
195 #define RECT(A,B,C,D) { {A, B}, {C, D}}
196 static rect map_rect = RECT(STARTX,STARTY,ENDX,ENDY);
197 static rect brushbg_rect = RECT(BRUSH_STARTX,BRUSH_STARTY, BRUSH_ENDX, BRUSH_ENDY);
198 static rect brushfg_rect = RECT(BRUSHFG_STARTX,BRUSHFG_STARTY, BRUSHFG_ENDX, BRUSHFG_ENDY);
199 #endif
201 vec2f get_tile(rect* area, int w, int h, vec2f* pos) {
202 vec2f ret;
203 ret.x = (pos->x - area->topleft.x) / w;
204 ret.y = (pos->y - area->topleft.y) / h;
205 return ret;
208 static void disable_sdl_cursor() {
209 if(cursor.ct == CT_NONE)
210 SDL_ShowCursor(0);
213 static void fill() {
214 vec2f tile = get_tile(&brushbg_rect, 64*SCALE, 32*SCALE, &cursor.pos);
215 int x,y;
216 for(y = 0; y < 6; y++) for(x=0; x < 3; x++) mapscreen.bg.bg[y][x] = tile.y;
219 static void set_bg() {
220 vec2f tile = get_tile(&brushbg_rect, 64*SCALE, 32*SCALE, &cursor.pos);
221 disable_sdl_cursor();
222 cursor.ct = CT_BG;
223 cursor.spriteno = tile.y;
226 static void set_fg() {
227 vec2f tile = get_tile(&brushfg_rect, 16*SCALE, 16*SCALE, &cursor.pos);
228 disable_sdl_cursor();
229 cursor.ct = CT_FG;
230 cursor.spriteno = (int)tile.y * 14 + (int)tile.x;
233 static void print_wall() {
234 vec2f tile = get_tile(&brushfg_rect, 16*SCALE, 16*SCALE, &cursor.pos);
235 int spriteno = (int)tile.y * 14 + (int)tile.x;
236 printf("[%d] = 1,\n", spriteno);
239 static void set_map_bg() {
240 vec2f tile = get_tile(&map_rect, 64*SCALE, 32*SCALE, &cursor.pos);
241 mapscreen.bg.bg[(int)tile.y][(int)tile.x] = cursor.spriteno;
244 static void set_map_fg() {
245 vec2f tile = get_tile(&map_rect, 16*SCALE, 16*SCALE, &cursor.pos);
246 if(bonus_layer_activated)
247 bonuslayer.fg[(int)tile.y][(int)tile.x] = cursor.spriteno;
248 else
249 mapscreen.fg.fg[(int)tile.y][(int)tile.x] = cursor.spriteno;
252 static void process_click(int isleft) {
253 if(point_in_rect(&cursor.pos, &map_rect)) {
254 if(!isleft) return;
255 if(cursor.ct == CT_BG) set_map_bg();
256 else if(cursor.ct == CT_FG) set_map_fg();
257 } else if (point_in_rect(&cursor.pos, &brushbg_rect)) {
258 if(isleft) set_bg();
259 else fill();
260 } else if (point_in_rect(&cursor.pos, &brushfg_rect)) {
261 if(walltag_mode) print_wall();
262 else if(isleft) set_fg();
266 void print_map() {
267 int i;
268 printf("A\n");
269 for(i = 0; i < sizeof(mapscreen.bg.bg); i++)
270 printf(i % 3 == 2 ? "%d,\n" : "%d,", (int)((unsigned char*)(mapscreen.bg.bg))[i]);
271 printf("B\n");
272 for(i = 0; i < sizeof(mapscreen.fg.fg); i++)
273 printf(i % 12 == 11 ? "%3d,\n" : "%3d,", (int)((unsigned char*)(mapscreen.fg.fg))[i]);
274 int dobonus = 0;
275 for(i = 0; i < sizeof(bonuslayer.fg); i++) {
276 if(((char*)bonuslayer.fg)[i] != 0) {
277 dobonus = 1;
278 break;
281 if(dobonus) {
282 printf("C\n");
283 for(i = 0; i < sizeof(bonuslayer.fg); i++)
284 printf(i % 12 == 11 ? "%3d,\n" : "%3d,", (int)((unsigned char*)(bonuslayer.fg))[i]);
286 printf("\n");
289 int main(int argc, char**argv) {
290 memset(&map, 0, sizeof(struct map));
291 memset(&mapscreen, 0, sizeof(struct map_screen));
292 assert(argc == 2 || argc == 3);
293 if(!strcmp(argv[1], "urban"))
294 map.maptype = MT_URBAN;
295 else if(!strcmp(argv[1], "desert"))
296 map.maptype = MT_DESERT;
297 else if(!strcmp(argv[1], "forest"))
298 map.maptype = MT_FOREST;
299 else assert(0);
300 if(argc == 3 && !strcmp(argv[2], "--wall")) walltag_mode = 1;
302 const struct palpic* map_fg_lut[] = {
303 [MT_URBAN] = &map_urban.header,
304 [MT_DESERT] = &map_desert.header,
305 [MT_FOREST] = &map_forest.header,
307 const struct palpic* map_bg_lut[] = {
308 [MT_URBAN] = &bg_urban.header,
309 [MT_DESERT] = &bg_desert.header,
310 [MT_FOREST] = &bg_forest.header,
312 fg_sprites = map_fg_lut[map.maptype];
313 bg_sprites = map_bg_lut[map.maptype];
315 init_video();
316 //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
317 SDL_EnableKeyRepeat(100, 20);
318 tick(1);
319 while(1) {
320 SDL_Event sdl_event;
321 unsigned need_redraw = 0;
322 while (SDL_PollEvent(&sdl_event)) {
323 switch (sdl_event.type) {
324 case SDL_MOUSEMOTION:
325 mousepos.x = sdl_event.motion.x;
326 mousepos.y = sdl_event.motion.y;
327 break;
328 case SDL_MOUSEBUTTONDOWN:
329 mousepos.x = sdl_event.button.x;
330 mousepos.y = sdl_event.button.y;
331 need_redraw = 1;
332 process_click(sdl_event.button.button == SDL_BUTTON_LEFT);
333 break;
334 case SDL_MOUSEBUTTONUP:
335 mousepos.x = sdl_event.button.x;
336 mousepos.y = sdl_event.button.y;
337 break;
338 case SDL_QUIT:
339 dun_goofed:
340 // restore desktop video mode correctly...
341 if(fullscreen_active)
342 SDL_WM_ToggleFullScreen(surface);
343 if(!walltag_mode) print_map();
344 return 0;
345 case SDL_KEYDOWN:
346 switch(sdl_event.key.keysym.sym) {
347 case SDLK_g:
348 grid_enabled = !grid_enabled;
349 need_redraw = 1;
350 break;
351 case SDLK_b:
352 bonus_layer_activated = !bonus_layer_activated;
353 if(bonus_layer_activated) SDL_WM_SetCaption("bonus layer activated",0);
354 else SDL_WM_SetCaption("bonus layer deactivated",0);
355 break;
356 case SDLK_ESCAPE:
357 goto dun_goofed;
358 case SDLK_w: case SDLK_a: case SDLK_s: case SDLK_d:
359 case SDLK_UP:
360 case SDLK_DOWN:
361 case SDLK_RIGHT:
362 case SDLK_LEFT:
363 case SDLK_RETURN:
364 if((sdl_event.key.keysym.mod & KMOD_LALT) ||
365 (sdl_event.key.keysym.mod & KMOD_RALT)) {
366 SDL_WM_ToggleFullScreen(surface);
367 fullscreen_active = !fullscreen_active;
368 } else {
370 break;
371 case SDLK_KP_PLUS:
372 break;
373 case SDLK_KP_MINUS:
374 break;
375 default:
376 break;
378 break;
379 case SDL_KEYUP:
380 switch(sdl_event.key.keysym.sym) {
381 case SDLK_w: case SDLK_a: case SDLK_s: case SDLK_d:
382 case SDLK_UP:
383 case SDLK_DOWN:
384 case SDLK_RIGHT:
385 case SDLK_LEFT:
386 default:
387 break;
389 default:
390 break;
393 tick(need_redraw);