# HG changeset patch # User mroi # Date 1047469091 0 # Node ID 66ca475e2a5a4d450da155ebbed4f81af6456eb1 # Parent bd8601b74c3dd646c87b90f540aa9f44e3655804 - provide the means to make copies of the VM to try certain operations on a copy and merge the changes back on success - do not trigger an assertion when falling off a program chain, but stop the VM diff -r bd8601b74c3d -r 66ca475e2a5a vm.c --- a/vm.c Sat Mar 08 14:04:20 2003 +0000 +++ b/vm.c Wed Mar 12 11:38:11 2003 +0000 @@ -251,8 +251,7 @@ /* Basic Handling */ -void vm_start(vm_t *vm) -{ +void vm_start(vm_t *vm) { /* Set pgc to FP (First Play) pgc */ set_FP_PGC(vm); process_command(vm, play_PGC(vm)); @@ -265,7 +264,7 @@ } if(vm->vtsi) { ifoClose(vm->vtsi); - vm->vmgi=NULL; + vm->vtsi=NULL; } if(vm->dvd) { DVDClose(vm->dvd); @@ -364,6 +363,46 @@ } +/* copying and merging */ + +vm_t *vm_new_copy(vm_t *source) { + vm_t *target = vm_new_vm(); + int vtsN; + int pgcN = get_PGCN(source); + int pgN = (source->state).pgN; + + assert(pgcN); + + memcpy(target, source, sizeof(vm_t)); + + /* open a new vtsi handle, because the copy might switch to another VTS */ + target->vtsi = NULL; + vtsN = (target->state).vtsN; + (target->state).vtsN = 0; + ifoOpenNewVTSI(target, target->dvd, vtsN); + + /* restore pgc pointer into the new vtsi */ + if (!set_PGCN(target, pgcN)) + assert(0); + (target->state).pgN = pgN; + + return target; +} + +void vm_merge(vm_t *target, vm_t *source) { + if(target->vtsi) + ifoClose(target->vtsi); + memcpy(target, source, sizeof(vm_t)); + memset(source, 0, sizeof(vm_t)); +} + +void vm_free_copy(vm_t *vm) { + if(vm->vtsi) + ifoClose(vm->vtsi); + free(vm); +} + + /* regular playback */ void vm_position_get(vm_t *vm, vm_position_t *position) { @@ -458,6 +497,7 @@ /* first program -> move to last program of previous PGC */ if ((vm->state).pgc->prev_pgc_nr && set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) { process_command(vm, play_PGC(vm)); + vm_jump_pg(vm, (vm->state).pgc->nr_of_programs); return 1; } return 0; @@ -919,10 +959,11 @@ #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n"); #endif - assert((vm->state).pgc->next_pgc_nr != 0); /* Should end up in the STOP_DOMAIN if next_pgc is 0. */ - if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) - assert(0); + if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) { + link_values.command = Exit; + return link_values; + } return play_PGC(vm); } @@ -1299,8 +1340,8 @@ break; case Exit: - fprintf(MSG_OUT, "libdvdnav: FIXME:in trouble...Link Exit - CRASHING!!!\n"); - assert(0); /* What should we do here?? */ + vm->stopped = 1; + return 0; case JumpTT: /* Jump to VTS Title Domain */ @@ -1742,6 +1783,11 @@ /* * $Log$ + * Revision 1.44 2003/03/12 11:38:10 mroi + * - provide the means to make copies of the VM to try certain operations on a copy and + * merge the changes back on success + * - do not trigger an assertion when falling off a program chain, but stop the VM + * * Revision 1.43 2003/02/20 15:32:19 mroi * big libdvdnav cleanup, quoting the ChangeLog: * * some bugfixes diff -r bd8601b74c3d -r 66ca475e2a5a vm.h --- a/vm.h Sat Mar 08 14:04:20 2003 +0000 +++ b/vm.h Wed Mar 12 11:38:11 2003 +0000 @@ -113,7 +113,7 @@ #define PTL_REG registers.SPRM[13] /* Initialisation & destruction */ -vm_t* vm_new_vm(); +vm_t *vm_new_vm(); void vm_free_vm(vm_t *vm); /* IFO access */ @@ -128,6 +128,11 @@ void vm_stop(vm_t *vm); int vm_reset(vm_t *vm, const char *dvdroot); +/* copying and merging - useful for try-running an operation */ +vm_t *vm_new_copy(vm_t *vm); +void vm_merge(vm_t *target, vm_t *source); +void vm_free_copy(vm_t *vm); + /* regular playback */ void vm_position_get(vm_t *vm, vm_position_t *position); void vm_get_next_cell(vm_t *vm);