summaryrefslogtreecommitdiff
path: root/src/input/libdvdnav/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/libdvdnav/vm.c')
-rw-r--r--src/input/libdvdnav/vm.c1685
1 files changed, 694 insertions, 991 deletions
diff --git a/src/input/libdvdnav/vm.c b/src/input/libdvdnav/vm.c
index c39737773..740928be0 100644
--- a/src/input/libdvdnav/vm.c
+++ b/src/input/libdvdnav/vm.c
@@ -19,7 +19,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: vm.c,v 1.12 2003/02/11 16:28:47 heikos Exp $
+ * $Id: vm.c,v 1.13 2003/02/20 16:02:01 mroi Exp $
*
*/
@@ -45,52 +45,50 @@
#include "vm.h"
#include "dvdnav_internal.h"
-
+/*
#define STRICT
-
+*/
/* Local prototypes */
-static void saveRSMinfo(vm_t *vm,int cellN, int blockN);
+/* get_XYZ returns a value.
+ * set_XYZ sets state using passed parameters.
+ * returns success/failure.
+ */
+
+/* Play */
static link_t play_PGC(vm_t *vm);
static link_t play_PGC_PG(vm_t *vm, int pgN);
static link_t play_PGC_post(vm_t *vm);
static link_t play_PG(vm_t *vm);
static link_t play_Cell(vm_t *vm);
static link_t play_Cell_post(vm_t *vm);
-static link_t process_command(vm_t *vm,link_t link_values);
-
-static void ifoOpenNewVTSI(vm_t *vm,dvd_reader_t *dvd, int vtsN);
-static pgcit_t* get_PGCIT(vm_t *vm);
-
-/* get_XYZ returns a value.
- * ser_XYZ sets state using passed parameters.
- * returns success/failure.
- */
-/* Can only be called when in VTS_DOMAIN */
-static int set_FP_PGC(vm_t *vm); /* FP */
-static int set_TT(vm_t *vm,int tt);
-static int set_VTS_TT(vm_t *vm,int vtsN, int vts_ttn);
-static int set_VTS_PTT(vm_t *vm,int vtsN, int vts_ttn, int part);
+/* Process link - returns 1 if a hop has been performed */
+static int process_command(vm_t *vm,link_t link_values);
-static int set_MENU(vm_t *vm,int menu); /* VTSM & VMGM */
+/* Set */
+static int set_TT(vm_t *vm, int tt);
+static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn);
+static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part);
+static int set_FP_PGC(vm_t *vm);
+static int set_MENU(vm_t *vm, int menu);
+static int set_PGCN(vm_t *vm, int pgcN);
+static int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */
+static void set_RSMinfo(vm_t *vm, int cellN, int blockN);
-/* Called in any domain */
+/* Get */
static int get_TT(vm_t *vm, int vtsN, int vts_ttn);
-static int get_ID(vm_t *vm,int id);
+static int get_ID(vm_t *vm, int id);
static int get_PGCN(vm_t *vm);
-static int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */
-static int set_PGC(vm_t *vm,int pgcN);
-/* Initialisation */
+static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
+static pgcit_t* get_PGCIT(vm_t *vm);
-vm_t* vm_new_vm() {
- vm_t *vm = (vm_t*)calloc(sizeof(vm_t), sizeof(char));
- return vm;
-}
+/* Helper functions */
+#ifdef TRACE
static void vm_print_current_domain_state(vm_t *vm) {
switch((vm->state).domain) {
case VTS_DOMAIN:
@@ -123,60 +121,9 @@ static void vm_print_current_domain_state(vm_t *vm) {
(vm->state).TTN_REG,
(vm->state).TT_PGCN_REG);
}
+#endif
-void vm_stop(vm_t *vm) {
- if(!vm)
- return;
-
- if(vm->vmgi) {
- ifoClose(vm->vmgi);
- vm->vmgi=NULL;
- }
-
- if(vm->vtsi) {
- ifoClose(vm->vtsi);
- vm->vmgi=NULL;
- }
-
- if(vm->dvd) {
- DVDClose(vm->dvd);
- vm->dvd=NULL;
- }
-}
-
-void vm_free_vm(vm_t *vm) {
- if(vm) {
- vm_stop(vm);
- free(vm);
- }
-}
-
-/* IFO Access */
-
-ifo_handle_t *vm_get_vmgi(vm_t *vm) {
- if(!vm)
- return NULL;
-
- return vm->vmgi;
-}
-
-ifo_handle_t *vm_get_vtsi(vm_t *vm) {
- if(!vm)
- return NULL;
-
- return vm->vtsi;
-}
-
-/* Reader Access */
-
-dvd_reader_t *vm_get_dvd_reader(vm_t *vm) {
- if(!vm)
- return NULL;
-
- return vm->dvd;
-}
-
-void dvd_read_name( vm_t *this, char *devname) {
+void dvd_read_name( vm_t *this, const char *devname) {
int fd, i;
#ifndef __FreeBSD__
off64_t off;
@@ -193,88 +140,173 @@ void dvd_read_name( vm_t *this, char *devname) {
off = read( fd, data, DVD_VIDEO_LB_LEN );
close(fd);
if (off == ( (int64_t) DVD_VIDEO_LB_LEN )) {
- fprintf( stderr, "VM DVD Title: ");
+ fprintf(MSG_OUT, "libdvdnav: DVD Title: ");
for(i=25; i < 73; i++ ) {
if((data[i] == 0)) break;
if((data[i] > 32) && (data[i] < 127)) {
- fprintf(stderr, "%c", data[i]);
+ fprintf(MSG_OUT, "%c", data[i]);
} else {
- fprintf(stderr, " ");
+ fprintf(MSG_OUT, " ");
}
}
strncpy(&this->dvd_name[0], &data[25], 48);
- /* fprintf(stderr, "TITLE:%s\n",&this->dvd_name[0]); */
this->dvd_name[48]=0;
- this->dvd_name_length=strlen(&this->dvd_name[0]);
- fprintf( stderr, "\nVM DVD Serial Number: ");
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: ");
for(i=73; i < 89; i++ ) {
if((data[i] == 0)) break;
if((data[i] > 32) && (data[i] < 127)) {
- fprintf(stderr, "%c", data[i]);
+ fprintf(MSG_OUT, "%c", data[i]);
} else {
- fprintf(stderr, " ");
+ fprintf(MSG_OUT, " ");
}
}
- fprintf( stderr, "\nVM DVD Title (Alternative): ");
+ fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): ");
for(i=89; i < 128; i++ ) {
if((data[i] == 0)) break;
if((data[i] > 32) && (data[i] < 127)) {
- fprintf(stderr, "%c", data[i]);
+ fprintf(MSG_OUT, "%c", data[i]);
} else {
- fprintf(stderr, " ");
+ fprintf(MSG_OUT, " ");
}
}
- fprintf( stderr, "\n");
+ fprintf(MSG_OUT, "\n");
} else {
- fprintf( stderr, "libdvdread: Can't read name block. Probably not a DVD-ROM device.\n");
+ fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
}
} else {
- fprintf( stderr, "libdvdread: Can't seek to block %u\n", 32 );
+ fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
}
close(fd);
} else {
- fprintf(stderr,"NAME OPEN FAILED\n");
- }
+ fprintf(MSG_OUT, "NAME OPEN FAILED\n");
+ }
+}
+
+static void ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
+ if((vm->state).vtsN == vtsN) {
+ return; /* We alread have it */
+ }
+
+ if(vm->vtsi != NULL)
+ ifoClose(vm->vtsi);
+
+ vm->vtsi = ifoOpenVTSI(dvd, vtsN);
+ if(vm->vtsi == NULL) {
+ fprintf(MSG_OUT, "libdvdnav: ifoOpenVTSI failed - CRASHING!!!\n");
+ assert(0);
+ }
+ if(!ifoRead_VTS_PTT_SRPT(vm->vtsi)) {
+ fprintf(MSG_OUT, "libdvdnav: ifoRead_VTS_PTT_SRPT failed - CRASHING!!!\n");
+ assert(0);
+ }
+ if(!ifoRead_PGCIT(vm->vtsi)) {
+ fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCIT failed - CRASHING!!!\n");
+ assert(0);
+ }
+ if(!ifoRead_PGCI_UT(vm->vtsi)) {
+ fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCI_UT failed - CRASHING!!!\n");
+ assert(0);
+ }
+ if(!ifoRead_VOBU_ADMAP(vm->vtsi)) {
+ fprintf(MSG_OUT, "libdvdnav: ifoRead_VOBU_ADMAP vtsi failed - CRASHING\n");
+ assert(0);
+ }
+ if(!ifoRead_TITLE_VOBU_ADMAP(vm->vtsi)) {
+ fprintf(MSG_OUT, "libdvdnav: ifoRead_TITLE_VOBU_ADMAP vtsi failed - CRASHING\n");
+ assert(0);
+ }
+ (vm->state).vtsN = vtsN;
+}
+
+
+/* Initialisation & Destruction */
+
+vm_t* vm_new_vm() {
+ return (vm_t*)calloc(sizeof(vm_t), sizeof(char));
+}
+
+void vm_free_vm(vm_t *vm) {
+ vm_stop(vm);
+ free(vm);
+}
+
+
+/* IFO Access */
+
+ifo_handle_t *vm_get_vmgi(vm_t *vm) {
+ return vm->vmgi;
}
-int vm_reset(vm_t *vm, char *dvdroot) /* , register_t regs) */ {
+ifo_handle_t *vm_get_vtsi(vm_t *vm) {
+ return vm->vtsi;
+}
+
+
+/* Reader Access */
+
+dvd_reader_t *vm_get_dvd_reader(vm_t *vm) {
+ return vm->dvd;
+}
+
+
+/* Basic Handling */
+
+void vm_start(vm_t *vm)
+{
+ /* Set pgc to FP (First Play) pgc */
+ set_FP_PGC(vm);
+ process_command(vm, play_PGC(vm));
+}
+
+void vm_stop(vm_t *vm) {
+ if(vm->vmgi) {
+ ifoClose(vm->vmgi);
+ vm->vmgi=NULL;
+ }
+ if(vm->vtsi) {
+ ifoClose(vm->vtsi);
+ vm->vmgi=NULL;
+ }
+ if(vm->dvd) {
+ DVDClose(vm->dvd);
+ vm->dvd=NULL;
+ }
+ vm->stopped = 1;
+}
+
+int vm_reset(vm_t *vm, const char *dvdroot) {
/* Setup State */
- memset((vm->state).registers.SPRM, 0, sizeof(uint16_t)*24);
+ memset((vm->state).registers.SPRM, 0, sizeof((vm->state).registers.SPRM));
memset((vm->state).registers.GPRM, 0, sizeof((vm->state).registers.GPRM));
memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode));
memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode));
memset((vm->state).registers.GPRM_time, 0, sizeof((vm->state).registers.GPRM_time));
- (vm->state).registers.SPRM[0] = ('e'<<8)|'n'; /* Player Menu Languange code */
- (vm->state).AST_REG = 15; /* 15 why? */
- (vm->state).SPST_REG = 62; /* 62 why? */
- (vm->state).AGL_REG = 1;
- (vm->state).TTN_REG = 1;
- (vm->state).VTS_TTN_REG = 1;
- /* (vm->state).TT_PGCN_REG = 0 */
- (vm->state).PTTN_REG = 1;
- (vm->state).HL_BTNN_REG = 1 << 10;
-
- (vm->state).PTL_REG = 15; /* Parental Level */
- (vm->state).registers.SPRM[12] = ('U'<<8)|'S'; /* Parental Management Country Code */
- (vm->state).registers.SPRM[16] = ('e'<<8)|'n'; /* Initial Language Code for Audio */
- (vm->state).registers.SPRM[18] = ('e'<<8)|'n'; /* Initial Language Code for Spu */
- /* Player Regional Code Mask.
- * bit0 = Region 1
- * bit1 = Region 2
- */
- (vm->state).registers.SPRM[20] = 0x1; /* Player Regional Code Mask. Region free! */
- (vm->state).registers.SPRM[14] = 0x100; /* Try Pan&Scan */
+ (vm->state).registers.SPRM[0] = ('e'<<8)|'n'; /* Player Menu Languange code */
+ (vm->state).AST_REG = 15; /* 15 why? */
+ (vm->state).SPST_REG = 62; /* 62 why? */
+ (vm->state).AGL_REG = 1;
+ (vm->state).TTN_REG = 1;
+ (vm->state).VTS_TTN_REG = 1;
+ /* (vm->state).TT_PGCN_REG = 0 */
+ (vm->state).PTTN_REG = 1;
+ (vm->state).HL_BTNN_REG = 1 << 10;
+ (vm->state).PTL_REG = 15; /* Parental Level */
+ (vm->state).registers.SPRM[12] = ('U'<<8)|'S'; /* Parental Management Country Code */
+ (vm->state).registers.SPRM[16] = ('e'<<8)|'n'; /* Initial Language Code for Audio */
+ (vm->state).registers.SPRM[18] = ('e'<<8)|'n'; /* Initial Language Code for Spu */
+ (vm->state).registers.SPRM[20] = 0x1; /* Player Regional Code Mask. Region free! */
+ (vm->state).registers.SPRM[14] = 0x100; /* Try Pan&Scan */
- (vm->state).pgN = 0;
- (vm->state).cellN = 0;
- (vm->state).cell_restart = 0;
+ (vm->state).pgN = 0;
+ (vm->state).cellN = 0;
+ (vm->state).cell_restart = 0;
- (vm->state).domain = FP_DOMAIN;
- (vm->state).rsm_vtsN = 0;
- (vm->state).rsm_cellN = 0;
- (vm->state).rsm_blockN = 0;
+ (vm->state).domain = FP_DOMAIN;
+ (vm->state).rsm_vtsN = 0;
+ (vm->state).rsm_cellN = 0;
+ (vm->state).rsm_blockN = 0;
- (vm->state).vtsN = -1;
+ (vm->state).vtsN = -1;
if (vm->dvd && dvdroot) {
/* a new dvd device has been requested */
@@ -284,92 +316,77 @@ int vm_reset(vm_t *vm, char *dvdroot) /* , register_t regs) */ {
vm->dvd = DVDOpen(dvdroot);
if(!vm->dvd) {
fprintf(MSG_OUT, "libdvdnav: vm: faild to open/read the DVD\n");
- return -1;
+ return 0;
}
dvd_read_name(vm, dvdroot);
- vm->map = remap_loadmap( vm->dvd_name);
-
+ vm->map = remap_loadmap(vm->dvd_name);
vm->vmgi = ifoOpenVMGI(vm->dvd);
if(!vm->vmgi) {
fprintf(MSG_OUT, "libdvdnav: vm: faild to read VIDEO_TS.IFO\n");
- return -1;
+ return 0;
}
if(!ifoRead_FP_PGC(vm->vmgi)) {
fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_FP_PGC failed\n");
- return -1;
+ return 0;
}
if(!ifoRead_TT_SRPT(vm->vmgi)) {
fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_TT_SRPT failed\n");
- return -1;
+ return 0;
}
if(!ifoRead_PGCI_UT(vm->vmgi)) {
fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_PGCI_UT failed\n");
- return -1;
+ return 0;
}
if(!ifoRead_PTL_MAIT(vm->vmgi)) {
fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_PTL_MAIT failed\n");
- ; /* return -1; Not really used for now.. */
+ /* return 0; Not really used for now.. */
}
if(!ifoRead_VTS_ATRT(vm->vmgi)) {
fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_VTS_ATRT failed\n");
- ; /* return -1; Not really used for now.. */
+ /* return 0; Not really used for now.. */
}
if(!ifoRead_VOBU_ADMAP(vm->vmgi)) {
fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_VOBU_ADMAP vgmi failed\n");
- ; /* return -1; Not really used for now.. */
+ /* return 0; Not really used for now.. */
}
/* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
}
- else fprintf(MSG_OUT, "libdvdnav: vm: reset\n");
if (vm->vmgi) {
- fprintf(MSG_OUT, "libdvdnav: DVD disk reports itself with Region mask 0x%08x. Maybe region %u.\n",
- vm->vmgi->vmgi_mat->vmg_category,
- (((vm->vmgi->vmgi_mat->vmg_category >> 16) ^ 0xff) & 0xff) );
+ int i, mask;
+ fprintf(MSG_OUT, "libdvdnav: DVD disk reports itself with Region mask 0x%08x. Regions:",
+ vm->vmgi->vmgi_mat->vmg_category);
+ for (i = 1, mask = 1; i <= 8; i++, mask <<= 1)
+ if (((vm->vmgi->vmgi_mat->vmg_category >> 16) & mask) == 0)
+ fprintf(MSG_OUT, " %d", i);
+ fprintf(MSG_OUT, "\n");
}
- return 0;
+ return 1;
}
-/* FIXME TODO XXX $$$ Handle error condition too... */
-int vm_start(vm_t *vm)
-{
- link_t link_values;
-
- /* Set pgc to FP(First Play) pgc */
- set_FP_PGC(vm);
- link_values = play_PGC(vm);
- link_values = process_command(vm,link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_start: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
+/* regular playback */
- return 0; /* ?? */
-}
-
-int vm_position_get(vm_t *vm, vm_position_t *position) {
+void vm_position_get(vm_t *vm, vm_position_t *position) {
position->button = (vm->state).HL_BTNN_REG >> 10;
+ position->vts = (vm->state).vtsN;
+ position->domain = (vm->state).domain;
position->spu_channel = (vm->state).SPST_REG;
position->audio_channel = (vm->state).AST_REG;
position->angle_channel = (vm->state).AGL_REG;
position->hop_channel = vm->hop_channel; /* Increases by one on each hop */
- position->vts = (vm->state).vtsN;
- position->domain = (vm->state).domain;
position->cell = (vm->state).cellN;
position->cell_restart = (vm->state).cell_restart;
+ position->cell_start = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector;
position->still = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].still_time;
- position->vobu_start = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector;
- position->vobu_next = (vm->state).blockN;
+ position->block = (vm->state).blockN;
/* still already detrmined or not at PGC end */
if (position->still || (vm->state).cellN < (vm->state).pgc->nr_of_cells)
- return 1;
+ return;
/* handle PGC stills */
if ((vm->state).pgc->still_time) {
position->still = (vm->state).pgc->still_time;
- return 1;
+ return;
}
/* This is a rough fix for some strange still situations on some strange DVDs.
* There are discs (like the German "Back to the Future" RC2) where the only
@@ -393,312 +410,95 @@ int vm_position_get(vm_t *vm, vm_position_t *position) {
if (time > 0xff) time = 0xff;
position->still = time;
}
-
- return 1;
-}
-
-int vm_position_print(vm_t *vm, vm_position_t *position) {
- fprintf(MSG_OUT, "libdvdnav: But=%x Spu=%x Aud=%x Ang=%x Hop=%x vts=%x dom=%x cell=%x cell_restart=%x still=%x start=%x next=%x\n",
- position->button,
- position->spu_channel,
- position->audio_channel,
- position->angle_channel,
- position->hop_channel,
- position->vts,
- position->domain,
- position->cell,
- position->cell_restart,
- position->still,
- position->vobu_start,
- position->vobu_next);
- return 1;
}
-
-int vm_start_title(vm_t *vm, int tt) {
- link_t link_values;
-
- set_TT(vm, tt);
- link_values = play_PGC(vm);
- link_values = process_command(vm, link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_start_title: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
-
- return 0; /* ?? */
+void vm_get_next_cell(vm_t *vm) {
+ process_command(vm, play_Cell_post(vm));
}
-int vm_jump_prog(vm_t *vm, int pr) {
- link_t link_values;
+/* Jumping */
- set_PGC(vm, get_PGCN(vm));
- (vm->state).pgN = pr; /* ?? set_PGC() clobbers pgN */
- link_values = play_PG(vm);
- link_values = process_command(vm, link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_jump_prog: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
-
- return 0; /* ?? */
+int vm_jump_pg(vm_t *vm, int pg) {
+ (vm->state).pgN = pg;
+ process_command(vm, play_PG(vm));
+ return 1;
}
-int vm_eval_cmd(vm_t *vm, vm_cmd_t *cmd)
-{
- link_t link_values;
-
- if(vmEval_CMD(cmd, 1, &(vm->state).registers, &link_values)) {
- link_values = process_command(vm, link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_eval_cmd: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- return link_values.data2; /* return if there acutally was a jump */
- } else {
- return 0; /* It updated some state thats all... */
- }
-}
+int vm_jump_title_part(vm_t *vm, int title, int part) {
+ int vtsN;
-int vm_get_next_cell(vm_t *vm)
-{
- link_t link_values;
- link_values = play_Cell_post(vm);
- link_values = process_command(vm,link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_get_next_cell: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
-
- return 0; /* ?? */
-}
+ vtsN = vm->vmgi->tt_srpt->title[title - 1].title_set_nr;
-int vm_top_pg(vm_t *vm)
-{
- link_t link_values;
- link_values = play_PG(vm);
- link_values = process_command(vm,link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_top_pg: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
-
- return 1; /* Jump */
+ if(!set_VTS_PTT(vm, vtsN, title, part))
+ return 0;
+ process_command(vm, play_PGC_PG(vm, (vm->state).pgN));
+ vm->hop_channel++;
+ return 1;
}
-int vm_go_up(vm_t *vm)
-{
- link_t link_values;
-
- if(set_PGC(vm, (vm->state).pgc->goup_pgc_nr))
- assert(0);
-
- link_values = play_PGC(vm);
- link_values = process_command(vm,link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_go_up: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
-
- return 1; /* Jump */
+int vm_jump_top_pg(vm_t *vm) {
+ process_command(vm, play_PG(vm));
+ return 1;
}
-int vm_next_pg(vm_t *vm)
-{
+int vm_jump_next_pg(vm_t *vm) {
if((vm->state).pgN >= (vm->state).pgc->nr_of_programs) {
- /* last program -> move to first program of next PGC */
- if ((vm->state).pgc->next_pgc_nr != 0 && set_PGC(vm, (vm->state).pgc->next_pgc_nr) == 0) {
- vm_jump_prog(vm, 1);
- return 1;
- }
- /* something failed, try to move to the cell after the last */
- (vm->state).cellN = (vm->state).pgc->nr_of_cells;
- vm_get_next_cell(vm);
+ /* last program -> move to TailPGC */
+ process_command(vm, play_PGC_post(vm));
return 1;
} else {
- vm_jump_prog(vm, (vm->state).pgN + 1);
+ vm_jump_pg(vm, (vm->state).pgN + 1);
return 1;
}
}
-int vm_prev_pg(vm_t *vm)
-{
+int vm_jump_prev_pg(vm_t *vm) {
if ((vm->state).pgN <= 1) {
/* first program -> move to last program of previous PGC */
- if ((vm->state).pgc->prev_pgc_nr != 0 && set_PGC(vm, (vm->state).pgc->prev_pgc_nr) == 0) {
- vm_jump_prog(vm, (vm->state).pgc->nr_of_programs);
+ if ((vm->state).pgc->prev_pgc_nr && set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) {
+ process_command(vm, play_PGC(vm));
return 1;
}
return 0;
} else {
- vm_jump_prog(vm, (vm->state).pgN - 1);
+ vm_jump_pg(vm, (vm->state).pgN - 1);
return 1;
}
}
-/* Get the current title and part from the current playing position. */
-/* returns S_ERR if not in the VTS_DOMAIN */
-/* FIXME: Should we do some locking here ? */
-int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result)
-{
- vts_ptt_srpt_t *vts_ptt_srpt;
- int title=0, part=0, ttn=0;
- int found = 0;
- int16_t pgcN, pgN;
-
- if((!vm) || (!vm->vtsi) )
- return S_ERR;
-
- if(!title_result || !part_result) {
- fprintf(MSG_OUT, "libdvdnav:vm_get_current_title_part: Passed a NULL pointer");
- return S_ERR;
- }
-
- if(!(vm->state.pgc) )
- return S_ERR;
- if (vm->state.domain != VTS_DOMAIN)
- return S_ERR;
- vts_ptt_srpt = vm->vtsi->vts_ptt_srpt;
- pgcN = get_PGCN(vm);
- pgN = vm->state.pgN;
- printf("VTS_PTT_SRPT - PGC: %3i PG: %3i\n",
- pgcN, pgN);
-
- for(ttn=0;( (ttn < vts_ptt_srpt->nr_of_srpts) && (found == 0) );ttn++) {
- for(part=0;((part < vts_ptt_srpt->title[ttn].nr_of_ptts) && (found == 0));part++) {
- if ( (vts_ptt_srpt->title[ttn].ptt[part].pgcn == pgcN) &&
- (vts_ptt_srpt->title[ttn].ptt[part].pgn == pgN ) ) {
- found = 1;
- break;
- }
- }
- if (found != 0) break;
- }
- ttn++;
- part++;
- for(title=0; title < vm->vmgi->tt_srpt->nr_of_srpts; title++){
- if( (vm->vmgi->tt_srpt->title[title].vts_ttn == ttn) &&
- (vm->vmgi->tt_srpt->title[title].title_set_nr == vm->state.vtsN)){
- found = 1;
- break;
- }
- }
- title++;
-
- if (found == 1) {
- fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n");
- fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
- title, part,
- vts_ptt_srpt->title[ttn-1].ptt[part-1].pgcn ,
- vts_ptt_srpt->title[ttn-1].ptt[part-1].pgn );
- } else {
- fprintf(MSG_OUT, "libdvdnav: ************ this chapter NOT FOUND!\n");
- return S_ERR;
- }
- *title_result = title;
- *part_result = part;
- return 1;
-}
-
-/* Jump to a particlar part of a particlar title on this vts */
-/* returns S_ERR if not in the VTS_DOMAIN */
-/* FIXME: Should we do some locking here ? */
-int vm_jump_title_part(vm_t *vm, int title, int part) {
- link_t link_values;
- int vtsN;
-
- if((!vm) || (!vm->vtsi) || (!vm->vmgi) )
- return S_ERR;
-
- if(!(vm->state.pgc) )
- return S_ERR;
-/* if ( (title < 1) || (title > vm->vtsi->vts_ptt_srpt->nr_of_srpts) ||
- (part < 1) || (part > vm->vtsi->vts_ptt_srpt->title[title].nr_of_ptts) ) {
- return S_ERR;
- }
- */
- if( (title < 1) || (title > vm->vmgi->tt_srpt->nr_of_srpts) ) {
- return S_ERR;
- }
- vtsN = vm->vmgi->tt_srpt->title[title - 1].title_set_nr;
-
- if(set_VTS_PTT(vm, vtsN, title, part) == -1) {
- return S_ERR;
- }
- link_values = play_PGC_PG( vm, (vm->state).pgN );
- link_values = process_command(vm,link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
- assert( (vm->state).blockN == 0 );
- vm->hop_channel++;
-
- fprintf(MSG_OUT, "libdvdnav: previous chapter done\n");
-
- return 1;
-}
-
-static domain_t menuid2domain(DVDMenuID_t menuid)
-{
- domain_t result = VTSM_DOMAIN; /* Really shouldn't have to.. */
-
- switch(menuid) {
- case DVD_MENU_Title:
- result = VMGM_DOMAIN;
- break;
- case DVD_MENU_Root:
- case DVD_MENU_Subpicture:
- case DVD_MENU_Audio:
- case DVD_MENU_Angle:
- case DVD_MENU_Part:
- result = VTSM_DOMAIN;
- break;
+int vm_jump_up(vm_t *vm) {
+ if((vm->state).pgc->goup_pgc_nr && set_PGCN(vm, (vm->state).pgc->goup_pgc_nr)) {
+ process_command(vm, play_PGC(vm));
+ return 1;
}
-
- return result;
+ return 0;
}
-int vm_menu_call(vm_t *vm, DVDMenuID_t menuid, int block)
-{
- domain_t old_domain;
- link_t link_values;
+int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) {
+ domain_t old_domain = (vm->state).domain;
- /* Should check if we are allowed/can acces this menu */
-
-
- /* FIXME XXX $$$ How much state needs to be restored
- * when we fail to find a menu? */
-
- old_domain = (vm->state).domain;
-
- switch((vm->state).domain) {
+ switch ((vm->state).domain) {
case VTS_DOMAIN:
- saveRSMinfo(vm, 0, block);
+ set_RSMinfo(vm, 0, (vm->state).blockN);
/* FALL THROUGH */
case VTSM_DOMAIN:
case VMGM_DOMAIN:
- (vm->state).domain = menuid2domain(menuid);
- if(get_PGCIT(vm) != NULL && set_MENU(vm, menuid) != -1) {
- link_values = play_PGC(vm);
- link_values = process_command(vm, link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_menu_call: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
- return 1; /* Jump */
+ switch(menuid) {
+ case DVD_MENU_Title:
+ (vm->state).domain = VMGM_DOMAIN;
+ break;
+ case DVD_MENU_Root:
+ case DVD_MENU_Subpicture:
+ case DVD_MENU_Audio:
+ case DVD_MENU_Angle:
+ case DVD_MENU_Part:
+ (vm->state).domain = VTSM_DOMAIN;
+ break;
+ }
+ if(get_PGCIT(vm) && set_MENU(vm, menuid)) {
+ process_command(vm, play_PGC(vm));
+ return 1; /* Jump */
} else {
(vm->state).domain = old_domain;
}
@@ -710,72 +510,74 @@ int vm_menu_call(vm_t *vm, DVDMenuID_t menuid, int block)
return 0;
}
-
-int vm_resume(vm_t *vm)
-{
- int i;
+int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd) {
link_t link_values;
- /* Check and see if there is any rsm info!! */
- if((vm->state).rsm_vtsN == 0) {
- return 0;
+ if(vmEval_CMD(cmd, 1, &(vm->state).registers, &link_values))
+ return process_command(vm, link_values);
+ else
+ return 0; /* It updated some state thats all... */
+}
+
+
+/* getting information */
+
+int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) {
+ vts_ptt_srpt_t *vts_ptt_srpt;
+ int title, part = 0, vts_ttn;
+ int found;
+ int16_t pgcN, pgN;
+
+ vts_ptt_srpt = vm->vtsi->vts_ptt_srpt;
+ pgcN = get_PGCN(vm);
+ pgN = vm->state.pgN;
+
+ found = 0;
+ for (vts_ttn = 0; (vts_ttn < vts_ptt_srpt->nr_of_srpts) && !found; vts_ttn++) {
+ for (part = 0; (part < vts_ptt_srpt->title[vts_ttn].nr_of_ptts) && !found; part++) {
+ if ((vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) &&
+ (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN )) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) break;
}
+ vts_ttn++;
+ part++;
- (vm->state).domain = VTS_DOMAIN;
- ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN);
- set_PGC(vm, (vm->state).rsm_pgcN);
-
- /* These should never be set in SystemSpace and/or MenuSpace */
- /* (vm->state).TTN_REG = (vm->state).rsm_tt; */
- /* (vm->state).TT_PGCN_REG = (vm->state).rsm_pgcN; */
- /* (vm->state).HL_BTNN_REG = (vm->state).rsm_btnn; */
- for(i = 0; i < 5; i++) {
- (vm->state).registers.SPRM[4 + i] = (vm->state).rsm_regs[i];
- }
+ title = get_TT(vm, vm->state.vtsN, vts_ttn);
- if((vm->state).rsm_cellN == 0) {
- assert((vm->state).cellN); /* Checking if this ever happens */
- (vm->state).pgN = 1;
- link_values = play_PG(vm);
- link_values = process_command(vm, link_values);
- assert(link_values.command == PlayThis);
- (vm->state).blockN = link_values.data1;
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_resume1: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- assert( (vm->state).blockN == 0 );
- } else {
- (vm->state).cellN = (vm->state).rsm_cellN;
- (vm->state).blockN = (vm->state).rsm_blockN;
#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: vm_resume2: blockN set to 0x%x\n", (vm->state).blockN);
-#endif
- /* (vm->state).pgN = ?? does this gets the righ value in play_Cell, no! */
- if(set_PGN(vm)) {
- /* Were at or past the end of the PGC, should not happen for a RSM */
- assert(0);
- play_PGC_post(vm);
- }
+ if (title) {
+ fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n");
+ fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
+ title, part,
+ vts_ptt_srpt->title[ttn-1].ptt[part-1].pgcn ,
+ vts_ptt_srpt->title[ttn-1].ptt[part-1].pgn );
+ } else {
+ fprintf(MSG_OUT, "libdvdnav: ************ this chapter NOT FOUND!\n");
}
-
- return 1; /* Jump */
+#endif
+ if (!title)
+ return 0;
+ *title_result = title;
+ *part_result = part;
+ return 1;
}
-/**
- * Return the substream id for 'logical' audio stream audioN.
- * 0 <= audioN < 8
+/* Return the substream id for 'logical' audio stream audioN.
+ * 0 <= audioN < 8
*/
-int vm_get_audio_stream(vm_t *vm, int audioN)
-{
+int vm_get_audio_stream(vm_t *vm, int audioN) {
int streamN = -1;
+
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: vm.c:get_audio_stream audioN=%d\n",audioN);
#endif
- if((vm->state).domain == VTSM_DOMAIN
- || (vm->state).domain == VMGM_DOMAIN
- || (vm->state).domain == FP_DOMAIN) {
+
+ if((vm->state).domain != VTS_DOMAIN)
audioN = 0;
- }
if(audioN < 8) {
/* Is there any contol info for this logical stream */
@@ -784,35 +586,26 @@ int vm_get_audio_stream(vm_t *vm, int audioN)
}
}
- if((vm->state).domain == VTSM_DOMAIN
- || (vm->state).domain == VMGM_DOMAIN
- || (vm->state).domain == FP_DOMAIN) {
- if(streamN == -1)
- streamN = 0;
- }
+ if((vm->state).domain != VTS_DOMAIN && streamN == -1)
+ streamN = 0;
- /* Should also check in vtsi/vmgi status that what kind of stream
+ /* FIXME: Should also check in vtsi/vmgi status what kind of stream
* it is (ac3/lpcm/dts/sdds...) to find the right (sub)stream id */
return streamN;
}
-/**
- * Return the substream id for 'logical' subpicture stream subpN and given mode.
+/* Return the substream id for 'logical' subpicture stream subpN and given mode.
* 0 <= subpN < 32
* mode == 0 - widescreen
* mode == 1 - letterbox
* mode == 2 - pan&scan
*/
-int vm_get_subp_stream(vm_t *vm, int subpN, int mode)
-{
+int vm_get_subp_stream(vm_t *vm, int subpN, int mode) {
int streamN = -1;
int source_aspect = vm_get_video_aspect(vm);
- if((vm->state).domain == VTSM_DOMAIN
- || (vm->state).domain == VMGM_DOMAIN
- || (vm->state).domain == FP_DOMAIN) {
+ if((vm->state).domain != VTS_DOMAIN)
subpN = 0;
- }
if(subpN < 32) { /* a valid logical stream */
/* Is this logical stream present */
@@ -833,76 +626,62 @@ int vm_get_subp_stream(vm_t *vm, int subpN, int mode)
}
}
- /* Paranoia.. if no stream select 0 anyway */
-/* I am not paranoid */
-/* if((vm->state).domain == VTSM_DOMAIN
- || (vm->state).domain == VMGM_DOMAIN
- || (vm->state).domain == FP_DOMAIN) {
- if(streamN == -1)
- streamN = 0;
- }
-*/
- /* Should also check in vtsi/vmgi status that what kind of stream it is. */
+ if((vm->state).domain != VTS_DOMAIN && streamN == -1)
+ streamN = 0;
+
+ /* FIXME: Should also check in vtsi/vmgi status what kind of stream it is. */
return streamN;
}
-int vm_get_subp_active_stream(vm_t *vm, int mode)
-{
- int subpN;
+int vm_get_audio_active_stream(vm_t *vm) {
+ int audioN;
int streamN;
- subpN = (vm->state).SPST_REG & ~0x40;
- streamN = vm_get_subp_stream(vm, subpN, mode);
+ audioN = (vm->state).AST_REG ;
+ streamN = vm_get_audio_stream(vm, audioN);
/* If no such stream, then select the first one that exists. */
if(streamN == -1) {
- for(subpN = 0; subpN < 32; subpN++) {
- if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
-
- streamN = vm_get_subp_stream(vm, subpN, mode);
- break;
+ for(audioN = 0; audioN < 8; audioN++) {
+ if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
+ if ((streamN = vm_get_audio_stream(vm, audioN)) >= 0)
+ break;
}
}
- }
-
- /* We should instead send the on/off status to the spudecoder / mixer */
- /* If we are in the title domain see if the spu mixing is on */
- if((vm->state).domain == VTS_DOMAIN && !((vm->state).SPST_REG & 0x40)) {
- /* Bit 7 set means hide, and only let Forced display show */
- return (streamN | 0x80);
- } else {
- return streamN;
}
+
+ return streamN;
}
-int vm_get_audio_active_stream(vm_t *vm)
-{
- int audioN;
+int vm_get_subp_active_stream(vm_t *vm, int mode) {
+ int subpN;
int streamN;
- audioN = (vm->state).AST_REG ;
- streamN = vm_get_audio_stream(vm, audioN);
+ subpN = (vm->state).SPST_REG & ~0x40;
+ streamN = vm_get_subp_stream(vm, subpN, mode);
/* If no such stream, then select the first one that exists. */
if(streamN == -1) {
- for(audioN = 0; audioN < 8; audioN++) {
- if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
- streamN = vm_get_audio_stream(vm, audioN);
- break;
+ for(subpN = 0; subpN < 32; subpN++) {
+ if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
+ if ((streamN = vm_get_subp_stream(vm, subpN, mode)) >= 0)
+ break;
}
}
- }
-
- return streamN;
-}
+ }
+ if((vm->state).domain == VTS_DOMAIN && !((vm->state).SPST_REG & 0x40))
+ /* Bit 7 set means hide, and only let Forced display show */
+ return (streamN | 0x80);
+ else
+ return streamN;
+}
-void vm_get_angle_info(vm_t *vm, int *num_avail, int *current)
-{
+void vm_get_angle_info(vm_t *vm, int *current, int *num_avail) {
*num_avail = 1;
*current = 1;
if((vm->state).domain == VTS_DOMAIN) {
- /* TTN_REG does not allways point to the correct title.. */
title_info_t *title;
+ /* TTN_REG does not allways point to the correct title.. */
if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
return;
title = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1];
@@ -911,87 +690,51 @@ void vm_get_angle_info(vm_t *vm, int *num_avail, int *current)
return;
*num_avail = title->nr_of_angles;
*current = (vm->state).AGL_REG;
- if(*current > *num_avail) /* Is this really a good idea? */
- *current = *num_avail;
}
}
-
-void vm_get_audio_info(vm_t *vm, int *num_avail, int *current)
-{
- if((vm->state).domain == VTS_DOMAIN) {
+#if 0
+/* currently unused */
+void vm_get_audio_info(vm_t *vm, int *current, int *num_avail) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vts_audio_streams;
*current = (vm->state).AST_REG;
- } else if((vm->state).domain == VTSM_DOMAIN) {
+ break;
+ case VTSM_DOMAIN:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; /* 1 */
*current = 1;
- } else if((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN) {
+ break;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
*num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; /* 1 */
*current = 1;
+ break;
}
}
-void vm_get_subp_info(vm_t *vm, int *num_avail, int *current)
-{
- if((vm->state).domain == VTS_DOMAIN) {
+/* currently unused */
+void vm_get_subp_info(vm_t *vm, int *current, int *num_avail) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vts_subp_streams;
*current = (vm->state).SPST_REG;
- } else if((vm->state).domain == VTSM_DOMAIN) {
+ break;
+ case VTSM_DOMAIN:
*num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; /* 1 */
*current = 0x41;
- } else if((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN) {
+ break;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
*num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; /* 1 */
*current = 0x41;
+ break;
}
}
-subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN)
-{
- subp_attr_t attr;
-
- if((vm->state).domain == VTS_DOMAIN) {
- attr = vm->vtsi->vtsi_mat->vts_subp_attr[streamN];
- } else if((vm->state).domain == VTSM_DOMAIN) {
- attr = vm->vtsi->vtsi_mat->vtsm_subp_attr;
- } else if((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN) {
- attr = vm->vmgi->vmgi_mat->vmgm_subp_attr;
- }
- return attr;
-}
-
-audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN)
-{
- audio_attr_t attr;
-
- if((vm->state).domain == VTS_DOMAIN) {
- attr = vm->vtsi->vtsi_mat->vts_audio_attr[streamN];
- } else if((vm->state).domain == VTSM_DOMAIN) {
- attr = vm->vtsi->vtsi_mat->vtsm_audio_attr;
- } else if((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN) {
- attr = vm->vmgi->vmgi_mat->vmgm_audio_attr;
- }
- return attr;
-}
-
-video_attr_t vm_get_video_attr(vm_t *vm)
-{
- video_attr_t attr;
-
- if((vm->state).domain == VTS_DOMAIN) {
- attr = vm->vtsi->vtsi_mat->vts_video_attr;
- } else if((vm->state).domain == VTSM_DOMAIN) {
- attr = vm->vtsi->vtsi_mat->vtsm_video_attr;
- } else if((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN) {
- attr = vm->vmgi->vmgi_mat->vmgm_video_attr;
- }
- return attr;
-}
-
-void vm_get_video_res(vm_t *vm, int *width, int *height)
-{
- video_attr_t attr;
-
- attr = vm_get_video_attr(vm);
+/* currently unused */
+void vm_get_video_res(vm_t *vm, int *width, int *height) {
+ video_attr_t attr = vm_get_video_attr(vm);
if(attr.video_format != 0)
*height = 576;
@@ -1013,70 +756,65 @@ void vm_get_video_res(vm_t *vm, int *width, int *height)
break;
}
}
+#endif
-/* Must be called before domain is changed (get_PGCN()) */
-static void saveRSMinfo(vm_t *vm, int cellN, int blockN)
-{
- int i;
+int vm_get_video_aspect(vm_t *vm) {
+ int aspect = vm_get_video_attr(vm).display_aspect_ratio;
- if(cellN != 0) {
- (vm->state).rsm_cellN = cellN;
- (vm->state).rsm_blockN = 0;
- } else {
- (vm->state).rsm_cellN = (vm->state).cellN;
- (vm->state).rsm_blockN = blockN;
- }
- (vm->state).rsm_vtsN = (vm->state).vtsN;
- (vm->state).rsm_pgcN = get_PGCN(vm);
-
- /* assert((vm->state).rsm_pgcN == (vm->state).TT_PGCN_REG); for VTS_DOMAIN */
+ assert(aspect == 0 || aspect == 3);
+ (vm->state).registers.SPRM[14] &= ~(0x3 << 10);
+ (vm->state).registers.SPRM[14] |= aspect << 10;
- for(i = 0; i < 5; i++) {
- (vm->state).rsm_regs[i] = (vm->state).registers.SPRM[4 + i];
- }
+ return aspect;
}
+int vm_get_video_scale_permission(vm_t *vm) {
+ return vm_get_video_attr(vm).permitted_df;
+}
+video_attr_t vm_get_video_attr(vm_t *vm) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ return vm->vtsi->vtsi_mat->vts_video_attr;
+ case VTSM_DOMAIN:
+ return vm->vtsi->vtsi_mat->vtsm_video_attr;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ return vm->vmgi->vmgi_mat->vmgm_video_attr;
+ }
+ assert(0);
+}
-/* Figure out the correct pgN from the cell and update (vm->state). */
-static int set_PGN(vm_t *vm) {
- int new_pgN = 0;
-
- while(new_pgN < (vm->state).pgc->nr_of_programs
- && (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN])
- new_pgN++;
-
- if(new_pgN == (vm->state).pgc->nr_of_programs) /* We are at the last program */
- if((vm->state).cellN > (vm->state).pgc->nr_of_cells)
- return 1; /* We are past the last cell */
-
- (vm->state).pgN = new_pgN;
-
- if((vm->state).domain == VTS_DOMAIN) {
- playback_type_t *pb_ty;
- if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
- return 0; /* ?? */
- pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
- if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) {
-#if 0 /* TTN_REG can't be trusted to have a correct value here... */
- vts_ptt_srpt_t *ptt_srpt = vtsi->vts_ptt_srpt;
- assert((vm->state).VTS_TTN_REG <= ptt_srpt->nr_of_srpts);
- assert(get_PGCN() == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgcn);
- assert(1 == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgn);
-#endif
- (vm->state).PTTN_REG = (vm->state).pgN;
- } else {
- /* FIXME: Handle RANDOM or SHUFFLE titles. */
- fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n");
- }
-
+audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ return vm->vtsi->vtsi_mat->vts_audio_attr[streamN];
+ case VTSM_DOMAIN:
+ return vm->vtsi->vtsi_mat->vtsm_audio_attr;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ return vm->vmgi->vmgi_mat->vmgm_audio_attr;
}
-
- return 0;
+ assert(0);
+}
+
+subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN) {
+ switch ((vm->state).domain) {
+ case VTS_DOMAIN:
+ return vm->vtsi->vtsi_mat->vts_subp_attr[streamN];
+ case VTSM_DOMAIN:
+ return vm->vtsi->vtsi_mat->vtsm_subp_attr;
+ case VMGM_DOMAIN:
+ case FP_DOMAIN:
+ return vm->vmgi->vmgi_mat->vmgm_subp_attr;
+ }
+ assert(0);
}
-static link_t play_PGC(vm_t *vm)
-{
+
+/* Playback control */
+
+static link_t play_PGC(vm_t *vm) {
link_t link_values;
#ifdef TRACE
@@ -1088,18 +826,19 @@ static link_t play_PGC(vm_t *vm)
}
#endif
- /* This must be set before the pre-commands are executed because they */
- /* might contain a CallSS that will save resume state */
+ /* This must be set before the pre-commands are executed because they
+ * might contain a CallSS that will save resume state */
/* FIXME: This may be only a temporary fix for something... */
(vm->state).pgN = 1;
(vm->state).cellN = 0;
+ (vm->state).blockN = 0;
/* eval -> updates the state and returns either
- some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- just play video i.e first PG
(This is what happens if you fall of the end of the pre_cmds)
- - or a error (are there more cases?) */
+ - or an error (are there more cases?) */
if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
(vm->state).pgc->command_tbl->nr_of_pre,
@@ -1115,8 +854,7 @@ static link_t play_PGC(vm_t *vm)
return play_PG(vm);
}
-static link_t play_PGC_PG(vm_t *vm, int pgN)
-{
+static link_t play_PGC_PG(vm_t *vm, int pgN) {
link_t link_values;
#ifdef TRACE
@@ -1128,18 +866,19 @@ static link_t play_PGC_PG(vm_t *vm, int pgN)
}
#endif
- /* This must be set before the pre-commands are executed because they */
- /* might contain a CallSS that will save resume state */
+ /* This must be set before the pre-commands are executed because they
+ * might contain a CallSS that will save resume state */
/* FIXME: This may be only a temporary fix for something... */
(vm->state).pgN = pgN;
(vm->state).cellN = 0;
+ (vm->state).blockN = 0;
/* eval -> updates the state and returns either
- some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- just play video i.e first PG
(This is what happens if you fall of the end of the pre_cmds)
- - or a error (are there more cases?) */
+ - or an error (are there more cases?) */
if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) {
if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds,
(vm->state).pgc->command_tbl->nr_of_pre,
@@ -1155,8 +894,39 @@ static link_t play_PGC_PG(vm_t *vm, int pgN)
return play_PG(vm);
}
-static link_t play_PG(vm_t *vm)
-{
+static link_t play_PGC_post(vm_t *vm) {
+ link_t link_values;
+
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
+#endif
+
+ /* FIXME: Implement PGC Stills. Currently only Cell stills work */
+ assert((vm->state).pgc->still_time == 0);
+
+ /* eval -> updates the state and returns either
+ - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
+ - just go to next PGC
+ (This is what happens if you fall of the end of the post_cmds)
+ - or an error (are there more cases?) */
+ if((vm->state).pgc->command_tbl &&
+ vmEval_CMD((vm->state).pgc->command_tbl->post_cmds,
+ (vm->state).pgc->command_tbl->nr_of_post,
+ &(vm->state).registers, &link_values)) {
+ return link_values;
+ }
+
+#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);
+ return play_PGC(vm);
+}
+
+static link_t play_PG(vm_t *vm) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i)\n", (vm->state).pgN);
#endif
@@ -1176,9 +946,9 @@ static link_t play_PG(vm_t *vm)
return play_Cell(vm);
}
+static link_t play_Cell(vm_t *vm) {
+ static const link_t play_this = {PlayThis, /* Block in Cell */ 0, 0, 0};
-static link_t play_Cell(vm_t *vm)
-{
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: play_Cell: (vm->state).cellN (%i)\n", (vm->state).cellN);
#endif
@@ -1193,7 +963,6 @@ static link_t play_Cell(vm_t *vm)
return play_PGC_post(vm);
}
-
/* Multi angle/Interleaved */
switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
case 0: /* Normal */
@@ -1204,19 +973,20 @@ static link_t play_Cell(vm_t *vm)
case 0: /* Not part of a block */
assert(0);
case 1: /* Angle block */
- /* Loop and check each cell instead? So we don't get outsid the block. */
+ /* Loop and check each cell instead? So we don't get outside the block? */
(vm->state).cellN += (vm->state).AGL_REG - 1;
#ifdef STRICT
assert((vm->state).cellN <= (vm->state).pgc->nr_of_cells);
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0);
assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1);
-#endif
+#else
if (!((vm->state).cellN <= (vm->state).pgc->nr_of_cells) ||
!((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0) ||
!((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1)) {
fprintf(MSG_OUT, "libdvdnav: Invalid angle block\n");
(vm->state).cellN -= (vm->state).AGL_REG - 1;
}
+#endif
break;
case 2: /* ?? */
case 3: /* ?? */
@@ -1224,33 +994,31 @@ static link_t play_Cell(vm_t *vm)
fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
+ assert(0);
}
break;
case 2: /* Cell in the block */
case 3: /* Last cell in the block */
- /* These might perhaps happen for RSM or LinkC commands? */
+ /* These might perhaps happen for RSM or LinkC commands? */
default:
fprintf(MSG_OUT, "libdvdnav: Cell is in block but did not enter at first cell!\n");
}
/* Updates (vm->state).pgN and PTTN_REG */
- if(set_PGN(vm)) {
+ if(!set_PGN(vm)) {
/* Should not happen */
- link_t tmp = {LinkTailPGC, /* No Button */ 0, 0, 0};
assert(0);
- return tmp;
+ return play_PGC_post(vm);
}
- (vm->state).cell_restart++;
+ (vm->state).cell_restart++;
+ (vm->state).blockN = 0;
+#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Cell should restart here\n");
- {
- link_t tmp = {PlayThis, /* Block in Cell */ 0, 0, 0};
- return tmp;
- }
-
+#endif
+ return play_this;
}
-static link_t play_Cell_post(vm_t *vm)
-{
+static link_t play_Cell_post(vm_t *vm) {
cell_playback_t *cell;
#ifdef TRACE
@@ -1283,16 +1051,17 @@ static link_t play_Cell_post(vm_t *vm)
&(vm->state).registers, &link_values)) {
return link_values;
} else {
+#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Cell command didn't do a Jump, Link or Call\n");
- /* Error ?? goto tail? goto next PG? or what? just continue? */
+#endif
}
} else {
+#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Invalid Cell command\n");
-
+#endif
}
}
-
/* Where to continue after playing the cell... */
/* Multi angle/Interleaved */
switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
@@ -1310,8 +1079,8 @@ static link_t play_Cell_post(vm_t *vm)
case 1: /* Angle block */
/* Skip the 'other' angles */
(vm->state).cellN++;
- while((vm->state).cellN <= (vm->state).pgc->nr_of_cells
- && (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode >= 2) {
+ while((vm->state).cellN <= (vm->state).pgc->nr_of_cells &&
+ (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode >= 2) {
(vm->state).cellN++;
}
break;
@@ -1321,89 +1090,47 @@ static link_t play_Cell_post(vm_t *vm)
fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n",
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode,
(vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type);
+ assert(0);
}
break;
}
-
/* Figure out the correct pgN for the new cell */
- if(set_PGN(vm)) {
+ if(!set_PGN(vm)) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: last cell in this PGC\n");
#endif
return play_PGC_post(vm);
}
-
return play_Cell(vm);
}
-static link_t play_PGC_post(vm_t *vm)
-{
- link_t link_values;
-
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n");
-#endif
-
- /* FIXME Implement PGC Stills. Currently only Cell stills work */
- assert((vm->state).pgc->still_time == 0);
+/* link processing */
- /* eval -> updates the state and returns either
- - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN)
- - or a error (are there more cases?)
- - if you got to the end of the post_cmds, then what ?? */
- if((vm->state).pgc->command_tbl &&
- vmEval_CMD((vm->state).pgc->command_tbl->post_cmds,
- (vm->state).pgc->command_tbl->nr_of_post,
- &(vm->state).registers, &link_values)) {
- return link_values;
- }
+static int process_command(vm_t *vm, link_t link_values) {
- /* Or perhaps handle it here? */
- {
- link_t link_next_pgc = {LinkNextPGC, 0, 0, 0};
- fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n");
- assert((vm->state).pgc->next_pgc_nr != 0);
- /* Should end up in the STOP_DOMAIN if next_pgc is 0. */
- return link_next_pgc;
- }
-}
-
-
-static link_t process_command(vm_t *vm, link_t link_values)
-{
- /* FIXME $$$ Move this to a separate function? */
- vm->badness_counter++;
- if (vm->badness_counter > 1) fprintf(MSG_OUT, "libdvdnav: **** WARNING: process_command re-entered %d*****\n",vm->badness_counter);
while(link_values.command != PlayThis) {
#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Before printout starts:\n");
vmPrint_LINK(link_values);
-
fprintf(MSG_OUT, "libdvdnav: Link values %i %i %i %i\n", link_values.command,
link_values.data1, link_values.data2, link_values.data3);
-
vm_print_current_domain_state(vm);
fprintf(MSG_OUT, "libdvdnav: Before printout ends.\n");
#endif
switch(link_values.command) {
case LinkNoLink:
- /* No Link => PlayThis */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
- link_values.command = PlayThis;
- link_values.data1 = (vm->state).blockN;
- link_values.data2 = 0; /* no actual jump */
- return link_values;
-
+ return 0; /* no actual jump */
+
case LinkTopC:
/* Restart playing from the beginning of the current Cell. */
/* BUTTON number:data1 */
- fprintf(MSG_OUT, "libdvdnav: FIXME: LinkTopC. Replay current Cell\n");
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
link_values = play_Cell(vm);
@@ -1413,7 +1140,8 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* BUTTON number:data1 */
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
- (vm->state).cellN += 1; /* if cellN becomes > nr_of_cells? it is handled in play_Cell() */
+ assert((vm->state).cellN > 1);
+ (vm->state).cellN += 1;
link_values = play_Cell(vm);
break;
case LinkPrevC:
@@ -1421,17 +1149,16 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* BUTTON number:data1 */
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
- (vm->state).cellN -= 1; /* If cellN becomes < 1? it is handled in play_Cell() */
+ (vm->state).cellN -= 1;
link_values = play_Cell(vm);
break;
case LinkTopPG:
- /* Link to Top Program */
+ /* Link to Top of Program */
/* BUTTON number:data1 */
fprintf(MSG_OUT, "libdvdnav: FIXME: LinkTopPG. This should start the current PG again.\n");
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
- /* Does pgN always contain the current value? */
link_values = play_PG(vm);
break;
case LinkNextPG:
@@ -1439,8 +1166,7 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* BUTTON number:data1 */
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
- /* Does pgN always contain the current value? */
- (vm->state).pgN += 1; /* FIXME: What if pgN becomes > pgc.nr_of_programs? */
+ (vm->state).pgN += 1;
link_values = play_PG(vm);
break;
case LinkPrevPG:
@@ -1448,16 +1174,14 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* BUTTON number:data1 */
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
- /* Does pgN always contain the current value? */
assert((vm->state).pgN > 1);
- (vm->state).pgN -= 1; /* FIXME: What if pgN becomes < 1? */
+ (vm->state).pgN -= 1;
link_values = play_PG(vm);
break;
-
+
case LinkTopPGC:
/* Restart playing from beginning of current Program Chain */
/* BUTTON number:data1 */
- fprintf(MSG_OUT, "libdvdnav: FIXME: LinkTopPGC. Restart from beginning of current Program Chain\n");
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
link_values = play_PGC(vm);
@@ -1468,7 +1192,7 @@ static link_t process_command(vm_t *vm, link_t link_values)
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
assert((vm->state).pgc->next_pgc_nr != 0);
- if(set_PGC(vm, (vm->state).pgc->next_pgc_nr))
+ if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr))
assert(0);
link_values = play_PGC(vm);
break;
@@ -1478,37 +1202,38 @@ static link_t process_command(vm_t *vm, link_t link_values)
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
assert((vm->state).pgc->prev_pgc_nr != 0);
- if(set_PGC(vm, (vm->state).pgc->prev_pgc_nr))
+ if(!set_PGCN(vm, (vm->state).pgc->prev_pgc_nr))
assert(0);
link_values = play_PGC(vm);
break;
case LinkGoUpPGC:
- /* Link to GoUp??? Program Chain */
+ /* Link to GoUp Program Chain */
/* BUTTON number:data1 */
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
assert((vm->state).pgc->goup_pgc_nr != 0);
- if(set_PGC(vm, (vm->state).pgc->goup_pgc_nr))
+ if(!set_PGCN(vm, (vm->state).pgc->goup_pgc_nr))
assert(0);
link_values = play_PGC(vm);
break;
case LinkTailPGC:
- /* Link to Tail??? Program Chain */
+ /* Link to Tail of Program Chain */
/* BUTTON number:data1 */
- /* fprintf(MSG_OUT, "libdvdnav: FIXME: LinkTailPGC. What is LinkTailPGC?\n"); */
if(link_values.data1 != 0)
(vm->state).HL_BTNN_REG = link_values.data1 << 10;
link_values = play_PGC_post(vm);
break;
-
+
case LinkRSM:
{
- /* Link to Resume */
+ /* Link to Resume point */
int i;
+
/* Check and see if there is any rsm info!! */
+ assert((vm->state).rsm_vtsN);
(vm->state).domain = VTS_DOMAIN;
ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN);
- set_PGC(vm, (vm->state).rsm_pgcN);
+ set_PGCN(vm, (vm->state).rsm_pgcN);
/* These should never be set in SystemSpace and/or MenuSpace */
/* (vm->state).TTN_REG = rsm_tt; ?? */
@@ -1522,17 +1247,14 @@ static link_t process_command(vm_t *vm, link_t link_values)
if((vm->state).rsm_cellN == 0) {
assert((vm->state).cellN); /* Checking if this ever happens */
- /* assert( time/block/vobu is 0 ); */
(vm->state).pgN = 1;
link_values = play_PG(vm);
} else {
- /* assert( time/block/vobu is _not_ 0 ); */
- /* play_Cell_at_time */
- /* (vm->state).pgN = ?? this gets the righ value in play_Cell */
+ /* (vm->state).pgN = ?? this gets the righ value in set_PGN() below */
(vm->state).cellN = (vm->state).rsm_cellN;
link_values.command = PlayThis;
link_values.data1 = (vm->state).rsm_blockN;
- if(set_PGN(vm)) {
+ if(!set_PGN(vm)) {
/* Were at the end of the PGC, should not happen for a RSM */
assert(0);
link_values.command = LinkTailPGC;
@@ -1543,17 +1265,17 @@ static link_t process_command(vm_t *vm, link_t link_values)
break;
case LinkPGCN:
/* Link to Program Chain Number:data1 */
- if(set_PGC(vm, link_values.data1))
+ if(!set_PGCN(vm, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
case LinkPTTN:
- /* Link to Part of this Title Number:data1 */
+ /* Link to Part of current Title Number:data1 */
/* BUTTON number:data2 */
assert((vm->state).domain == VTS_DOMAIN);
if(link_values.data2 != 0)
(vm->state).HL_BTNN_REG = link_values.data2 << 10;
- if(set_VTS_PTT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG, link_values.data1) == -1)
+ if(!set_VTS_PTT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG, link_values.data1))
assert(0);
link_values = play_PG(vm);
break;
@@ -1585,7 +1307,7 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* Only allowed from the First Play domain(PGC) */
/* or the Video Manager domain (VMG) */
assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
- if(set_TT(vm,link_values.data1) == -1)
+ if(!set_TT(vm, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
@@ -1594,8 +1316,7 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* Only allowed from the VTS Menu Domain(VTSM) */
/* or the Video Title Set Domain(VTS) */
assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
- fprintf(MSG_OUT, "libdvdnav: FIXME: Should be able to use get_VTS_PTT here.\n");
- if(set_VTS_TT(vm,(vm->state).vtsN, link_values.data1) == -1)
+ if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
@@ -1604,9 +1325,9 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* Only allowed from the VTS Menu Domain(VTSM) */
/* or the Video Title Set Domain(VTS) */
assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
- if(set_VTS_PTT(vm,(vm->state).vtsN, link_values.data1, link_values.data2) == -1)
+ if(!set_VTS_PTT(vm, (vm->state).vtsN, link_values.data1, link_values.data2))
assert(0);
- link_values = play_PGC_PG( vm, (vm->state).pgN );
+ link_values = play_PGC_PG(vm, (vm->state).pgN);
break;
case JumpSS_FP:
@@ -1614,17 +1335,16 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* Only allowed from the VTS Menu Domain(VTSM) */
/* or the Video Manager domain (VMG) */
assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN); /* ?? */
- set_FP_PGC(vm);
+ if (!set_FP_PGC(vm))
+ assert(0);
link_values = play_PGC(vm);
break;
case JumpSS_VMGM_MENU:
/* Jump to Video Manger domain - Title Menu:data1 or any PGC in VMG */
/* Allowed from anywhere except the VTS Title domain */
- assert((vm->state).domain == VMGM_DOMAIN ||
- (vm->state).domain == VTSM_DOMAIN ||
- (vm->state).domain == FP_DOMAIN); /* ?? */
+ assert((vm->state).domain != VTS_DOMAIN); /* ?? */
(vm->state).domain = VMGM_DOMAIN;
- if(set_MENU(vm,link_values.data1) == -1)
+ if(!set_MENU(vm, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
@@ -1645,7 +1365,7 @@ static link_t process_command(vm_t *vm, link_t link_values)
fprintf(MSG_OUT, "libdvdnav: *******************************************************************\n");
#endif
- if(link_values.data1 !=0) {
+ if(link_values.data1 != 0) {
assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
(vm->state).domain = VTSM_DOMAIN;
ifoOpenNewVTSI(vm, vm->dvd, link_values.data1); /* Also sets (vm->state).vtsN */
@@ -1657,59 +1377,57 @@ static link_t process_command(vm_t *vm, link_t link_values)
/* Alien or Aliens has this != 1, I think. */
/* assert(link_values.data2 == 1); */
(vm->state).VTS_TTN_REG = link_values.data2;
- if(set_MENU(vm, link_values.data3) == -1)
+ if(!set_MENU(vm, link_values.data3))
assert(0);
link_values = play_PGC(vm);
break;
case JumpSS_VMGM_PGC:
- /* get_PGC:data1 */
- assert((vm->state).domain == VMGM_DOMAIN ||
- (vm->state).domain == VTSM_DOMAIN ||
- (vm->state).domain == FP_DOMAIN); /* ?? */
+ /* set_PGCN:data1 */
+ assert((vm->state).domain != VTS_DOMAIN); /* ?? */
(vm->state).domain = VMGM_DOMAIN;
- if(set_PGC(vm,link_values.data1) == -1)
+ if(!set_PGCN(vm, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
case CallSS_FP:
- /* saveRSMinfo:data1 */
- assert((vm->state).domain == VTS_DOMAIN); /* ?? */
- /* Must be called before domain is changed */
- saveRSMinfo(vm, link_values.data1, /* We dont have block info */ 0);
+ /* set_RSMinfo:data1 */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
+ /* Must be called before domain is changed */
+ set_RSMinfo(vm, link_values.data1, /* We dont have block info */ 0);
set_FP_PGC(vm);
link_values = play_PGC(vm);
break;
case CallSS_VMGM_MENU:
- /* get_MENU:data1 */
- /* saveRSMinfo:data2 */
- assert((vm->state).domain == VTS_DOMAIN); /* ?? */
- /* Must be called before domain is changed */
- saveRSMinfo(vm,link_values.data2, /* We dont have block info */ 0);
+ /* set_MENU:data1 */
+ /* set_RSMinfo:data2 */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
+ /* Must be called before domain is changed */
+ set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
(vm->state).domain = VMGM_DOMAIN;
- if(set_MENU(vm,link_values.data1) == -1)
+ if(!set_MENU(vm, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
case CallSS_VTSM:
- /* get_MENU:data1 */
- /* saveRSMinfo:data2 */
- assert((vm->state).domain == VTS_DOMAIN); /* ?? */
- /* Must be called before domain is changed */
- saveRSMinfo(vm,link_values.data2, /* We dont have block info */ 0);
+ /* set_MENU:data1 */
+ /* set_RSMinfo:data2 */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
+ /* Must be called before domain is changed */
+ set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
(vm->state).domain = VTSM_DOMAIN;
- if(set_MENU(vm,link_values.data1) == -1)
+ if(!set_MENU(vm, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
case CallSS_VMGM_PGC:
- /* get_PGC:data1 */
- /* saveRSMinfo:data2 */
- assert((vm->state).domain == VTS_DOMAIN); /* ?? */
- /* Must be called before domain is changed */
- saveRSMinfo(vm,link_values.data2, /* We dont have block info */ 0);
+ /* set_PGC:data1 */
+ /* set_RSMinfo:data2 */
+ assert((vm->state).domain == VTS_DOMAIN); /* ?? */
+ /* Must be called before domain is changed */
+ set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
(vm->state).domain = VMGM_DOMAIN;
- if(set_PGC(vm,link_values.data1) == -1)
+ if(!set_PGCN(vm, link_values.data1))
assert(0);
link_values = play_PGC(vm);
break;
@@ -1720,134 +1438,201 @@ static link_t process_command(vm_t *vm, link_t link_values)
}
#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: After printout starts:\n");
- vm_print_current_domain_state(vm);
- fprintf(MSG_OUT, "libdvdnav: After printout ends.\n");
+ fprintf(MSG_OUT, "libdvdnav: After printout starts:\n");
+ vm_print_current_domain_state(vm);
+ fprintf(MSG_OUT, "libdvdnav: After printout ends.\n");
#endif
}
- link_values.data2 = 1; /* there was actually a jump */
- vm->badness_counter--;
- return link_values;
+ (vm->state).blockN = link_values.data1;
+ return 1;
}
-/* Searches the TT tables, to find the current TT.
- * returns the current TT.
- * returns 0 if not found.
- */
-static int get_TT(vm_t *vm, int vtsN, int vts_ttn) {
- int i;
- int tt=0;
- for(i = 1; i <= vm->vmgi->tt_srpt->nr_of_srpts; i++) {
- if( vm->vmgi->tt_srpt->title[i - 1].title_set_nr == vtsN &&
- vm->vmgi->tt_srpt->title[i - 1].vts_ttn == vts_ttn) {
- tt=i;
- break;
- }
- }
- return tt;
-}
-static int set_TT(vm_t *vm, int tt)
-{
+/* Set functions */
+
+static int set_TT(vm_t *vm, int tt) {
assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
-
(vm->state).TTN_REG = tt;
-
return set_VTS_TT(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
vm->vmgi->tt_srpt->title[tt - 1].vts_ttn);
}
-
-static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn)
-{
- fprintf(MSG_OUT, "libdvdnav: get_VTS_TT called, testing!!! vtsN=%d, vts_ttn=%d\n", vtsN, vts_ttn);
+static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn) {
return set_VTS_PTT(vm, vtsN, vts_ttn, 1);
- /* pgcN = get_ID(vm, vts_ttn); This might return -1 */
- /*
- assert(pgcN != -1);
-
- (vm->state).TTN_REG = get_TT(*vm, vtsN, vts_ttn);
- (vm->state).VTS_TTN_REG = vts_ttn;
- (vm->state).vtsN =
- */
- /* Any other registers? */
-
- /* return set_PGC(vm, pgcN); */
}
-
-static int set_VTS_PTT(vm_t *vm, int vtsN, int /* is this really */ vts_ttn, int part)
-{
+static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) {
int pgcN, pgN, res;
(vm->state).domain = VTS_DOMAIN;
+
if(vtsN != (vm->state).vtsN)
- ifoOpenNewVTSI(vm, vm->dvd, vtsN); /* Also sets (vm->state).vtsN */
+ ifoOpenNewVTSI(vm, vm->dvd, vtsN); /* Also sets (vm->state).vtsN */
if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts) ||
(part < 1) || (part > vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts) ) {
- return S_ERR;
+ return 0;
}
pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn;
pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn;
(vm->state).TT_PGCN_REG = pgcN;
- (vm->state).PTTN_REG = pgN;
-
- (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
+ (vm->state).PTTN_REG = pgN;
+ (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
assert( (vm->state.TTN_REG) != 0 );
(vm->state).VTS_TTN_REG = vts_ttn;
- (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
+ (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */
/* Any other registers? */
- res = set_PGC(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
- (vm->state).pgN = pgN; /* Part?? */
+ res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */
+ (vm->state).pgN = pgN;
return res;
}
+static int set_FP_PGC(vm_t *vm) {
+ (vm->state).domain = FP_DOMAIN;
+ (vm->state).pgc = vm->vmgi->first_play_pgc;
+ return 1;
+}
-static int set_FP_PGC(vm_t *vm)
-{
- (vm->state).domain = FP_DOMAIN;
+static int set_MENU(vm_t *vm, int menu) {
+ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN);
+ return set_PGCN(vm, get_ID(vm, menu));
+}
- (vm->state).pgc = vm->vmgi->first_play_pgc;
+static int set_PGCN(vm_t *vm, int pgcN) {
+ pgcit_t *pgcit;
- return 0;
+ pgcit = get_PGCIT(vm);
+ assert(pgcit != NULL); /* ?? Make this return -1 instead */
+
+ if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
+#ifdef TRACE
+ fprintf(MSG_OUT, "libdvdnav: ** No such pgcN = %d\n", pgcN);
+#endif
+ return 0;
+ }
+
+ (vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc;
+ (vm->state).pgN = 1;
+
+ if((vm->state).domain == VTS_DOMAIN)
+ (vm->state).TT_PGCN_REG = pgcN;
+
+ return 1;
}
+/* Figure out the correct pgN from the cell and update (vm->state). */
+static int set_PGN(vm_t *vm) {
+ int new_pgN = 0;
+
+ while(new_pgN < (vm->state).pgc->nr_of_programs
+ && (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN])
+ new_pgN++;
+
+ if(new_pgN == (vm->state).pgc->nr_of_programs) /* We are at the last program */
+ if((vm->state).cellN > (vm->state).pgc->nr_of_cells)
+ return 0; /* We are past the last cell */
+
+ (vm->state).pgN = new_pgN;
+
+ if((vm->state).domain == VTS_DOMAIN) {
+ playback_type_t *pb_ty;
+ if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
+ return 0; /* ?? */
+ pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
+ if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) {
+ int dummy;
+#if 0
+ /* TTN_REG can't be trusted to have a correct value here... */
+ vts_ptt_srpt_t *ptt_srpt = vtsi->vts_ptt_srpt;
+ assert((vm->state).VTS_TTN_REG <= ptt_srpt->nr_of_srpts);
+ assert(get_PGCN() == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgcn);
+ assert(1 == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgn);
+#endif
+ vm_get_current_title_part(vm, &dummy, &(vm->state).pgN);
+ (vm->state).PTTN_REG = (vm->state).pgN;
+ } else {
+ /* FIXME: Handle RANDOM or SHUFFLE titles. */
+ fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n");
+ }
+ }
+ return 1;
+}
-static int set_MENU(vm_t *vm, int menu)
-{
- assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN);
- return set_PGC(vm, get_ID(vm, menu));
+/* Must be called before domain is changed (set_PGCN()) */
+static void set_RSMinfo(vm_t *vm, int cellN, int blockN) {
+ int i;
+
+ if(cellN) {
+ (vm->state).rsm_cellN = cellN;
+ (vm->state).rsm_blockN = blockN;
+ } else {
+ (vm->state).rsm_cellN = (vm->state).cellN;
+ (vm->state).rsm_blockN = blockN;
+ }
+ (vm->state).rsm_vtsN = (vm->state).vtsN;
+ (vm->state).rsm_pgcN = get_PGCN(vm);
+
+ /* assert((vm->state).rsm_pgcN == (vm->state).TT_PGCN_REG); for VTS_DOMAIN */
+
+ for(i = 0; i < 5; i++) {
+ (vm->state).rsm_regs[i] = (vm->state).registers.SPRM[4 + i];
+ }
+}
+
+
+/* Get functions */
+
+/* Searches the TT tables, to find the current TT.
+ * returns the current TT.
+ * returns 0 if not found.
+ */
+static int get_TT(vm_t *vm, int vtsN, int vts_ttn) {
+ int i;
+ int tt=0;
+
+ for(i = 1; i <= vm->vmgi->tt_srpt->nr_of_srpts; i++) {
+ if( vm->vmgi->tt_srpt->title[i - 1].title_set_nr == vtsN &&
+ vm->vmgi->tt_srpt->title[i - 1].vts_ttn == vts_ttn) {
+ tt=i;
+ break;
+ }
+ }
+ return tt;
}
/* Search for entry_id match of the PGC Category in the current VTS PGCIT table.
* Return pgcN based on entry_id match.
*/
-static int get_ID(vm_t *vm, int id)
-{
+static int get_ID(vm_t *vm, int id) {
int pgcN, i;
pgcit_t *pgcit;
/* Relies on state to get the correct pgcit. */
pgcit = get_PGCIT(vm);
assert(pgcit != NULL);
+#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: ** Searching for menu (0x%x) entry PGC\n", id);
+#endif
/* Force high bit set. */
id |=0x80;
+
/* Get menu/title */
for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
if( (pgcit->pgci_srp[i].entry_id) == id) {
pgcN = i + 1;
+#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: Found menu.\n");
+#endif
return pgcN;
}
}
+#ifdef TRACE
fprintf(MSG_OUT, "libdvdnav: ** No such id/menu (0x%02x) entry PGC\n", id & 0x7f);
for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
if ( (pgcit->pgci_srp[i].entry_id & 0x80) == 0x80) {
@@ -1855,42 +1640,15 @@ static int get_ID(vm_t *vm, int id)
pgcit->pgci_srp[i].entry_id & 0x7f);
}
}
- return -1; /* error */
-}
-
-/* Set the vm->state to pgcN.
- * Returns success/failure.
- */
-static int set_PGC(vm_t *vm, int pgcN)
-{
- /* FIXME: Keep this up to date with the ogle people */
- pgcit_t *pgcit;
-
- pgcit = get_PGCIT(vm);
-
- assert(pgcit != NULL); /* ?? Make this return -1 instead */
- if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) {
- fprintf(MSG_OUT, "libdvdnav: ** No such pgcN = %d\n", pgcN);
- return -1; /* error */
- }
-
- /* (vm->state).pgcN = pgcN; */
- (vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc;
- (vm->state).pgN = 1;
-
- if((vm->state).domain == VTS_DOMAIN)
- (vm->state).TT_PGCN_REG = pgcN;
-
- return 0;
+#endif
+ return 0; /* error */
}
-static int get_PGCN(vm_t *vm)
-{
+static int get_PGCN(vm_t *vm) {
pgcit_t *pgcit;
int pgcN = 1;
pgcit = get_PGCIT(vm);
-
assert(pgcit != NULL);
while(pgcN <= pgcit->nr_of_pgci_srp) {
@@ -1898,99 +1656,13 @@ static int get_PGCN(vm_t *vm)
return pgcN;
pgcN++;
}
- fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Trying to find pgcN in domain %d \n",
+ fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n",
(vm->state).domain);
/* assert(0);*/
- return -1; /* error */
-}
-
-int vm_get_video_aspect(vm_t *vm)
-{
- int aspect = 0;
-
- switch ((vm->state).domain) {
- case VTS_DOMAIN:
- aspect = vm->vtsi->vtsi_mat->vts_video_attr.display_aspect_ratio;
- break;
- case VTSM_DOMAIN:
- aspect = vm->vtsi->vtsi_mat->vtsm_video_attr.display_aspect_ratio;
- break;
- case VMGM_DOMAIN:
- aspect = vm->vmgi->vmgi_mat->vmgm_video_attr.display_aspect_ratio;
- break;
- default:
- fprintf(MSG_OUT, "libdvdnav: vm_get_video_aspect failed. Unknown domain %d\n",
- (vm->state).domain);
- assert(0);
- break;
- }
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: get_video_aspect:aspect=%d\n",aspect);
-#endif
- assert(aspect == 0 || aspect == 3);
- (vm->state).registers.SPRM[14] &= ~(0x3 << 10);
- (vm->state).registers.SPRM[14] |= aspect << 10;
-
- return aspect;
-}
-
-int vm_get_video_scale_permission(vm_t *vm)
-{
- int permission = 0;
-
- if((vm->state).domain == VTS_DOMAIN) {
- permission = vm->vtsi->vtsi_mat->vts_video_attr.permitted_df;
- } else if((vm->state).domain == VTSM_DOMAIN) {
- permission = vm->vtsi->vtsi_mat->vtsm_video_attr.permitted_df;
- } else if((vm->state).domain == VMGM_DOMAIN) {
- permission = vm->vmgi->vmgi_mat->vmgm_video_attr.permitted_df;
- }
-#ifdef TRACE
- fprintf(MSG_OUT, "libdvdnav: get_video_scale_permission:permission=%d\n",permission);
-#endif
-
- return permission;
-}
-
-static void ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN)
-{
- if((vm->state).vtsN == vtsN) {
- return; /* We alread have it */
- }
-
- if(vm->vtsi != NULL)
- ifoClose(vm->vtsi);
-
- vm->vtsi = ifoOpenVTSI(dvd, vtsN);
- if(vm->vtsi == NULL) {
- fprintf(MSG_OUT, "libdvdnav: ifoOpenVTSI failed - CRASHING!!!\n");
- assert(0);
- }
- if(!ifoRead_VTS_PTT_SRPT(vm->vtsi)) {
- fprintf(MSG_OUT, "libdvdnav: ifoRead_VTS_PTT_SRPT failed - CRASHING!!!\n");
- assert(0);
- }
- if(!ifoRead_PGCIT(vm->vtsi)) {
- fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCIT failed - CRASHING!!!\n");
- assert(0);
- }
- if(!ifoRead_PGCI_UT(vm->vtsi)) {
- fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCI_UT failed - CRASHING!!!\n");
- assert(0);
- }
- if(!ifoRead_VOBU_ADMAP(vm->vtsi)) {
- fprintf(MSG_OUT, "libdvdnav: ifoRead_VOBU_ADMAP vtsi failed - CRASHING\n");
- assert(0);
- }
- if(!ifoRead_TITLE_VOBU_ADMAP(vm->vtsi)) {
- fprintf(MSG_OUT, "libdvdnav: ifoRead_TITLE_VOBU_ADMAP vtsi failed - CRASHING\n");
- assert(0);
- }
- (vm->state).vtsN = vtsN;
+ return 0; /* error */
}
-static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang)
-{
+static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang) {
int i;
if(h == NULL || h->pgci_ut == NULL) {
@@ -2008,13 +1680,12 @@ static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang)
(char)(h->pgci_ut->lu[0].lang_code >> 8),
(char)(h->pgci_ut->lu[0].lang_code & 0xff));
fprintf(MSG_OUT, "libdvdnav: Menu Languages available: ");
- for(i=0;i< h->pgci_ut->nr_of_lus;i++) {
+ for(i = 0; i < h->pgci_ut->nr_of_lus; i++) {
fprintf(MSG_OUT, "%c%c ",
- (char)(h->pgci_ut->lu[0].lang_code >> 8),
- (char)(h->pgci_ut->lu[0].lang_code & 0xff));
+ (char)(h->pgci_ut->lu[i].lang_code >> 8),
+ (char)(h->pgci_ut->lu[i].lang_code & 0xff));
}
fprintf(MSG_OUT, "\n");
-
i = 0; /* error? */
}
@@ -2047,8 +1718,40 @@ static pgcit_t* get_PGCIT(vm_t *vm) {
return pgcit;
}
+
+/* Debug functions */
+
+#ifdef TRACE
+void vm_position_print(vm_t *vm, vm_position_t *position) {
+ fprintf(MSG_OUT, "libdvdnav: But=%x Spu=%x Aud=%x Ang=%x Hop=%x vts=%x dom=%x cell=%x cell_restart=%x cell_start=%x still=%x block=%x\n",
+ position->button,
+ position->spu_channel,
+ position->audio_channel,
+ position->angle_channel,
+ position->hop_channel,
+ position->vts,
+ position->domain,
+ position->cell,
+ position->cell_restart,
+ position->cell_start,
+ position->still,
+ position->block);
+}
+#endif
+
+
/*
* $Log: vm.c,v $
+ * Revision 1.13 2003/02/20 16:02:01 mroi
+ * syncing to libdvdnav 0.1.5 and modifying input plugin accordingly
+ * quoting the ChangeLog:
+ * * some bugfixes
+ * * code cleanup
+ * * build process polishing
+ * * more sensible event order in get_next_block to ensure useful event delivery
+ * * VOBU level resume
+ * * fixed: seeking in a multiangle feature briefly showed the wrong angle
+ *
* Revision 1.12 2003/02/11 16:28:47 heikos
* freebsd compile fix
*