Main Page | Alphabetical List | Class List | File List | Class Members | File Members

editor/editor.c

Go to the documentation of this file.
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     // Pool allocation of all the rows together
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++) { // Removed maps
00063         cleanup_map(&maps[ii]);
00064     }
00065     maps = (editor_map*)realloc_throw(maps, sizeof(*maps)*n);
00066     for(ii=num_maps; ii<n; ii++) { // Added maps
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     // If the field is *smaller*, then it needs a border around it
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) // Off-screen tile
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) // Make sure there's only one Kye on the map
00233                             // at a time
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         // Shortcuts for things also available from menus
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) // Don't do a partial-redraw if about to redraw everything
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 

Generated on Thu Apr 22 14:06:32 2004 for SKye by doxygen 1.3.6