00001 #include "editor.h"
00002
00003 editor_map *current_map = NULL;
00004 editor_map *maps = NULL;
00005 int num_maps = 0;
00006 int current_map_num = 0;
00007 int select_x=0, select_y=0;
00008 int cursor_x=0, cursor_y=0;
00009 int edit_brush=1;
00010
00011
00012 void initialize_editor(void)
00013 {
00014 set_num_maps(1);
00015 set_current_map(0);
00016 }
00017
00018
00019 void initialize_map(editor_map *M)
00020 {
00021 memset(M, 0, sizeof(*M));
00022 strcpy(M->name, "Unnamed");
00023 strcpy(M->author, "Anonymous");
00024 }
00025
00026
00027 void cleanup_map(editor_map *M)
00028 {
00029 if(M->t) free(M->t);
00030 M->t = NULL;
00031 }
00032
00033
00034 void set_level_size(int level, int width, int height)
00035 {
00036 map_square **pos, *alloc_pos;
00037 size_t size = sizeof(map_square*)*height + sizeof(map_square)*width*height;
00038 int ii;
00039
00040 if(maps[level].t) free(maps[level].t);
00041
00042
00043 maps[level].t = pos = (map_square**)malloc_throw(size);
00044 memset(pos, 0, size);
00045 alloc_pos = (map_square*)(pos + height);
00046
00047 for(ii=0; ii<height; ii++)
00048 {
00049 *pos = alloc_pos;
00050 pos++;
00051 alloc_pos += width;
00052 }
00053
00054 maps[level].width = width;
00055 maps[level].height = height;
00056 }
00057
00058
00059 void set_num_maps(int n)
00060 {
00061 int ii;
00062 for(ii=n; ii<num_maps; ii++) {
00063 cleanup_map(&maps[ii]);
00064 }
00065 maps = (editor_map*)realloc_throw(maps, sizeof(*maps)*n);
00066 for(ii=num_maps; ii<n; ii++) {
00067 initialize_map(&maps[ii]);
00068 set_level_size(ii, 20, 11);
00069 }
00070 num_maps = n;
00071 if(current_map_num >= num_maps)
00072 current_map_num = num_maps-1;
00073 set_current_map(current_map_num);
00074 }
00075
00076
00077 void set_current_map(int n)
00078 {
00079 current_map_num = n;
00080 current_map = &maps[n];
00081 draw_level_number();
00082 }
00083
00084
00085
00086 void enter_edit_state(void)
00087 {
00088 input_state = editing_state;
00089 draw_current_map();
00090 }
00091
00092
00093 void clear_map(void)
00094 {
00095 int xi, yi;
00096
00097 for(yi=0; yi<FIELD_HEIGHT; yi++)
00098 for(xi=0; xi<FIELD_WIDTH; xi++)
00099 current_map->t[yi][xi] = TILE_EMPTY;
00100 }
00101
00102
00103 void default_map(void)
00104 {
00105 clear_map();
00106 current_map->t[0][0] = TILE_KYE;
00107 current_map->t[0][1] = TILE_DIAMOND;
00108 strcpy(current_map->name, "Unnamed");
00109 strcpy(current_map->author, "Anonymous");
00110 strcpy(current_map->hint, "");
00111 strcpy(current_map->congrat, "");
00112 current_map->gamerules = 0;
00113 }
00114
00115
00116 #define TILEFIELD_TOP 12
00117
00118 void draw_current_map(void)
00119 {
00120 clear_screen();
00121 draw_menu_labels();
00122 draw_map_field();
00123 draw_line(0, 9, (LCD_WIDTH-1), 9, A_NORMAL);
00124 draw_editor_brush();
00125 draw_level_number();
00126 }
00127
00128
00129 int scroll_x=0;
00130 int scroll_y=0;
00131
00132
00133 void draw_map_field(void)
00134 {
00135 int xi, yi;
00136 int xmax = min(VIEWPORT_WIDTH, FIELD_WIDTH-scroll_x);
00137 int ymax = min(VIEWPORT_HEIGHT, FIELD_HEIGHT-scroll_y);
00138
00139 clear_line_range(10, TILEFIELD_TOP);
00140
00141
00142 if(FIELD_WIDTH < VIEWPORT_WIDTH) {
00143 draw_line(FIELD_WIDTH*8+1, 10, FIELD_WIDTH*8+1,
00144 TILEFIELD_TOP+ymax*8, A_NORMAL);
00145 }
00146 if(FIELD_HEIGHT < VIEWPORT_HEIGHT) {
00147 draw_line(0, TILEFIELD_TOP+ymax*8+1, FIELD_WIDTH*8+1,
00148 TILEFIELD_TOP+ymax*8+1, A_NORMAL);
00149 }
00150
00151 for(xi=0; xi<xmax; xi++)
00152 for(yi=0; yi<ymax; yi++)
00153 draw_map_tile(xi+scroll_x, yi+scroll_y);
00154 }
00155
00156
00157 void draw_map_tile(int x, int y)
00158 {
00159 int xpos = (x-scroll_x)<<3;
00160 int ypos = ((y-scroll_y)<<3)+TILEFIELD_TOP;
00161
00162 if( x<scroll_x || y<scroll_y || x>=scroll_x+VIEWPORT_WIDTH
00163 || y>=scroll_y+VIEWPORT_HEIGHT)
00164 return;
00165
00166 draw_sprite(tile_sprites[ current_map->t[y][x] ],
00167 xpos, ypos);
00168 if( ((x>=select_x && x<=cursor_x) || (x<=select_x && x>=cursor_x)) &&
00169 ((y>=select_y && y<=cursor_y) || (y<=select_y && y>=cursor_y)) )
00170 draw_sprite_xor(black_square, xpos, ypos);
00171 }
00172
00173
00174 void xor_tile(int x, int y)
00175 {
00176 int xpos = (x-scroll_x)<<3;
00177 int ypos = ((y-scroll_y)<<3)+TILEFIELD_TOP;
00178 draw_sprite_xor(black_square, xpos, ypos);
00179 }
00180
00181
00182 void xor_selected_range(void)
00183 {
00184 int top, bottom, left, right;
00185 int xi, yi;
00186
00187 if(cursor_x == select_x && cursor_y == select_y) {
00188 top = bottom = cursor_y;
00189 left = right = cursor_x;
00190 } else {
00191 get_selected_region(&top, &left, &right, &bottom);
00192 }
00193
00194 if(top < scroll_y) top = scroll_y;
00195 if(left < scroll_x) left = scroll_x;
00196 if(bottom >= scroll_y + VIEWPORT_HEIGHT)
00197 bottom = scroll_y + VIEWPORT_HEIGHT - 1;
00198 if(right >= scroll_x + VIEWPORT_WIDTH)
00199 bottom = scroll_x + VIEWPORT_WIDTH - 1;
00200
00201 for(yi=top; yi<=bottom; yi++)
00202 for(xi=left; xi<=right; xi++)
00203 {
00204 xor_tile(xi, yi);
00205 }
00206 }
00207
00208
00209 void draw_editor_brush(void)
00210 {
00211 draw_sprite(tile_sprites[ edit_brush ], 0, 0);
00212 }
00213
00214
00215 void draw_level_number(void)
00216 {
00217 char buf[32];
00218 sprintf(buf, "%i/%i", current_map_num+1, num_maps);
00219 clear_rect(130, 0, 20, 9);
00220 draw_string(buf, 130, 2);
00221 }
00222
00223
00224
00225 void place_tile(int x, int y, int brush)
00226 {
00227 int xi, yi;
00228 if(current_map->t[y][x])
00229 current_map->t[y][x] = TILE_EMPTY;
00230 else
00231 {
00232 if(brush==TILE_KYE)
00233
00234 {
00235 for(yi=0; yi<FIELD_HEIGHT; yi++)
00236 for(xi=0; xi<FIELD_WIDTH; xi++)
00237 if(current_map->t[yi][xi] == TILE_KYE)
00238 {
00239 current_map->t[yi][xi] = TILE_EMPTY;
00240 draw_map_tile(xi, yi);
00241 }
00242 }
00243 current_map->t[y][x] = brush;
00244 }
00245 draw_map_tile(x, y);
00246 }
00247
00248
00249 void editing_state(int key)
00250 {
00251 if(key == KEY_LEFT) move_cursor(-1, 0, 0);
00252 else if(key == KEY_UP) move_cursor(0, -1, 0);
00253 else if(key == KEY_RIGHT) move_cursor(1, 0, 0);
00254 else if(key == KEY_DOWN) move_cursor(0, 1, 0);
00255 else if(key == (KEY_SHIFT|KEY_LEFT)) move_cursor(-1, 0, 1);
00256 else if(key == (KEY_SHIFT|KEY_UP)) move_cursor(0, -1, 1);
00257 else if(key == (KEY_SHIFT|KEY_RIGHT)) move_cursor(1, 0, 1);
00258 else if(key == (KEY_SHIFT|KEY_DOWN)) move_cursor(0, 1, 1);
00259 else if(key == (KEY_DIAMOND|KEY_UP)) map_move_up();
00260 else if(key == (KEY_DIAMOND|KEY_DOWN)) map_move_down();
00261 else switch(key)
00262 {
00263 case KEY_ENTER:
00264 place_tile(cursor_x, cursor_y, edit_brush);
00265 break;
00266 case KEY_STO:
00267 if(current_map->t[cursor_y][cursor_x])
00268 edit_brush = current_map->t[cursor_y][cursor_x];
00269 else
00270 edit_brush = TILE_WALL_5;
00271 draw_editor_brush();
00272 break;
00273 case KEY_F1:
00274 enter_palette_state();
00275 break;
00276 case KEY_F2: enter_menu_state(0); break;
00277 case KEY_F3: enter_menu_state(1); break;
00278 case KEY_F4: enter_menu_state(2); break;
00279 case KEY_F5: enter_menu_state(3); break;
00280 case KEY_ESC:
00281 exit(0);
00282 break;
00283
00284 case '+': map_next(); break;
00285 case '-': map_previous(); break;
00286 case 'X': edit_cut(); draw_current_map(); break;
00287 case 'Y': edit_copy(); draw_current_map(); break;
00288 case '=': edit_paste(); draw_current_map(); break;
00289 case 'A': edit_select_all(); draw_current_map(); break;
00290 case 'N': file_new(); draw_current_map(); break;
00291 case 'O': file_open(); draw_current_map(); break;
00292 case 'S': file_save(); draw_current_map(); break;
00293 case KEY_MODE:
00294 map_properties(); break;
00295 case 'H': transform_mirror_horizontal(); draw_current_map(); break;
00296 case 'V': transform_mirror_vertical(); draw_current_map(); break;
00297 case 'R': transform_rotate_180(); draw_current_map(); break;
00298 case 'C': transform_smooth(); draw_current_map(); break;
00299 }
00300 }
00301
00302
00303 void move_cursor(int dx, int dy, int shifted)
00304 {
00305 int new_x = cursor_x + dx;
00306 int new_y = cursor_y + dy;
00307 int redraw = 0;
00308 if(new_x<0 || new_y<0 || new_x>=FIELD_WIDTH || new_y>=FIELD_HEIGHT)
00309 return;
00310
00311 if(new_x < scroll_x) {
00312 scroll_x = max(scroll_x-SCROLL_INCR_X, 0);
00313 redraw = 1;
00314 }
00315 if(new_y < scroll_y) {
00316 scroll_y = max(scroll_y-SCROLL_INCR_Y, 0);
00317 redraw = 1;
00318 }
00319 if(new_x >= scroll_x+VIEWPORT_WIDTH) {
00320 scroll_x = min(scroll_x+SCROLL_INCR_X, FIELD_WIDTH-VIEWPORT_WIDTH);
00321 redraw = 1;
00322 }
00323 if(new_y >= scroll_y+VIEWPORT_HEIGHT) {
00324 scroll_y = min(scroll_y+SCROLL_INCR_Y, FIELD_HEIGHT-VIEWPORT_HEIGHT);
00325 redraw = 1;
00326 }
00327
00328 if(shifted) {
00329 if(!redraw)
00330 xor_selected_range();
00331 cursor_x = new_x;
00332 cursor_y = new_y;
00333 if(!redraw)
00334 xor_selected_range();
00335 } else {
00336 if(!redraw)
00337 xor_selected_range();
00338 select_x = new_x;
00339 select_y = new_y;
00340 cursor_x = new_x;
00341 cursor_y = new_y;
00342 if(!redraw)
00343 xor_selected_range();
00344 }
00345
00346 if(redraw) {
00347 draw_map_field();
00348 }
00349 }
00350
00351
00352