changeset 120:66ca475e2a5a src

- 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
author mroi
date Wed, 12 Mar 2003 11:38:11 +0000
parents bd8601b74c3d
children 545bd4fc0a16
files vm.c vm.h
diffstat 2 files changed, 60 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);