diff options
Diffstat (limited to 'src/editor/editor.cpp')
| -rw-r--r-- | src/editor/editor.cpp | 161 |
1 files changed, 120 insertions, 41 deletions
diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp index c96f908..72ca4d2 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -2,6 +2,7 @@ #include "../game.h" #include "../game/object.h" +#include "properties.h" GAME_EDITOR* editor = 0; @@ -31,7 +32,7 @@ void editor_clear_gui_state_refs( GAME_EDITOR* e ) { e->gui.header_viewtype = 0; } -void editor_push_undo_action( GAME_EDITOR* e, const GAME_EDITOR::EDITOR_UNDO_ACTION& action ) { +void editor_push_undo_action( GAME_EDITOR* e, const EDITOR_UNDO_ACTION& action ) { if( !e ) return; @@ -265,11 +266,11 @@ void editor_undo_record_create_walls( GAME_EDITOR* e, I32 start_idx, I32 count ) if( count <= 0 ) return; - GAME_EDITOR::EDITOR_UNDO_ACTION action{}; + EDITOR_UNDO_ACTION action{}; action.type = EDITOR_UNDO_CREATE_WALLS; - action.start_idx = start_idx; + action.create.start_idx = start_idx; for( I32 i = 0; i < count; ++i ) - action.walls.push( map->walls[start_idx + i] ); + action.create.walls.push( map->walls[start_idx + i] ); editor_push_undo_action( e, action ); } @@ -282,10 +283,11 @@ void editor_undo_record_create_poly( GAME_EDITOR* e, I32 start_idx ) { if( start_idx < 0 || start_idx >= (I32)map->polygons.size ) return; - GAME_EDITOR::EDITOR_UNDO_ACTION action{}; - action.type = EDITOR_UNDO_CREATE_POLY; - action.start_idx = start_idx; - action.polys.push( map->polygons[start_idx] ); + EDITOR_UNDO_ACTION action{ + .type = EDITOR_UNDO_CREATE_POLY, + .create = { .start_idx = start_idx } + }; + action.create.polys.push( map->polygons[start_idx] ); editor_push_undo_action( e, action ); } @@ -298,10 +300,12 @@ void editor_undo_record_create_sprite( GAME_EDITOR* e, I32 start_idx ) { if( start_idx < 0 || start_idx >= (I32)map->sprites.size ) return; - GAME_EDITOR::EDITOR_UNDO_ACTION action{}; - action.type = EDITOR_UNDO_CREATE_SPRITES; - action.start_idx = start_idx; - action.sprites.push( map->sprites[start_idx] ); + EDITOR_UNDO_ACTION action = { + .type = EDITOR_UNDO_CREATE_SPRITES, + .create = { .start_idx = start_idx } + }; + + action.create.sprites.push( map->sprites[start_idx] ); editor_push_undo_action( e, action ); } @@ -314,18 +318,36 @@ void editor_undo_record_create_entity( GAME_EDITOR* e, I32 start_idx ) { if( start_idx < 0 || start_idx >= (I32)map->entities.size ) return; - GAME_EDITOR::EDITOR_UNDO_ACTION action{}; - action.type = EDITOR_UNDO_CREATE_ENTITIES; - action.start_idx = start_idx; - action.entities.push( map->entities[start_idx] ); + EDITOR_UNDO_ACTION action{ + .type = EDITOR_UNDO_CREATE_ENTITIES, + .create = { .start_idx = start_idx } + }; + action.create.entities.push( map->entities[start_idx] ); editor_push_undo_action( e, action ); } -static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_UNDO_ACTION& action ) { +// NOTE: +// this is a util func. +// individual components create records manually +void editor_undo_record_change_prop( GAME_EDITOR* e, FNV1A hash, void* oldv, void* newv, U32 size ) { if( !e || !e->map ) - return 0; + return; + + EDITOR_UNDO_ACTION rec{ .type = EDITOR_UNDO_EDITPROPS }; + for( auto e : e->gui.props->curselect ) { + EDITOR_UNDO_PROPS::CHANGES changes{}; + + changes.props.push( { hash, size, oldv, newv } ); + changes.obj = (EOBJECT*)e.obj; + rec.props.changes.push( changes ); + } + + e->undo_actions.push( rec ); +} + +U8 editor_apply_undo_action_reverse_create( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) { WORLD_MAP* map = e->map; U8 clear_props_select = 0; U8 clear_view_select = 0; @@ -333,13 +355,13 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_ switch( action.type ) { case EDITOR_UNDO_CREATE_WALLS: { - I32 count = (I32)action.walls.size; + I32 count = (I32)action.create.walls.size; for( I32 i = count - 1; i >= 0; --i ) { if( !map->walls.size ) break; - I32 expected = action.start_idx + i; - I32 idx = editor_find_wall_idx( map, action.walls[i], expected ); + I32 expected = action.create.start_idx + i; + I32 idx = editor_find_wall_idx( map, action.create.walls[i], expected ); if( idx < 0 ) idx = editor_clamp_valid_idx( expected, (I32)map->walls.size ); @@ -350,15 +372,15 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_ } } break; case EDITOR_UNDO_CREATE_POLY: { - I32 count = (I32)action.polys.size; + I32 count = (I32)action.create.polys.size; if( count <= 0 ) return 0; for( I32 i = count - 1; i >= 0; --i ) { if( !map->polygons.size ) break; - I32 expected = action.start_idx + i; - I32 idx = i < (I32)action.polys.size ? editor_find_poly_idx( map, action.polys[i], expected ) : -1; + I32 expected = action.create.start_idx + i; + I32 idx = i < (I32)action.create.polys.size ? editor_find_poly_idx( map, action.create.polys[i], expected ) : -1; if( idx < 0 ) idx = editor_clamp_valid_idx( expected, (I32)map->polygons.size ); @@ -369,13 +391,13 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_ } } break; case EDITOR_UNDO_CREATE_SPRITES: { - I32 count = (I32)action.sprites.size; + I32 count = (I32)action.create.sprites.size; for( I32 i = count - 1; i >= 0; --i ) { if( !map->sprites.size ) break; - I32 expected = action.start_idx + i; - I32 idx = editor_find_sprite_idx( map, action.sprites[i], expected ); + I32 expected = action.create.start_idx + i; + I32 idx = editor_find_sprite_idx( map, action.create.sprites[i], expected ); if( idx < 0 ) idx = editor_clamp_valid_idx( expected, (I32)map->sprites.size ); @@ -385,13 +407,13 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_ } } break; case EDITOR_UNDO_CREATE_ENTITIES: { - I32 count = (I32)action.entities.size; + I32 count = (I32)action.create.entities.size; for( I32 i = count - 1; i >= 0; --i ) { if( !map->entities.size ) break; - I32 expected = action.start_idx + i; - I32 idx = editor_find_entity_idx( map, action.entities[i], expected ); + I32 expected = action.create.start_idx + i; + I32 idx = editor_find_entity_idx( map, action.create.entities[i], expected ); if( idx < 0 ) idx = editor_clamp_valid_idx( expected, (I32)map->entities.size ); @@ -422,41 +444,88 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_ return 1; } -static U8 editor_apply_undo_action_forward( GAME_EDITOR* e, GAME_EDITOR::EDITOR_UNDO_ACTION& action ) { +U8 editor_apply_undo_action_reverse_props( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) { + EDITOR_UNDO_PROPS* c = &action.props; + + for( auto it : c->changes ) { + EOBJECT* obj = it.obj; + for( auto it2 : it.props ) { + EDITOR_PROP* p = eprop_from_hash( obj, it2.hash ); + if( !p ) { + dlog( "editor_apply_undo_action_reverse_props() : warn: prop not found %x\n", it2.hash ); + return 0; + } + + void* data = eprop_ptr( p ); + memcpy( data, it2.oldval.data, p->size ); + } + } + + return 1; +} + +U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) { if( !e || !e->map ) return 0; + if( action.type == EDITOR_UNDO_EDITPROPS ) + return editor_apply_undo_action_reverse_props( e, action ); + + return editor_apply_undo_action_reverse_create( e, action ); +} + +U8 editor_apply_undo_action_forward_props( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) { + EDITOR_UNDO_PROPS* c = &action.props; + + for( auto it : c->changes ) { + EOBJECT* obj = it.obj; + for( auto it2 : it.props ) { + EDITOR_PROP* p = eprop_from_hash( obj, it2.hash ); + if( !p ) { + dlog( "editor_apply_undo_action_forward_props() : warn: prop not found %x\n", it2.hash ); + return 0; + } + + void* data = eprop_ptr( p ); + memcpy( data, it2.newval.data, p->size ); + } + } + + return 1; +} + +U8 editor_apply_undo_action_forward_create( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) { WORLD_MAP* map = e->map; switch( action.type ) { case EDITOR_UNDO_CREATE_WALLS: { - if( !action.walls.size ) + if( !action.create.walls.size ) return 0; - action.walls.each( fn( MAP_WALL* w ) { + action.create.walls.each( fn( MAP_WALL* w ) { map->walls.push( *w ); } ); } break; case EDITOR_UNDO_CREATE_POLY: { - if( !action.polys.size ) + if( !action.create.polys.size ) return 0; - action.polys.each( fn( MAP_POLYGON* p ) { + action.create.polys.each( fn( MAP_POLYGON* p ) { map->polygons.push( *p ); } ); } break; case EDITOR_UNDO_CREATE_SPRITES: { - if( !action.sprites.size ) + if( !action.create.sprites.size ) return 0; - action.sprites.each( fn( MAP_SPRITE* s ) { + action.create.sprites.each( fn( MAP_SPRITE* s ) { map->sprites.push( *s ); } ); } break; case EDITOR_UNDO_CREATE_ENTITIES: { - if( !action.entities.size ) + if( !action.create.entities.size ) return 0; - action.entities.each( fn( MAP_ENTITY* ent ) { + action.create.entities.each( fn( MAP_ENTITY* ent ) { map->entities.push( *ent ); } ); } break; @@ -469,11 +538,21 @@ static U8 editor_apply_undo_action_forward( GAME_EDITOR* e, GAME_EDITOR::EDITOR_ return 1; } +U8 editor_apply_undo_action_forward( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) { + if( !e || !e->map ) + return 0; + + if( action.type == EDITOR_UNDO_EDITPROPS ) + return editor_apply_undo_action_forward_props( e, action ); + + return editor_apply_undo_action_forward_create( e, action ); +} + U8 editor_undo( GAME_EDITOR* e ) { if( !e || !e->map || !e->undo_actions.size ) return 0; - GAME_EDITOR::EDITOR_UNDO_ACTION action = e->undo_actions.pop(); + EDITOR_UNDO_ACTION action = e->undo_actions.pop(); if( !editor_apply_undo_action_reverse( e, action ) ) { e->undo_actions.push( action ); return 0; @@ -487,7 +566,7 @@ U8 editor_redo( GAME_EDITOR* e ) { if( !e || !e->map || !e->redo_actions.size ) return 0; - GAME_EDITOR::EDITOR_UNDO_ACTION action = e->redo_actions.pop(); + EDITOR_UNDO_ACTION action = e->redo_actions.pop(); if( !editor_apply_undo_action_forward( e, action ) ) { e->redo_actions.push( action ); return 0; |
