Mercurial > libdvdnav.hg
comparison vm.c @ 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 | b6834e6359cf |
children | e404d210ff91 |
comparison
equal
deleted
inserted
replaced
119:bd8601b74c3d | 120:66ca475e2a5a |
---|---|
249 } | 249 } |
250 | 250 |
251 | 251 |
252 /* Basic Handling */ | 252 /* Basic Handling */ |
253 | 253 |
254 void vm_start(vm_t *vm) | 254 void vm_start(vm_t *vm) { |
255 { | |
256 /* Set pgc to FP (First Play) pgc */ | 255 /* Set pgc to FP (First Play) pgc */ |
257 set_FP_PGC(vm); | 256 set_FP_PGC(vm); |
258 process_command(vm, play_PGC(vm)); | 257 process_command(vm, play_PGC(vm)); |
259 } | 258 } |
260 | 259 |
263 ifoClose(vm->vmgi); | 262 ifoClose(vm->vmgi); |
264 vm->vmgi=NULL; | 263 vm->vmgi=NULL; |
265 } | 264 } |
266 if(vm->vtsi) { | 265 if(vm->vtsi) { |
267 ifoClose(vm->vtsi); | 266 ifoClose(vm->vtsi); |
268 vm->vmgi=NULL; | 267 vm->vtsi=NULL; |
269 } | 268 } |
270 if(vm->dvd) { | 269 if(vm->dvd) { |
271 DVDClose(vm->dvd); | 270 DVDClose(vm->dvd); |
272 vm->dvd=NULL; | 271 vm->dvd=NULL; |
273 } | 272 } |
362 } | 361 } |
363 return 1; | 362 return 1; |
364 } | 363 } |
365 | 364 |
366 | 365 |
366 /* copying and merging */ | |
367 | |
368 vm_t *vm_new_copy(vm_t *source) { | |
369 vm_t *target = vm_new_vm(); | |
370 int vtsN; | |
371 int pgcN = get_PGCN(source); | |
372 int pgN = (source->state).pgN; | |
373 | |
374 assert(pgcN); | |
375 | |
376 memcpy(target, source, sizeof(vm_t)); | |
377 | |
378 /* open a new vtsi handle, because the copy might switch to another VTS */ | |
379 target->vtsi = NULL; | |
380 vtsN = (target->state).vtsN; | |
381 (target->state).vtsN = 0; | |
382 ifoOpenNewVTSI(target, target->dvd, vtsN); | |
383 | |
384 /* restore pgc pointer into the new vtsi */ | |
385 if (!set_PGCN(target, pgcN)) | |
386 assert(0); | |
387 (target->state).pgN = pgN; | |
388 | |
389 return target; | |
390 } | |
391 | |
392 void vm_merge(vm_t *target, vm_t *source) { | |
393 if(target->vtsi) | |
394 ifoClose(target->vtsi); | |
395 memcpy(target, source, sizeof(vm_t)); | |
396 memset(source, 0, sizeof(vm_t)); | |
397 } | |
398 | |
399 void vm_free_copy(vm_t *vm) { | |
400 if(vm->vtsi) | |
401 ifoClose(vm->vtsi); | |
402 free(vm); | |
403 } | |
404 | |
405 | |
367 /* regular playback */ | 406 /* regular playback */ |
368 | 407 |
369 void vm_position_get(vm_t *vm, vm_position_t *position) { | 408 void vm_position_get(vm_t *vm, vm_position_t *position) { |
370 position->button = (vm->state).HL_BTNN_REG >> 10; | 409 position->button = (vm->state).HL_BTNN_REG >> 10; |
371 position->vts = (vm->state).vtsN; | 410 position->vts = (vm->state).vtsN; |
456 int vm_jump_prev_pg(vm_t *vm) { | 495 int vm_jump_prev_pg(vm_t *vm) { |
457 if ((vm->state).pgN <= 1) { | 496 if ((vm->state).pgN <= 1) { |
458 /* first program -> move to last program of previous PGC */ | 497 /* first program -> move to last program of previous PGC */ |
459 if ((vm->state).pgc->prev_pgc_nr && set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) { | 498 if ((vm->state).pgc->prev_pgc_nr && set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) { |
460 process_command(vm, play_PGC(vm)); | 499 process_command(vm, play_PGC(vm)); |
500 vm_jump_pg(vm, (vm->state).pgc->nr_of_programs); | |
461 return 1; | 501 return 1; |
462 } | 502 } |
463 return 0; | 503 return 0; |
464 } else { | 504 } else { |
465 vm_jump_pg(vm, (vm->state).pgN - 1); | 505 vm_jump_pg(vm, (vm->state).pgN - 1); |
917 } | 957 } |
918 | 958 |
919 #ifdef TRACE | 959 #ifdef TRACE |
920 fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n"); | 960 fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n"); |
921 #endif | 961 #endif |
922 assert((vm->state).pgc->next_pgc_nr != 0); | |
923 /* Should end up in the STOP_DOMAIN if next_pgc is 0. */ | 962 /* Should end up in the STOP_DOMAIN if next_pgc is 0. */ |
924 if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) | 963 if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) { |
925 assert(0); | 964 link_values.command = Exit; |
965 return link_values; | |
966 } | |
926 return play_PGC(vm); | 967 return play_PGC(vm); |
927 } | 968 } |
928 | 969 |
929 static link_t play_PG(vm_t *vm) { | 970 static link_t play_PG(vm_t *vm) { |
930 #ifdef TRACE | 971 #ifdef TRACE |
1297 (vm->state).cellN = link_values.data1; | 1338 (vm->state).cellN = link_values.data1; |
1298 link_values = play_Cell(vm); | 1339 link_values = play_Cell(vm); |
1299 break; | 1340 break; |
1300 | 1341 |
1301 case Exit: | 1342 case Exit: |
1302 fprintf(MSG_OUT, "libdvdnav: FIXME:in trouble...Link Exit - CRASHING!!!\n"); | 1343 vm->stopped = 1; |
1303 assert(0); /* What should we do here?? */ | 1344 return 0; |
1304 | 1345 |
1305 case JumpTT: | 1346 case JumpTT: |
1306 /* Jump to VTS Title Domain */ | 1347 /* Jump to VTS Title Domain */ |
1307 /* Only allowed from the First Play domain(PGC) */ | 1348 /* Only allowed from the First Play domain(PGC) */ |
1308 /* or the Video Manager domain (VMG) */ | 1349 /* or the Video Manager domain (VMG) */ |
1740 #endif | 1781 #endif |
1741 | 1782 |
1742 | 1783 |
1743 /* | 1784 /* |
1744 * $Log$ | 1785 * $Log$ |
1786 * Revision 1.44 2003/03/12 11:38:10 mroi | |
1787 * - provide the means to make copies of the VM to try certain operations on a copy and | |
1788 * merge the changes back on success | |
1789 * - do not trigger an assertion when falling off a program chain, but stop the VM | |
1790 * | |
1745 * Revision 1.43 2003/02/20 15:32:19 mroi | 1791 * Revision 1.43 2003/02/20 15:32:19 mroi |
1746 * big libdvdnav cleanup, quoting the ChangeLog: | 1792 * big libdvdnav cleanup, quoting the ChangeLog: |
1747 * * some bugfixes | 1793 * * some bugfixes |
1748 * * code cleanup | 1794 * * code cleanup |
1749 * * build process polishing | 1795 * * build process polishing |