1 /***************************************************************************
4 begin : Fri Oct 12 2001
5 copyright : (C) 2001 by Michael Speck
6 email : kulkanie@gmx.net
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
18 #include "lbreakout.h"
19 #include "../game/game.h"
26 SDL_Surface
*sel_frame
= 0, *buttons
= 0;
27 SDL_Surface
*editor_bkgnd
= 0; /* background (black with frame) of editor */
28 char edit_file_name
[512]; /* full path of edited file */
29 Level
*edit_levels
[MAX_LEVELS
]; /* editor levels */
30 char edit_version
[16]; /* version of edited set */
31 int edit_level_count
; /* how many levels currently used? */
32 int edit_cur_level_id
;
33 Level
*edit_cur_level
; /* current level modified */
34 enum { EDITOR_BRICK
, EDITOR_EXTRA
};
35 int edit_sel_type
; /* type of selected tile */
36 int edit_sel_id
; /* brick or extra id */
37 int edit_sel_x
, edit_sel_y
; /* position in map of selected tile */
38 int edit_tile_x
= 1, edit_tile_y
= 20, edit_tile_w
= MAP_WIDTH
- 2, edit_tile_h
= 3; /* part where either bricks ro bonuses
40 int extra_vis
; /* extras currently shown? blinks. */
41 int first_swap_level
= -1; /* if not -1 this and the current level will be swapped
42 next time the button is pressed */
47 BUTTON_LAST_BRICK
= BUTTON_FIRST_BRICK
+ ( BRICK_COUNT_REGULAR
),
49 BUTTON_LAST_EXTRA
= BUTTON_FIRST_EXTRA
+ ( EX_NUMBER
-1 ),
67 int edit_buttons
[MAP_WIDTH
][MAP_HEIGHT
]; /* an action is assigned to each map tile */
69 extern SDL_Surface
*stk_display
;
70 extern SDL_Surface
*frame
;
71 extern SDL_Surface
*extra_pic
;
72 extern SDL_Surface
*brick_pic
;
73 extern StkFont
*mfont
; /* use menu's font to draw status */
74 extern StkFont
*font
; /* use game's font to confirm */
76 extern int stk_quit_request
;
78 /* extra conversion table may be found in bricks.c */
79 extern Extra_Conv extra_conv_table
[EX_NUMBER
];
80 extern Brick_Conv brick_conv_table
[BRICK_COUNT
];
83 ====================================================================
85 ====================================================================
89 ====================================================================
90 We had a right click into the tile region so check and change the
91 bricks displayed there. We select the first new tile and set
92 edit_sel_id, edit_sel_x, edit_sel_y. The full update is initated
93 by editor_handle_click().
94 ====================================================================
96 void editor_switch_tiles()
98 int x_off
= 2, y_off
= 20, len
= MAP_WIDTH
- x_off
* 2; /* offset in map of tiles, len is the number of tiles in one line */
100 /* clear edit buttons */
101 for ( i
= edit_tile_x
; i
< edit_tile_x
+ edit_tile_w
; i
++ )
102 for ( j
= edit_tile_y
; j
< edit_tile_y
+ edit_tile_h
; j
++ )
103 edit_buttons
[i
][j
] = BUTTON_NONE
;
104 /* clear this part of the editor bkjgnd */
105 stk_surface_fill( editor_bkgnd
,
106 edit_tile_x
* BRICK_WIDTH
, edit_tile_y
* BRICK_HEIGHT
,
107 edit_tile_w
* BRICK_WIDTH
, edit_tile_h
* BRICK_HEIGHT
, 0x0 );
109 if ( edit_sel_type
== EDITOR_BRICK
) {
111 edit_sel_type
= EDITOR_EXTRA
;
112 /* button map & background */
114 while ( i
+ j
* len
< EX_NUMBER
) {
115 edit_buttons
[x_off
+ i
][y_off
+ j
] = BUTTON_FIRST_EXTRA
+ i
+ j
* len
;
116 stk_surface_blit( extra_pic
, ( i
+ j
* len
) * BRICK_WIDTH
, 0,
117 BRICK_WIDTH
, BRICK_HEIGHT
,
118 editor_bkgnd
, ( i
+ x_off
) * BRICK_WIDTH
, ( j
+ y_off
) * BRICK_HEIGHT
);
125 /* select first tile */
132 edit_sel_type
= EDITOR_BRICK
;
133 /* button map & background */
135 while ( i
+ j
* len
< BRICK_COUNT_REGULAR
) {
136 edit_buttons
[x_off
+ i
][y_off
+ j
] = BUTTON_FIRST_BRICK
+ i
+ j
* len
;
137 stk_surface_blit( brick_pic
, ( i
+ j
* len
) * BRICK_WIDTH
, 0,
138 BRICK_WIDTH
, BRICK_HEIGHT
,
139 editor_bkgnd
, ( i
+ x_off
) * BRICK_WIDTH
, ( j
+ y_off
) * BRICK_HEIGHT
);
146 /* select first tile */
154 ====================================================================
156 ====================================================================
158 void editor_draw_grid()
162 buffer
= stk_surface_create( SDL_SWSURFACE
, EDIT_WIDTH
* BRICK_WIDTH
, 1 );
163 stk_surface_fill( buffer
, 0,0,-1,-1, 0xffffff );
164 stk_surface_blit( buffer
, 0,0,-1,-1, editor_bkgnd
, BRICK_WIDTH
, BRICK_HEIGHT
);
165 stk_surface_blit( buffer
, 0,0,-1,-1, editor_bkgnd
, BRICK_WIDTH
,
166 ( EDIT_HEIGHT
+ 1 ) * BRICK_HEIGHT
- 1 );
167 for ( i
= 0; i
< EDIT_HEIGHT
- 1; i
++ ) {
168 if ( i
== EDIT_HEIGHT
/ 2 - 1 )
171 if ( i
% (EDIT_HEIGHT
/4) == 0 )
175 stk_surface_alpha_blit( buffer
, 0,0,-1,-1, editor_bkgnd
,
176 BRICK_WIDTH
, ( i
+ 1 ) * BRICK_HEIGHT
+ BRICK_HEIGHT
- 1,
179 SDL_FreeSurface( buffer
);
180 buffer
= stk_surface_create( SDL_SWSURFACE
, 1, EDIT_HEIGHT
* BRICK_HEIGHT
);
181 stk_surface_fill( buffer
, 0,0,-1,-1, 0xffffff );
182 stk_surface_blit( buffer
, 0,0,-1,-1, editor_bkgnd
, BRICK_WIDTH
, BRICK_HEIGHT
);
183 stk_surface_blit( buffer
, 0,0,-1,-1, editor_bkgnd
,
184 ( EDIT_WIDTH
+ 1 ) * BRICK_WIDTH
- 1, BRICK_HEIGHT
);
185 for ( i
= 0; i
< EDIT_WIDTH
- 1; i
++ ) {
186 if ( i
== EDIT_WIDTH
/ 2 - 1 )
189 if ( i
% (EDIT_WIDTH
/4) == 0 )
193 stk_surface_alpha_blit( buffer
, 0,0,-1,-1, editor_bkgnd
,
194 ( i
+ 1 ) * BRICK_WIDTH
+ BRICK_WIDTH
- 1, BRICK_HEIGHT
,
197 SDL_FreeSurface( buffer
);
201 ====================================================================
202 Translate the saved character strings into extra and brick indices
204 ====================================================================
206 enum { INDICES_2_CHAR
, CHAR_2_INDICES
};
207 void editor_translate_level( Level
*level
, int type
)
210 if ( type
== CHAR_2_INDICES
) {
211 for ( i
= 0; i
< EDIT_WIDTH
; i
++ )
212 for ( j
= 0; j
< EDIT_HEIGHT
; j
++ ) {
214 for ( k
= 0; k
< BRICK_COUNT
; k
++ )
215 if ( brick_conv_table
[k
].c
== level
->bricks
[i
][j
] ) {
216 level
->bricks
[i
][j
] = brick_conv_table
[k
].id
;
219 if ( k
== BRICK_COUNT
) level
->bricks
[i
][j
] = -1;
221 for ( k
= 0; k
< EX_NUMBER
; k
++ )
222 if ( extra_conv_table
[k
].c
== level
->extras
[i
][j
] ) {
223 level
->extras
[i
][j
] = extra_conv_table
[k
].type
;
226 if ( k
== EX_NUMBER
) level
->extras
[i
][j
] = EX_NONE
;
230 /* indices to characters */
231 for ( i
= 0; i
< EDIT_WIDTH
; i
++ )
232 for ( j
= 0; j
< EDIT_HEIGHT
; j
++ ) {
234 if ( level
->bricks
[i
][j
] == -1 )
235 level
->bricks
[i
][j
] = '.';
237 for ( k
= 0; k
< BRICK_COUNT
; k
++ )
238 if ( level
->bricks
[i
][j
] == brick_conv_table
[k
].id
) {
239 level
->bricks
[i
][j
] = brick_conv_table
[k
].c
;
243 if ( level
->extras
[i
][j
] == EX_NONE
)
244 level
->extras
[i
][j
] = '.';
246 for ( k
= 0; k
< EX_NUMBER
; k
++ )
247 if ( level
->extras
[i
][j
] == extra_conv_table
[k
].type
) {
248 level
->extras
[i
][j
] = extra_conv_table
[k
].c
;
255 ====================================================================
256 Draw name of set file, current level, current count, remaining
257 levels, and other info stuff.
258 ====================================================================
260 void editor_draw_status()
263 int x
= BRICK_WIDTH
, y
= ( MAP_HEIGHT
- 1 ) * BRICK_HEIGHT
- 2;
266 sprintf( str
, _("Location: %s"), edit_file_name
);
267 mfont
->align
= STK_FONT_ALIGN_LEFT
| STK_FONT_ALIGN_TOP
;
268 stk_font_write( mfont
, stk_display
, x
, y
, STK_OPAQUE
, str
);
270 sprintf( str
, _("Current Level: %i/%i (Free: %i)"), edit_cur_level_id
+ 1, edit_level_count
, MAX_LEVELS
- edit_level_count
);
271 mfont
->align
= STK_FONT_ALIGN_LEFT
| STK_FONT_ALIGN_TOP
;
272 stk_font_write( mfont
, stk_display
, x
, y
+ height
, STK_OPAQUE
, str
);
274 mfont
->align
= STK_FONT_ALIGN_RIGHT
| STK_FONT_ALIGN_TOP
;
275 if ( first_swap_level
!= -1 ) {
276 sprintf( str
, _("*** Level %i Marked For Swap ***"), first_swap_level
+ 1 );
277 stk_font_write( mfont
, stk_display
, stk_display
->w
- BRICK_WIDTH
, y
+ height
, STK_OPAQUE
, str
);
281 sprintf( str
, _("Version: %s "), edit_version
);
282 stk_font_write( mfont
, stk_display
, stk_display
->w
- BRICK_WIDTH
, y
+ height
, STK_OPAQUE
, str
);
284 /* name and author */
285 mfont
->align
= STK_FONT_ALIGN_LEFT
| STK_FONT_ALIGN_TOP
;
286 sprintf( str
, _("Title: %s"), edit_cur_level
->name
);
287 stk_font_write( mfont
, stk_display
, BRICK_WIDTH
+ 2, ( MAP_HEIGHT
- 5 ) * BRICK_HEIGHT
+ 5, STK_OPAQUE
, str
);
288 mfont
->align
= STK_FONT_ALIGN_RIGHT
| STK_FONT_ALIGN_TOP
;
289 sprintf( str
, _("Author: %s"), edit_cur_level
->author
);
290 stk_font_write( mfont
, stk_display
, stk_display
->w
- BRICK_WIDTH
- 2, ( MAP_HEIGHT
- 5 ) * BRICK_HEIGHT
+ 5, STK_OPAQUE
, str
);
293 ====================================================================
294 Draw brick and extra (if any) from screen map pos
295 so it fits the editable field (no frame, no bottom).
296 ====================================================================
298 void editor_draw_brick( int edit_map_x
, int edit_map_y
)
301 if ( edit_cur_level
->bricks
[edit_map_x
][edit_map_y
] != -1 ) {
302 if ( edit_cur_level
->bricks
[edit_map_x
][edit_map_y
] != INVIS_BRICK_ID
)
303 stk_surface_blit( brick_pic
,
304 edit_cur_level
->bricks
[edit_map_x
][edit_map_y
] * BRICK_WIDTH
, 0,
305 BRICK_WIDTH
, BRICK_HEIGHT
,
306 stk_display
, (edit_map_x
+ 1) * BRICK_WIDTH
, (edit_map_y
+ 1) * BRICK_HEIGHT
);
308 stk_surface_fill( stk_display
,
309 (edit_map_x
+ 1) * BRICK_WIDTH
, (edit_map_y
+ 1) * BRICK_HEIGHT
,
310 BRICK_WIDTH
, BRICK_HEIGHT
, 0x777777 );
313 stk_surface_blit( editor_bkgnd
,
314 (edit_map_x
+ 1) * BRICK_WIDTH
, (edit_map_y
+ 1) * BRICK_HEIGHT
,
315 BRICK_WIDTH
, BRICK_HEIGHT
, stk_display
,
316 (edit_map_x
+ 1) * BRICK_WIDTH
, (edit_map_y
+ 1) * BRICK_HEIGHT
);
319 if ( ( extra_vis
|| edit_sel_type
== EDITOR_EXTRA
) && edit_cur_level
->extras
[edit_map_x
][edit_map_y
] != EX_NONE
) {
320 stk_surface_blit( extra_pic
,
321 ( edit_cur_level
->extras
[edit_map_x
][edit_map_y
] ) * BRICK_WIDTH
, 0,
322 BRICK_WIDTH
, BRICK_HEIGHT
,
323 stk_display
, (edit_map_x
+ 1) * BRICK_WIDTH
, (edit_map_y
+ 1) * BRICK_HEIGHT
);
325 stk_display_store_drect();
328 ====================================================================
329 Redraw and refresh full screen
330 ====================================================================
332 void editor_full_update()
336 stk_surface_blit( editor_bkgnd
, 0,0,-1,-1, stk_display
, 0,0 );
338 for ( i
= 0; i
< EDIT_WIDTH
; i
++ )
339 for ( j
= 0; j
< EDIT_HEIGHT
; j
++ )
340 editor_draw_brick( i
, j
);
341 /* selection frame */
342 stk_surface_blit( sel_frame
, 0,0,-1,-1,
343 stk_display
, edit_sel_x
* BRICK_WIDTH
, edit_sel_y
* BRICK_HEIGHT
);
345 editor_draw_status();
347 stk_display_update( STK_UPDATE_ALL
);
350 ====================================================================
351 Do only redraw and refresh those bricks with an extra
352 ====================================================================
354 void editor_update_extra_bricks()
357 for ( i
= 0; i
< EDIT_WIDTH
; i
++ )
358 for ( j
= 0; j
< EDIT_HEIGHT
; j
++ )
359 if ( edit_cur_level
->extras
[i
][j
] != EX_NONE
)
360 editor_draw_brick( i
, j
);
361 stk_display_update( STK_UPDATE_RECTS
);
364 ====================================================================
365 Free all editor levels
366 ====================================================================
368 void editor_clear_levels()
371 for ( i
= 0; i
< MAX_LEVELS
; i
++ )
372 if ( edit_levels
[i
] ) level_delete( edit_levels
[i
] );
373 memset( edit_levels
, 0, sizeof( Level
* ) * MAX_LEVELS
);
374 edit_level_count
= 0;
377 ====================================================================
378 Save/load levels to/from editor file.
379 ====================================================================
381 void editor_load_levels()
383 int i
, version
, update
;
386 /* clear levels first */
387 editor_clear_levels();
388 /* read levels while there are some in it */
389 edit_level_count
= 0;
390 if ( ( file
= fopen( edit_file_name
, "rb" ) ) != 0 ) {
391 levelset_get_version( file
, &version
, &update
);
392 sprintf( edit_version
, "%i.%02i", version
, update
);
393 while ( ( level
= level_load( file
) ) != 0 )
394 edit_levels
[edit_level_count
++] = level
;
397 /* if we got no level at all create an empty one */
398 if ( edit_level_count
== 0 ) {
399 edit_level_count
= 1;
400 edit_levels
[0] = level_create_empty( _("noname"), _("untitled") );
402 /* translate the character strings to editor info */
403 for ( i
= 0; i
< edit_level_count
; i
++ )
404 editor_translate_level( edit_levels
[i
], CHAR_2_INDICES
);
406 void editor_save_levels()
412 for ( i
= 0; i
< edit_level_count
; i
++ )
413 editor_translate_level( edit_levels
[i
], INDICES_2_CHAR
);
415 if ( ( file
= fopen( edit_file_name
, "w" ) ) != 0 ) {
416 fprintf( file
, "Version: %s\n", edit_version
);
417 for ( i
= 0; i
< edit_level_count
; i
++ ) {
418 level
= edit_levels
[i
];
420 fprintf( file
, "Level:\n%s\n%s\nBricks:\n", level
->author
, level
->name
);
421 for ( j
= 0; j
< EDIT_HEIGHT
; j
++ ) {
422 for ( k
= 0; k
< EDIT_WIDTH
; k
++ )
423 fprintf( file
, "%c", level
->bricks
[k
][j
] );
424 fprintf( file
, "\n" );
426 fprintf( file
, "Bonus:\n" );
427 for ( j
= 0; j
< EDIT_HEIGHT
; j
++ ) {
428 for ( k
= 0; k
< EDIT_WIDTH
; k
++ )
429 fprintf( file
, "%c", level
->extras
[k
][j
] );
430 fprintf( file
, "\n" );
436 for ( i
= 0; i
< edit_level_count
; i
++ )
437 editor_translate_level( edit_levels
[i
], CHAR_2_INDICES
);
440 ====================================================================
442 ====================================================================
444 void editor_handle_button( int type
, int *full_update
) {
452 edit_cur_level_id
= 0;
453 edit_cur_level
= edit_levels
[0];
458 if ( edit_cur_level_id
== edit_level_count
) edit_cur_level_id
= 0;
459 edit_cur_level
= edit_levels
[edit_cur_level_id
];
464 if ( edit_cur_level_id
== -1 ) edit_cur_level_id
= edit_level_count
- 1;
465 edit_cur_level
= edit_levels
[edit_cur_level_id
];
469 if ( first_swap_level
== -1 ) {
470 first_swap_level
= edit_cur_level_id
;
474 /* swap current and marked level */
475 dummy_ptr
= edit_levels
[first_swap_level
];
476 edit_levels
[first_swap_level
] = edit_levels
[edit_cur_level_id
];
477 edit_levels
[edit_cur_level_id
] = dummy_ptr
;
478 edit_cur_level
= edit_levels
[edit_cur_level_id
];
479 first_swap_level
= -1;
484 if ( !confirm( font
, _("Discard All Changes? y/n"), CONFIRM_YES_NO
) ) break;
485 /* load levels and reset position if level doesn't exist */
486 old_pos
= edit_cur_level_id
;
487 editor_load_levels();
488 if ( old_pos
>= edit_level_count
) edit_cur_level_id
= 0;
489 edit_cur_level
= edit_levels
[edit_cur_level_id
];
490 first_swap_level
= -1;
494 if ( !confirm( font
, _("Save Changes? y/n"), CONFIRM_YES_NO
) ) break;
495 editor_save_levels();
498 if ( !confirm( font
, _("Clear Level? y/n"), CONFIRM_YES_NO
) ) break;
499 author
= strdup( edit_cur_level
->author
);
500 name
= strdup( edit_cur_level
->name
);
501 level_delete( edit_levels
[edit_cur_level_id
] );
502 edit_levels
[edit_cur_level_id
] = level_create_empty( author
, name
);
503 edit_cur_level
= edit_levels
[edit_cur_level_id
];
504 free( name
); free( author
);
508 if ( edit_level_count
== MAX_LEVELS
) break;
509 if ( !confirm( font
, _("Add Level? y/n"), CONFIRM_YES_NO
) ) break;
510 edit_levels
[edit_level_count
] = level_create_empty( edit_levels
[edit_level_count
- 1]->author
, edit_levels
[edit_level_count
- 1]->name
);
515 if ( edit_level_count
== MAX_LEVELS
) break;
516 if ( !confirm( font
, _("Insert Level? y/n"), CONFIRM_YES_NO
) ) break;
517 for ( i
= edit_level_count
; i
> edit_cur_level_id
; i
-- )
518 edit_levels
[i
] = edit_levels
[i
- 1];
520 edit_levels
[edit_cur_level_id
] = level_create_empty( edit_cur_level
->author
, edit_cur_level
->name
);
521 edit_cur_level
= edit_levels
[edit_cur_level_id
];
525 if ( edit_level_count
== 1 ) break; /* last level may not be removed */
526 if ( !confirm( font
, _("Delete Level? y/n"), CONFIRM_YES_NO
) ) break;
527 level_delete( edit_levels
[edit_cur_level_id
] );
528 for ( i
= edit_cur_level_id
; i
< edit_level_count
- 1; i
++ )
529 edit_levels
[i
] = edit_levels
[i
+ 1];
532 if ( edit_cur_level_id
>= edit_level_count
)
533 edit_cur_level_id
= edit_level_count
- 1;
534 edit_cur_level
= edit_levels
[edit_cur_level_id
];
538 stk_display_fade( STK_FADE_OUT
, STK_FADE_DEFAULT_TIME
);
540 editor_translate_level( edit_cur_level
, INDICES_2_CHAR
);
542 client_game_test_level( edit_cur_level
);
544 editor_translate_level( edit_cur_level
, CHAR_2_INDICES
);
548 if ( enter_string( font
, _("Levelset Version:"), edit_version
, 8 ) ) {
549 parse_version( edit_version
, &version
, &update
);
550 sprintf( edit_version
, "%i.%02i", version
, update
);
557 ====================================================================
558 Handle a click on a map tile.
559 If set is False a remove action was requested (only for
561 ====================================================================
563 int near_grow_brick( int x
, int y
) {
565 for ( i
= x
- 1; i
<= x
+ 1; i
++ )
566 for ( j
= y
- 1; j
<= y
+ 1; j
++ )
567 if ( i
!= x
|| j
!= y
)
568 if ( i
>= 0 && j
>= 0 && i
< EDIT_WIDTH
&& j
< EDIT_HEIGHT
)
569 if ( edit_cur_level
->bricks
[i
][j
] == GROW_BRICK_ID
)
573 void editor_handle_click( int x
, int y
, int set
, int *full_update
)
578 /* if !set and within the tile field we perform a switch */
580 if ( x
>= edit_tile_x
&& y
>= edit_tile_y
&& x
< edit_tile_x
+ edit_tile_w
&& y
< edit_tile_y
+ edit_tile_h
) {
581 editor_switch_tiles();
586 /* the remaining stuff requires a tile at the position */
587 if ( edit_buttons
[x
][y
] == BUTTON_NONE
) return; /* no action */
589 if ( edit_buttons
[x
][y
] >= BUTTON_FIRST_BRICK
&& edit_buttons
[x
][y
] <= BUTTON_LAST_BRICK
) {
591 edit_sel_type
= EDITOR_BRICK
;
592 edit_sel_id
= edit_buttons
[x
][y
] - BUTTON_FIRST_BRICK
;
595 if ( edit_buttons
[x
][y
] >= BUTTON_FIRST_EXTRA
&& edit_buttons
[x
][y
] <= BUTTON_LAST_EXTRA
) {
597 edit_sel_type
= EDITOR_EXTRA
;
598 edit_sel_id
= edit_buttons
[x
][y
] - BUTTON_FIRST_EXTRA
;
601 if ( edit_buttons
[x
][y
] == BUTTON_EDIT
) {
604 if ( edit_sel_type
== EDITOR_BRICK
) {
607 edit_cur_level
->bricks
[edit_x
][edit_y
] = edit_sel_id
;
611 /* remove brick and extra if any */
612 if ( edit_cur_level
->bricks
[edit_x
][edit_y
] != -1 ) {
613 edit_cur_level
->bricks
[edit_x
][edit_y
] = -1;
614 edit_cur_level
->extras
[edit_x
][edit_y
] = EX_NONE
;
621 /* set extra - must be on a brick or beside a grow brick */
622 if ( edit_cur_level
->bricks
[edit_x
][edit_y
] != -1 || near_grow_brick( edit_x
, edit_y
) ) {
623 edit_cur_level
->extras
[edit_x
][edit_y
] = edit_sel_id
;
629 if ( edit_cur_level
->extras
[edit_x
][edit_y
] != EX_NONE
) {
630 edit_cur_level
->extras
[edit_x
][edit_y
] = EX_NONE
;
637 editor_handle_button( edit_buttons
[x
][y
], full_update
);
640 if ( edit_buttons
[x
][y
] == BUTTON_EDIT_AUTHOR
)
641 if ( enter_string( font
, _("Author's Name:"), str
, 24 ) ) {
642 snprintf( edit_cur_level
->author
, 31, "%s", str
);
645 if ( edit_buttons
[x
][y
] == BUTTON_EDIT_NAME
)
646 if ( enter_string( font
, _("Title:"), str
, 24 ) ) {
647 snprintf( edit_cur_level
->name
, 31, "%s", str
);
650 /* sel frame tile position */
659 ====================================================================
661 ====================================================================
664 ====================================================================
665 Create/delete editor resources
666 ====================================================================
671 /* clear all level pointers */
672 memset( edit_levels
, 0, sizeof( Level
* ) * MAX_LEVELS
);
674 sel_frame
= stk_surface_load( SDL_SWSURFACE
, "sel_frame.png" );
676 buttons
= stk_surface_load( SDL_SWSURFACE
, "buttons.png" );
677 /* background is black + frame */
678 editor_bkgnd
= stk_surface_create( SDL_SWSURFACE
, stk_display
->w
, stk_display
->h
);
679 SDL_SetColorKey( editor_bkgnd
, 0, 0 );
680 stk_surface_fill( editor_bkgnd
, 0,0,-1,-1, 0x0 );
681 /* add helping grid */
685 for ( i
= 0; i
< EDIT_WIDTH
; i
++ )
686 for ( j
= 0; j
< EDIT_HEIGHT
; j
++ )
687 edit_buttons
[i
+ 1][j
+ 1] = BUTTON_EDIT
;
689 for ( i
= 0; i
< 11; i
++ )
690 edit_buttons
[0][MAP_HEIGHT
- 11 + i
] = BUTTON_FIRST
+ i
;
691 edit_buttons
[MAP_WIDTH
- 1][MAP_HEIGHT
- 1] = BUTTON_PLAY
;
693 for ( i
= 1; i
< MAP_WIDTH
/ 2; i
++ )
694 edit_buttons
[i
][MAP_HEIGHT
- 5] = BUTTON_EDIT_NAME
;
695 for ( i
= MAP_WIDTH
/ 2; i
< MAP_WIDTH
- 1; i
++ )
696 edit_buttons
[i
][MAP_HEIGHT
- 5] = BUTTON_EDIT_AUTHOR
;
698 for ( i
= 0; i
< 11; i
++ ) {
699 stk_surface_blit( buttons
, i
* BRICK_WIDTH
, 0,
700 BRICK_WIDTH
, BRICK_HEIGHT
,
701 editor_bkgnd
, 0, ( MAP_HEIGHT
- 11 + i
) * BRICK_HEIGHT
);
703 stk_surface_blit( buttons
, 11 * BRICK_WIDTH
, 0,
704 BRICK_WIDTH
, BRICK_HEIGHT
,
706 ( MAP_WIDTH
- 1 ) * BRICK_WIDTH
,
707 ( MAP_HEIGHT
- 1 ) * BRICK_HEIGHT
);
711 stk_surface_free( &editor_bkgnd
);
712 stk_surface_free( &sel_frame
);
713 stk_surface_free( &buttons
);
716 ====================================================================
717 Initiate and clear stuff for each editor call.
718 file_name is the name of the edited file in home directory.
719 ====================================================================
721 int editor_init( char *file_name
)
724 /* set full file name */
725 snprintf( edit_file_name
, sizeof(edit_file_name
)-1, "%s/%s/lbreakout2-levels/%s", (getenv( "HOME" )?getenv( "HOME" ):"."), CONFIG_DIR_NAME
, file_name
);
726 /* test this file for write access. use append to keep contents */
727 if ( ( file
= fopen( edit_file_name
, "a" ) ) == 0 ) {
728 fprintf( stderr
, "Permission to write to file '%s' denied.\n", edit_file_name
);
734 editor_load_levels();
735 /* select first level */
736 edit_cur_level_id
= 0;
737 edit_cur_level
= edit_levels
[0];
738 /* select first brick */
739 edit_sel_type
= EDITOR_EXTRA
;
740 editor_switch_tiles();
741 /* clear other flags */
743 first_swap_level
= -1;
748 /* free all levels */
749 editor_clear_levels();
752 ====================================================================
754 ====================================================================
761 int last_switch_time
= 0;
762 int full_update
= 0, set
;
766 /* reset any alpha keys */
767 SDL_SetAlpha( extra_pic
, 0,0 );
768 /* draw first time */
769 editor_full_update();
772 while ( !leave
&& !stk_quit_request
) {
773 if ( SDL_PollEvent( &event
) ) {
774 switch ( event
.type
) {
775 case SDL_QUIT
: leave
= 1; stk_quit_request
= 1; break;
776 case SDL_MOUSEBUTTONDOWN
:
777 editor_handle_click( event
.button
.x
/ BRICK_WIDTH
,
778 event
.button
.y
/ BRICK_HEIGHT
,
779 (event
.button
.button
== STK_BUTTON_LEFT
),
783 switch ( event
.key
.keysym
.sym
) {
785 if ( confirm( font
, _("Quit Editor? y/n"), CONFIRM_YES_NO
) ) leave
= 1;
787 case SDLK_LEFT
: editor_handle_button( BUTTON_PREV
, &full_update
); break;
788 case SDLK_RIGHT
: editor_handle_button( BUTTON_NEXT
, &full_update
); break;
789 case SDLK_UP
: editor_handle_button( BUTTON_FIRST
, &full_update
); break;
791 config
.fullscreen
= !config
.fullscreen
;
792 stk_display_apply_fullscreen( config
.fullscreen
);
801 /* mouse motion is handled directly */
802 buttonstate
= SDL_GetRelativeMouseState( &xoff
, &yoff
);
803 if ( (xoff
|| yoff
) && buttonstate
) {
804 buttonstate
= SDL_GetMouseState( &x
, &y
);
805 set
= 0; if ( buttonstate
& SDL_BUTTON(1) ) set
= 1;
806 editor_handle_click( x
/ BRICK_WIDTH
, y
/ BRICK_HEIGHT
, set
, &full_update
);
808 ms
= stk_timer_get_time();
809 if ( ( last_switch_time
-= ms
) <= 0 ) {
810 extra_vis
= !extra_vis
;
811 last_switch_time
= 500;
812 editor_update_extra_bricks();
816 editor_full_update();
819 /* don't consume all CPU time */