changeset 1:1c897db44135 src

first removal of dvdnav-specific code
author nicodvb
date Sun, 01 Jun 2008 14:51:25 +0000
parents 427b7da5cbdb
children a286eb135a1a
files FELLOWSHIP.map README.MAP dvd_types.h dvdnav.c dvdnav.h dvdnav_events.h dvdnav_internal.h highlight.c navigation.c read_cache.c read_cache.h remap.c remap.h searching.c settings.c vm/Makefile.am vm/decoder.c vm/decoder.h vm/vm.c vm/vm.h vm/vmcmd.c vm/vmcmd.h
diffstat 22 files changed, 0 insertions(+), 8514 deletions(-) [+]
line wrap: on
line diff
--- a/FELLOWSHIP.map	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-# The Lord of the Rings: Fellowship of the Ring (Widescreen Theatrical Release)
-domain 8, title 1, program 1, start 0x0000, end 0x1f0a   # Introduction
-
-# history of middle earth
-#domain 2, title 1, program 1, start 0x9cba, end 0xcea4   # violence/war
-#domain 2, title 1, program 1, start 0xf018, end 0x1272c  # violence/war
-domain 2, title 1, program 1, start 0x11ff3, end 0x1272c # gore
-#domain 2, title 1, program 1, start 0x173f1, end 0x185d6 # violence/death
-
-# hobbiton 
-domain 2, title 1, program 2, start 0x30373, end 0x31946 # vices/smoking
-domain 2, title 1, program 2, start 0x32942, end 0x34426 # vices/smoking
-domain 2, title 1, program 2, start 0x34895, end 0x34ad1 # vices/smoking
-domain 2, title 1, program 2, start 0x3965c, end 0x39d7c # vices/smoking
-
-# bag end
-domain 2, title 1, program 3, start 0x40288, end 0x412de # vices/drinking/talk
-domain 2, title 1, program 3, start 0x4cfbe, end 0x4f955 # vices/smoking
-
-# party
-domain 2, title 1, program 4, start 0x53ee0, end 0x54396 # vices/drinking
-domain 2, title 1, program 4, start 0x58851, end 0x5ae3d # imitative/theft
-domain 2, title 1, program 4, start 0x5cd0a, end 0x5e216 # jump 
-
-# gandalf departs
-domain 2, title 1, program 6, start 0x7f05d, end 0x7f1b3 # jump
-domain 2, title 1, program 6, start 0x7f51a, end 0x834a7 # vices/smoking
-
-# research
-domain 2, title 1, program 7, start 0x8e6e8, end 0x8e9d7 # vices/smoking
-
-# hobbiton
-domain 2, title 1, program 8, start 0x98f49, end 0x990ba # jump
-domain 2, title 1, program 8, start 0xa0ad1, end 0xa17ac # jump
-domain 2, title 1, program 8, start 0xa9e32, end 0xaaa70 # violence/torture
-domain 2, title 1, program 8, start 0xabc6c, end 0xabd92 # violence
-
-# orthanc
-domain 2, title 1, program 9, start 0xd50b7, end 0xd87f9 # violence
-domain 2, title 1, program 9, start 0xd8e49, end 0xda611 # violence
-
-# farmer maggot
-domain 2, title 1, program 10, start 0xde856, end 0xdeb07 # jump
-domain 2, title 1, program 10, start 0xe4cfe, end 0xe50b3 # gore/excrement
-domain 2, title 1, program 10, start 0xebba3, end 0xebf93 # gore/blood
-domain 2, title 1, program 10, start 0xed222, end 0xeda7e # gore/insects
-
-# buckleberry ferry
-domain 2, title 1, program 11, start 0xf6d77, end 0xf83f8 # jump
-
-# prancing pony in bree
-domain 2, title 1, program 12, start 0x10945e, end 0x10a2f2 # vices/drinking/rolemodel
-domain 2, title 1, program 12, start 0x10c103, end 0x10c417 # vices/smoking
-domain 2, title 1, program 12, start 0x10c934, end 0x10cb44 # vices/smoking
-# 10c934
-# 10c9b4
-# 10ca3c
-# 10cad6
-# 10cb44
-# 10cbb4
-domain 2, title 1, program 12, start 0x10ddab, end 0x10e0f2 # vices/smoking
-domain 2, title 1, program 12, start 0x10e1df, end 0x10e411 # vices/drinking
-
-# ring wraiths in bree
-domain 2, title 1, program 13, start 0x117853, end 0x117f6e # violence
-domain 2, title 1, program 13, start 0x117853, end 0x117f6e # gore/crushing
-domain 2, title 1, program 13, start 0x11b2b3, end 0x11bffc # violence
-
-# weathertop
-#domain 2, title 1, program 15, start 0x13b85b, end 0x141b38 # violence
-domain 2, title 1, program 15, start 0x14093a, end 0x141063 # gore/stabbing
-domain 2, title 1, program 15, start 0x142555, end 0x1466e9 # violence
-
-# isengard
-domain 2, title 1, program 16, start 0x152a28, end 0x1549fb # violence
-domain 2, title 1, program 16, start 0x152a28, end 0x1549fb # gore
-
-# the ford
-domain 2, title 1, program 17, start 0x173dbe, end 0x1748a6 # violence
-
-# rivendell
-domain 2, title 1, program 18, start 0x179793, end 0x17a667 # vices/smoking
-domain 2, title 1, program 18, start 0x17c452, end 0x17eab6 # violence
-
-# rivendell
-domain 2, title 1, program 20, start 0x19caaf, end 0x19db12 # violence
-
-# tomb of isildur
-domain 2, title 1, program 21, start 0x1a69ae, end 0x1a6a3d # gore/blood
-
-# rivendell
-domain 2, title 1, program 22, start 0x1b298b, end 0x1b2bae # kiss
-
-# rivendell
-domain 2, title 1, program 24, start 0x1d8253, end 0x1d8f5d # horror/posession
-
-# on the road south
-domain 2, title 1, program 25, start 0x1e2fc2, end 0x1e31b8 # vices/smoking
-
-# at the entrance to moria
-domain 2, title 1, program 27, start 0x214bdd, end 0x214fcc # gore/skeletons
-domain 2, title 1, program 27, start 0x2157d9, end 0x216731 # gore/skeletons
-domain 2, title 1, program 27, start 0x217ba6, end 0x21cdb4 # violence
-
-# moria
-#domain 2, title 1, program 28, start 0x22173d, end 0x221e58 # gore/skeletons
-#domain 2, title 1, program 28, start 0x222e0b, end 0x223345 # gore/skeletons
-domain 2, title 1, program 28, start 0x22173d, end 0x223345 # gore/skeletons
-domain 2, title 1, program 28, start 0x2239e2, end 0x223e8c # gore/skeletons
-domain 2, title 1, program 28, start 0x22589f, end 0x2259bf # vices/smoking
-
-# balin's tomb
-domain 2, title 1, program 29, start 0x234abb, end 0x234dd0 # gore/skeletons
-domain 2, title 1, program 29, start 0x2352ed, end 0x2361d7 # gore/skeletons
-domain 2, title 1, program 29, start 0x23898b, end 0x23955c # gore/skeletons
-domain 2, title 1, program 29, start 0x23b467, end 0x23db2b # gore/skeletons
-#domain 2, title 1, program 29, start 0x247360, end 0x25e24b # violence
-domain 2, title 1, program 29, start 0x2483b6, end 0x248b62 # gore/impalement
-domain 2, title 1, program 29, start 0x24a606, end 0x24a9f3 # gore/headshot
-domain 2, title 1, program 29, start 0x24acd8, end 0x24ae7e # gore/decapitation
-domain 2, title 1, program 29, start 0x24d708, end 0x24d88f # gore/bashing
-domain 2, title 1, program 29, start 0x25013a, end 0x250501 # gore/impalement
-domain 2, title 1, program 29, start 0x2540a0, end 0x254507 # jump
-domain 2, title 1, program 29, start 0x2560b3, end 0x256423 # gore/impalement
-domain 2, title 1, program 29, start 0x258152, end 0x258459 # gore/impalement
-domain 2, title 1, program 29, start 0x258152, end 0x258459 # gore/impalement
-
-# the bridge
-#domain 2, title 1, program 30, start 0x274235, end 0x275e59 # violence
-domain 2, title 1, program 30, start 0x2744c6, end 0x274a5e # gore/headshot
-domain 2, title 1, program 30, start 0x275661, end 0x275e59 # violence/death
-domain 2, title 1, program 30, start 0x289d2a, end 0x28a066 # gore/falling
-
-# lothlorien
-domain 2, title 1, program 32, start 0x2be304, end 0x2beb1d # violence
-domain 2, title 1, program 32, start 0x2c5d59, end 0x2c9a40 # horror/posession
-#domain 2, title 1, program 32, start 0x2c5d59, end 0x2c9e41 # horror/posession
-
-# parth galen
-domain 2, title 1, program 36, start 0x2fa317, end 0x2fb0b0 # violence
-
-# parth galen w/ orcs
-domain 2, title 1, program 37, start 0x30c8cb, end 0x313054 # violence
-domain 2, title 1, program 37, start 0x310428, end 0x313054 # gore/impalement
-#domain 2, title 1, program 37, start 0x317f45, end 0x332a52 # violence
-domain 2, title 1, program 37, start 0x322d8b, end 0x328f4d # gore/impalement
-domain 2, title 1, program 37, start 0x32f2a4, end 0x330731 # gore/impalement
-domain 2, title 1, program 37, start 0x330b3b, end 0x330c4d # gore/blood
-domain 2, title 1, program 37, start 0x331c4e, end 0x332a52 # gore/dismemberment
-domain 2, title 1, program 37, start 0x331c4e, end 0x332a52 # gore/decapitation
-
-# death of boromir
-domain 2, title 1, program 38, start 0x33322f, end 0x33c10c # gore/bodies
-domain 2, title 1, program 38, start 0x33b558, end 0x33c10c # horror/death
-
-# to the eastern shore
-domain 2, title 1, program 39, start 0x34a25b, end 0x34c1e3 # horror/drowning
-
-
-
-
-
-
--- a/README.MAP	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-Contents
-
-WHAT ARE MAP FILES
-HOWTO
-FINDING MAP FILES
-WHOM TO BLAME
-
-WHAT ARE MAP FILES
-==================
-
-Map files are an experimental feature that lets you customize the way
-you watch DVDs.  If you are opposed to violence, are sickened by gore,
-or would rather your two year old didn't ask you just yet why that 
-woman in the movie was naked, you might want to create a map file.  
-
-Map files identify sections of the movie that will be skipped during
-playback.  You can skip any section you like with the only restriction
-(right now) that the movie player must play at least the last VOBU 
-(about a fifth of a second) of each chapter in the movie in order
-to detect chapter changes correctly.  
-
-Included with this patch is an example map file that describes most
-of the potentially objectionable content in the new "The Lord of the 
-Rings" DVD.  I've added a comment after each block that identifies 
-what content it contains so that you can customize the file to your
-preferences.  The map file looks something like this:
-
- # The Lord of the Rings: Fellowship of the Ring 
- # (Widescreen Theatrical Release)
- debug
- domain 8, title 1, program 1, start 0x0000, end 0x1f0a   # Introduction
-
- # history of middle earth
- #domain 2, title 1, program 1, start 0x9cba, end 0xcea4   # violence/war
- #domain 2, title 1, program 1, start 0xf018, end 0x1272c  # violence/war
- domain 2, title 1, program 1, start 0x11ff3, end 0x1272c # gore
- #domain 2, title 1, program 1, start 0x173f1, end 0x185d6 # violence/death
-
-Place the map file in your .xine directory to enable the selected
-cuts as follows:
-
-    cp FELLOWSHIP.map ~/.xine
-
-The debug command tells the map code that you would like to see the
-VOBU numbers as the movie is playing.  Comment out this line to hide
-this output.  The remaining lines are all either comments or blocks.
-Each block has a start and an end, and whenever Xine tries to load
-a VOBU between the start and end, it will be redirected to the end
-block instead.
-
-
-HOWTO
-=====
-
-To create your own map files you would create a new map file using the
-title of the disk as the filename, and add the debug line to it.  The
-map file should be placed in your '.xine' directory and have a '.map'
-extension added.  For example "The Lord Of The Rings" map must be stored 
-in the file ~/.xine/FELLOWSHIP.map
-
-After you create the file with the DEBUG line you will see output that
-looks like this in window where you started Xine:
-
-   FELLOWSHIP: domain 8, title 1, program 1, start 2205, next 22a8
-   FELLOWSHIP: domain 8, title 1, program 1, start 22a8, next 234b
-   FELLOWSHIP: domain 8, title 1, program 1, start 234b, next 23eb
-   FELLOWSHIP: domain 8, title 1, program 1, start 23eb, next 248a
-
-Each line represents one VOBU, and the start and end addresses match
-the start and end addresses that you should place in the map file
-if you want to skip that block.  If you want to skip multiple blocks
-you would just add one line with the start address of the first block
-to skip, and the end address of the last block to skip.  For example
-to skip these four blocks you would add the following line to your
-map file:
-
-   domain 8, title 1, program 1, start 0x2205, end 0x248a # 4 blocks
-
-Xine uses a buffered input chain so that if you pause the viewer you
-won't find the same VOBU being displayed on the terminal as is 
-currently on the screen.  In my testing the correct VOBU to use if
-you pause exactly on the section you want to cut will be about five
-or six lines above the last one printed to the screen.  Replay the
-scene with the deletion to see if you caught the correct blocks.
-
-
-WHERE TO FIND MAP FILES
-=======================
-
-If you create a map file for a new movie, please send it to me.  If
-there is widespread interest I'll put up a site where map files can
-be located and downloaded.
-
-
-WHOM TO BLAME
-=============
-
-If the patch doesn't work for you (and you want it to) you can contact
-me at 'kevin_smathers@hp.com'.  
-
-If the patch works for you and you don't want it to, remember that 
-not everyone in the world has the same needs.  The freedom to censor 
-movies in our own homes is quite different from the government 
-interfering into libraries and other public forums to censor movies 
-for us.
--- a/dvd_types.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Björn Englund, Håkan Hjort
- *
- * This file is part of libdvdnav, a DVD navigation library. It is a modified
- * file originally part of the Ogle DVD player project.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-/*
- * Various useful structs and enums for DVDs.
- */
-
-#ifndef DVD_H_INCLUDED
-#define DVD_H_INCLUDED
-
-/*
- * DVD Menu ID
- * (see dvdnav_menu_call())
- */
-typedef enum {
-  /* When used in VTS domain, DVD_MENU_Escape behaves like DVD_MENU_Root,
-   * but from within a menu domain, DVD_MENU_Escape resumes playback. */
-  DVD_MENU_Escape     = 0,
-  DVD_MENU_Title      = 2,
-  DVD_MENU_Root       = 3,
-  DVD_MENU_Subpicture = 4,
-  DVD_MENU_Audio      = 5,
-  DVD_MENU_Angle      = 6,
-  DVD_MENU_Part       = 7
-} DVDMenuID_t;
-
-
-/*
- * Structure containing info on highlight areas
- * (see dvdnav_get_highlight_area())
- */
-typedef struct {
-  uint32_t palette;     /* The CLUT entries for the highlight palette 
-			   (4-bits per entry -> 4 entries) */
-  uint16_t sx,sy,ex,ey; /* The start/end x,y positions */
-  uint32_t pts;         /* Highlight PTS to match with SPU */
-
-  /* button number for the SPU decoder/overlaying engine */
-  uint32_t buttonN;
-} dvdnav_highlight_area_t;
-
-
-/* the following types are currently unused */
-
-#if 0
-
-/* Domain */
-typedef enum {
-  DVD_DOMAIN_FirstPlay,  /* First Play Domain */
-  DVD_DOMAIN_VMG,        /* Video Manager Domain */
-  DVD_DOMAIN_VTSMenu,    /* Video Title Set Menu Domain */
-  DVD_DOMAIN_VTSTitle,   /* Video Title Set Domain */
-  DVD_DOMAIN_Stop        /* Stop Domain */
-} DVDDomain_t;
-
-/* User operation permissions */
-typedef enum {
-  UOP_FLAG_TitleOrTimePlay            = 0x00000001, 
-  UOP_FLAG_ChapterSearchOrPlay        = 0x00000002, 
-  UOP_FLAG_TitlePlay                  = 0x00000004, 
-  UOP_FLAG_Stop                       = 0x00000008,  
-  UOP_FLAG_GoUp                       = 0x00000010,
-  UOP_FLAG_TimeOrChapterSearch        = 0x00000020, 
-  UOP_FLAG_PrevOrTopPGSearch          = 0x00000040,  
-  UOP_FLAG_NextPGSearch               = 0x00000080,   
-  UOP_FLAG_ForwardScan                = 0x00000100,  
-  UOP_FLAG_BackwardScan               = 0x00000200,
-  UOP_FLAG_TitleMenuCall              = 0x00000400,
-  UOP_FLAG_RootMenuCall               = 0x00000800,
-  UOP_FLAG_SubPicMenuCall             = 0x00001000,
-  UOP_FLAG_AudioMenuCall              = 0x00002000,
-  UOP_FLAG_AngleMenuCall              = 0x00004000,
-  UOP_FLAG_ChapterMenuCall            = 0x00008000,
-  UOP_FLAG_Resume                     = 0x00010000,
-  UOP_FLAG_ButtonSelectOrActivate     = 0x00020000,
-  UOP_FLAG_StillOff                   = 0x00040000,
-  UOP_FLAG_PauseOn                    = 0x00080000,
-  UOP_FLAG_AudioStreamChange          = 0x00100000,
-  UOP_FLAG_SubPicStreamChange         = 0x00200000,
-  UOP_FLAG_AngleChange                = 0x00400000,
-  UOP_FLAG_KaraokeAudioPresModeChange = 0x00800000,
-  UOP_FLAG_VideoPresModeChange        = 0x01000000 
-} DVDUOP_t;
-
-/* Parental Level */
-typedef enum {
-  DVD_PARENTAL_LEVEL_1 = 1,
-  DVD_PARENTAL_LEVEL_2 = 2,
-  DVD_PARENTAL_LEVEL_3 = 3,
-  DVD_PARENTAL_LEVEL_4 = 4,
-  DVD_PARENTAL_LEVEL_5 = 5,
-  DVD_PARENTAL_LEVEL_6 = 6,
-  DVD_PARENTAL_LEVEL_7 = 7,
-  DVD_PARENTAL_LEVEL_8 = 8,
-  DVD_PARENTAL_LEVEL_None = 15
-} DVDParentalLevel_t;
-
-/* Language ID (ISO-639 language code) */
-typedef uint16_t DVDLangID_t;
-
-/* Country ID (ISO-3166 country code) */
-typedef uint16_t DVDCountryID_t;
-
-/* Register */
-typedef uint16_t DVDRegister_t;
-typedef enum {
-  DVDFalse = 0,
-  DVDTrue = 1
-} DVDBool_t; 
-typedef DVDRegister_t DVDGPRMArray_t[16];
-typedef DVDRegister_t DVDSPRMArray_t[24];
-
-/* Navigation */
-typedef int DVDStream_t;
-typedef int DVDPTT_t;
-typedef int DVDTitle_t;
-
-/* Angle number (1-9 or default?) */
-typedef int DVDAngle_t;
-
-/* Timecode */
-typedef struct {
-  uint8_t Hours;
-  uint8_t Minutes;
-  uint8_t Seconds;
-  uint8_t Frames;
-} DVDTimecode_t;
-
-/* Subpicture stream number (0-31,62,63) */
-typedef int DVDSubpictureStream_t;  
-
-/* Audio stream number (0-7, 15(none)) */
-typedef int DVDAudioStream_t;  
-
-/* The audio application mode */
-typedef enum {
-  DVD_AUDIO_APP_MODE_None     = 0,
-  DVD_AUDIO_APP_MODE_Karaoke  = 1,
-  DVD_AUDIO_APP_MODE_Surround = 2,
-  DVD_AUDIO_APP_MODE_Other    = 3
-} DVDAudioAppMode_t;
-
-/* The audio format */
-typedef enum {
-  DVD_AUDIO_FORMAT_AC3       = 0,
-  DVD_AUDIO_FORMAT_MPEG1     = 1,
-  DVD_AUDIO_FORMAT_MPEG1_DRC = 2,
-  DVD_AUDIO_FORMAT_MPEG2     = 3,
-  DVD_AUDIO_FORMAT_MPEG2_DRC = 4,
-  DVD_AUDIO_FORMAT_LPCM      = 5,
-  DVD_AUDIO_FORMAT_DTS       = 6,
-  DVD_AUDIO_FORMAT_SDDS      = 7,
-  DVD_AUDIO_FORMAT_Other     = 8
-} DVDAudioFormat_t;
-
-/* Audio language extension */
-typedef enum {
-  DVD_AUDIO_LANG_EXT_NotSpecified       = 0,
-  DVD_AUDIO_LANG_EXT_NormalCaptions     = 1,
-  DVD_AUDIO_LANG_EXT_VisuallyImpaired   = 2,
-  DVD_AUDIO_LANG_EXT_DirectorsComments1 = 3,
-  DVD_AUDIO_LANG_EXT_DirectorsComments2 = 4
-} DVDAudioLangExt_t;
-
-/* Subpicture language extension */
-typedef enum {
-  DVD_SUBPICTURE_LANG_EXT_NotSpecified  = 0,
-  DVD_SUBPICTURE_LANG_EXT_NormalCaptions  = 1,
-  DVD_SUBPICTURE_LANG_EXT_BigCaptions  = 2,
-  DVD_SUBPICTURE_LANG_EXT_ChildrensCaptions  = 3,
-  DVD_SUBPICTURE_LANG_EXT_NormalCC  = 5,
-  DVD_SUBPICTURE_LANG_EXT_BigCC  = 6,
-  DVD_SUBPICTURE_LANG_EXT_ChildrensCC  = 7,
-  DVD_SUBPICTURE_LANG_EXT_Forced  = 9,
-  DVD_SUBPICTURE_LANG_EXT_NormalDirectorsComments  = 13,
-  DVD_SUBPICTURE_LANG_EXT_BigDirectorsComments  = 14,
-  DVD_SUBPICTURE_LANG_EXT_ChildrensDirectorsComments  = 15,
-} DVDSubpictureLangExt_t;  
-
-/* Karaoke Downmix mode */
-typedef enum {
-  DVD_KARAOKE_DOWNMIX_0to0 = 0x0001,
-  DVD_KARAOKE_DOWNMIX_1to0 = 0x0002,
-  DVD_KARAOKE_DOWNMIX_2to0 = 0x0004,
-  DVD_KARAOKE_DOWNMIX_3to0 = 0x0008,
-  DVD_KARAOKE_DOWNMIX_4to0 = 0x0010,
-  DVD_KARAOKE_DOWNMIX_Lto0 = 0x0020,
-  DVD_KARAOKE_DOWNMIX_Rto0 = 0x0040,
-  DVD_KARAOKE_DOWNMIX_0to1 = 0x0100,
-  DVD_KARAOKE_DOWNMIX_1to1 = 0x0200,
-  DVD_KARAOKE_DOWNMIX_2to1 = 0x0400,
-  DVD_KARAOKE_DOWNMIX_3to1 = 0x0800,
-  DVD_KARAOKE_DOWNMIX_4to1 = 0x1000,
-  DVD_KARAOKE_DOWNMIX_Lto1 = 0x2000,
-  DVD_KARAOKE_DOWNMIX_Rto1 = 0x4000
-} DVDKaraokeDownmix_t;
-typedef int DVDKaraokeDownmixMask_t;
-
-/* Display mode */
-typedef enum {
-  DVD_DISPLAY_MODE_ContentDefault = 0,
-  DVD_DISPLAY_MODE_16x9 = 1,
-  DVD_DISPLAY_MODE_4x3PanScan = 2,
-  DVD_DISPLAY_MODE_4x3Letterboxed = 3  
-} DVDDisplayMode_t;
-
-/* Audio attributes */
-typedef struct {
-  DVDAudioAppMode_t     AppMode;
-  DVDAudioFormat_t      AudioFormat;
-  DVDLangID_t           Language;
-  DVDAudioLangExt_t     LanguageExtension;
-  DVDBool_t             HasMultichannelInfo;
-  DVDAudioSampleFreq_t  SampleFrequency;
-  DVDAudioSampleQuant_t SampleQuantization;
-  DVDChannelNumber_t    NumberOfChannels;
-} DVDAudioAttributes_t;
-typedef int DVDAudioSampleFreq_t;
-typedef int DVDAudioSampleQuant_t;
-typedef int DVDChannelNumber_t;
-
-/* Subpicture attributes */
-typedef enum {
-  DVD_SUBPICTURE_TYPE_NotSpecified = 0,
-  DVD_SUBPICTURE_TYPE_Language     = 1,
-  DVD_SUBPICTURE_TYPE_Other        = 2
-} DVDSubpictureType_t;
-typedef enum {
-  DVD_SUBPICTURE_CODING_RunLength = 0,
-  DVD_SUBPICTURE_CODING_Extended  = 1,
-  DVD_SUBPICTURE_CODING_Other     = 2
-} DVDSubpictureCoding_t;
-typedef struct {
-  DVDSubpictureType_t    Type;
-  DVDSubpictureCoding_t  CodingMode;
-  DVDLangID_t            Language;
-  DVDSubpictureLangExt_t LanguageExtension;
-} DVDSubpictureAttributes_t;
-
-/* Video attributes */
-typedef struct {
-  DVDBool_t PanscanPermitted;
-  DVDBool_t LetterboxPermitted;
-  int AspectX;
-  int AspectY;
-  int FrameRate;
-  int FrameHeight;
-  DVDVideoCompression_t Compression;
-  DVDBool_t Line21Field1InGop;
-  DVDBool_t Line21Field2InGop;
-  int more_to_come;
-} DVDVideoAttributes_t;
-typedef int DVDVideoCompression_t;
-
-#endif
-
-#endif /* DVD_H_INCLUDED */
--- a/dvdnav.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1165 +0,0 @@
-/* 
- * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/*
-#define LOG_DEBUG
-*/
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <limits.h>
-#include <string.h>
-#include <sys/time.h>
-#include "dvd_types.h"
-#include "dvd_reader.h"
-#include "nav_types.h"
-#include "ifo_types.h" /* For vm_cmd_t */
-#include "remap.h"
-#include "vm/decoder.h"
-#include "vm/vm.h"
-#include "dvdnav.h"
-#include "dvdnav_events.h"
-#include "dvdnav_internal.h"
-#include "read_cache.h"
-#include "nav_read.h"
-#include "remap.h"
-
-static dvdnav_status_t dvdnav_clear(dvdnav_t * this) {
-  /* clear everything except file, vm, mutex, readahead */
-
-  pthread_mutex_lock(&this->vm_lock);
-  if (this->file) DVDCloseFile(this->file);
-  this->file = NULL;
-
-  memset(&this->pci,0,sizeof(this->pci));
-  memset(&this->dsi,0,sizeof(this->dsi));
-  this->last_cmd_nav_lbn = SRI_END_OF_CELL;
-
-  /* Set initial values of flags */
-  this->position_current.still = 0;
-  this->skip_still = 0;
-  this->sync_wait = 0;
-  this->sync_wait_skip = 0;
-  this->spu_clut_changed = 0;
-  this->started = 0;
-  this->cur_cell_time = 0;
-
-  dvdnav_read_cache_clear(this->cache);
-  pthread_mutex_unlock(&this->vm_lock);
-  
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
-  dvdnav_t *this;
-  struct timeval time;
-  
-  /* Create a new structure */
-  fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://dvd.sf.net\n", VERSION);
-
-  (*dest) = NULL;
-  this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
-  if(!this)
-    return DVDNAV_STATUS_ERR;
-  memset(this, 0, (sizeof(dvdnav_t) ) ); /* Make sure this structure is clean */
- 
-  pthread_mutex_init(&this->vm_lock, NULL);
-  /* Initialise the error string */
-  printerr("");
-
-  /* Initialise the VM */
-  this->vm = vm_new_vm();
-  if(!this->vm) {
-    printerr("Error initialising the DVD VM.");
-    pthread_mutex_destroy(&this->vm_lock);
-    free(this);
-    return DVDNAV_STATUS_ERR;
-  }
-  if(!vm_reset(this->vm, path)) {
-    printerr("Error starting the VM / opening the DVD device.");
-    pthread_mutex_destroy(&this->vm_lock);
-    vm_free_vm(this->vm);
-    free(this);
-    return DVDNAV_STATUS_ERR;
-  }
-
-  /* Set the path. FIXME: Is a deep copy 'right' */
-  strncpy(this->path, path, MAX_PATH_LEN - 1);
-  this->path[MAX_PATH_LEN - 1] = '\0';
-
-  /* Pre-open and close a file so that the CSS-keys are cached. */
-  this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), 0, DVD_READ_MENU_VOBS);
-    
-  /* Start the read-ahead cache. */
-  this->cache = dvdnav_read_cache_new(this);
-
-  /* Seed the random numbers. So that the DVD VM Command rand()
-   * gives a different start value each time a DVD is played. */
-  gettimeofday(&time, NULL);
-  srand(time.tv_usec);
- 
-  dvdnav_clear(this);
- 
-  (*dest) = this;
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_close(dvdnav_t *this) {
-
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: close:called\n");
-#endif
-
-  if (this->file) {
-    pthread_mutex_lock(&this->vm_lock); 
-    DVDCloseFile(this->file);
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: close:file closing\n");
-#endif
-    this->file = NULL;
-    pthread_mutex_unlock(&this->vm_lock); 
-  }
-
-  /* Free the VM */
-  if(this->vm)
-    vm_free_vm(this->vm);
-
-  pthread_mutex_destroy(&this->vm_lock);
-
-  /* We leave the final freeing of the entire structure to the cache,
-   * because we don't know, if there are still buffers out in the wild,
-   * that must return first. */
-  if(this->cache)
-    dvdnav_read_cache_free(this->cache);
-  else
-    free(this);
-  
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_reset(dvdnav_t *this) {
-  dvdnav_status_t result;
-
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: reset:called\n");
-#endif
-
-  pthread_mutex_lock(&this->vm_lock); 
-
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: reseting vm\n");
-#endif
-  if(!vm_reset(this->vm, NULL)) {
-    printerr("Error restarting the VM.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_ERR;
-  }
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: clearing dvdnav\n");
-#endif
-  result = dvdnav_clear(this);
-
-  pthread_mutex_unlock(&this->vm_lock); 
-  return result;
-}
-
-dvdnav_status_t dvdnav_path(dvdnav_t *this, const char** path) {
-  (*path) = this->path;
-
-  return DVDNAV_STATUS_OK;
-}
-
-const char* dvdnav_err_to_string(dvdnav_t *this) {
-  
-  if(!this)
-    return "Hey! You gave me a NULL pointer you naughty person!";
-  
-  return this->err_str;
-}
-
-/* converts a dvd_time_t to PTS ticks */
-int64_t dvdnav_convert_time(dvd_time_t *time) {
-  int64_t result;
-  int64_t frames;
-  
-  result  = (time->hour    >> 4  ) * 10 * 60 * 60 * 90000;
-  result += (time->hour    & 0x0f)      * 60 * 60 * 90000;
-  result += (time->minute  >> 4  )      * 10 * 60 * 90000;
-  result += (time->minute  & 0x0f)           * 60 * 90000;
-  result += (time->second  >> 4  )           * 10 * 90000;
-  result += (time->second  & 0x0f)                * 90000;
-  
-  frames  = ((time->frame_u & 0x30) >> 4) * 10;
-  frames += ((time->frame_u & 0x0f)     )     ;
-  
-  if (time->frame_u & 0x80)
-    result += frames * 3000;
-  else
-    result += frames * 3600;
-  
-  return result;
-}
-
-/*
- * Returns 1 if block contains NAV packet, 0 otherwise.
- * Processes said NAV packet if present.
- *
- * Most of the code in here is copied from xine's MPEG demuxer
- * so any bugs which are found in that should be corrected here also.
- */
-static int32_t dvdnav_decode_packet(dvdnav_t *this, uint8_t *p, dsi_t *nav_dsi, pci_t *nav_pci) {
-  int32_t        bMpeg1 = 0;
-  uint32_t       nHeaderLen;
-  uint32_t       nPacketLen;
-  uint32_t       nStreamID;
-
-  if (p[3] == 0xBA) { /* program stream pack header */
-    int32_t nStuffingBytes;
-
-    bMpeg1 = (p[4] & 0x40) == 0;
-
-    if (bMpeg1) {
-      p += 12;
-    } else { /* mpeg2 */
-      nStuffingBytes = p[0xD] & 0x07;
-      p += 14 + nStuffingBytes;
-    }
-  }
-
-  if (p[3] == 0xbb) { /* program stream system header */
-    nHeaderLen = (p[4] << 8) | p[5];
-    p += 6 + nHeaderLen;
-  }
-
-  /* we should now have a PES packet here */
-  if (p[0] || p[1] || (p[2] != 1)) {
-    fprintf(MSG_OUT, "libdvdnav: demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]);
-    return 0;
-  }
-
-  nPacketLen = p[4] << 8 | p[5];
-  nStreamID  = p[3];
-
-  nHeaderLen = 6;
-  p += nHeaderLen;
-
-  if (nStreamID == 0xbf) { /* Private stream 2 */
-#if 0
-    int32_t i;
-    fprintf(MSG_OUT, "libdvdnav: nav packet=%u\n",p-p_start-6);
-    for(i=0;i<80;i++)
-      fprintf(MSG_OUT, "%02x ",p[i-6]);
-    fprintf(MSG_OUT, "\n");
-#endif
-
-    if(p[0] == 0x00) {
-      navRead_PCI(nav_pci, p+1);
-    }
-
-    p += nPacketLen;
-
-    /* We should now have a DSI packet. */
-    if(p[6] == 0x01) {
-      nPacketLen = p[4] << 8 | p[5];
-      p += 6;
-      navRead_DSI(nav_dsi, p+1);
-    } 
-    return 1;
-  }
-  return 0;
-}
-
-/* DSI is used for most angle stuff. 
- * PCI is used for only non-seemless angle stuff
- */ 
-static int32_t dvdnav_get_vobu(dvdnav_t *this, dsi_t *nav_dsi, pci_t *nav_pci, dvdnav_vobu_t *vobu) {
-  uint32_t next;
-  int32_t angle, num_angle;
-
-  vobu->vobu_start = nav_dsi->dsi_gi.nv_pck_lbn; /* Absolute offset from start of disk */
-  vobu->vobu_length = nav_dsi->dsi_gi.vobu_ea; /* Relative offset from vobu_start */
-     
-  /*
-   * If we're not at the end of this cell, we can determine the next
-   * VOBU to display using the VOBU_SRI information section of the
-   * DSI.  Using this value correctly follows the current angle,
-   * avoiding the doubled scenes in The Matrix, and makes our life
-   * really happy.
-   *
-   * vobu_next is an offset value, 0x3fffffff = SRI_END_OF_CELL
-   * DVDs are about 6 Gigs, which is only up to 0x300000 blocks
-   * Should really assert if bit 31 != 1
-   */
-  
-#if 0
-  /* Old code -- may still be useful one day */
-  if(nav_dsi->vobu_sri.next_vobu != SRI_END_OF_CELL ) {
-    vobu->vobu_next = ( nav_dsi->vobu_sri.next_vobu & 0x3fffffff );
-  } else {
-    vobu->vobu_next = vobu->vobu_length;
-  }
-#else
-  /* Relative offset from vobu_start */
-  vobu->vobu_next = ( nav_dsi->vobu_sri.next_vobu & 0x3fffffff );
-#endif
-  
-  vm_get_angle_info(this->vm, &angle, &num_angle);
-
-  /* FIMXE: The angle reset doesn't work for some reason for the moment */
-#if 0
-  if((num_angle < angle) && (angle != 1)) {
-    fprintf(MSG_OUT, "libdvdnav: angle ends!\n");
-    
-    /* This is to switch back to angle one when we
-     * finish with angles. */
-    dvdnav_angle_change(this, 1);
-  } 
-#endif
-
-  if(num_angle != 0) {
-    
-    if((next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]) != 0) {
-      if((next & 0x3fffffff) != 0) {
-	if(next & 0x80000000)
-	  vobu->vobu_next = - (int32_t)(next & 0x3fffffff);
-	else
-	  vobu->vobu_next = + (int32_t)(next & 0x3fffffff);
-      }
-    } else if((next = nav_dsi->sml_agli.data[angle-1].address) != 0) {
-      vobu->vobu_length = nav_dsi->sml_pbi.ilvu_ea;
-      
-      if((next & 0x80000000) && (next != 0x7fffffff))
-	vobu->vobu_next =  - (int32_t)(next & 0x3fffffff);
-      else
-	vobu->vobu_next =  + (int32_t)(next & 0x3fffffff);
-    }
-  }
-
-  return 1;
-}
-
-/*
- * These are the main get_next_block function which actually get the media stream video and audio etc.
- *
- * There are two versions: The second one is using the zero-copy read ahead cache and therefore
- * hands out pointers targetting directly into the cache.
- * The first one uses a memcopy to fill this cache block into the application provided memory.
- * The benefit of this first one is that no special memory management is needed. The application is
- * the only one responsible of allocating and freeing the memory associated with the pointer.
- * The drawback is the additional memcopy.
- */
-
-dvdnav_status_t dvdnav_get_next_block(dvdnav_t *this, uint8_t *buf,
-				      int32_t *event, int32_t *len) {
-  unsigned char *block;
-  dvdnav_status_t status;
-  
-  block = buf;
-  status = dvdnav_get_next_cache_block(this, &block, event, len);
-  if (status == DVDNAV_STATUS_OK && block != buf) {
-    /* we received a block from the cache, copy it, so we can give it back */
-    memcpy(buf, block, DVD_VIDEO_LB_LEN);
-    dvdnav_free_cache_block(this, block);
-  }
-  return status;
-}
-
-int64_t dvdnav_get_current_time(dvdnav_t *this) {
-  int i;
-  int64_t tm=0;
-  dvd_state_t *state = &this->vm->state;
-
-  for(i=0; i<state->cellN-1; i++) {
-    if(!
-        (state->pgc->cell_playback[i].block_type == BLOCK_TYPE_ANGLE_BLOCK &&
-         state->pgc->cell_playback[i].block_mode != BLOCK_MODE_FIRST_CELL)
-    )
-      tm += dvdnav_convert_time(&state->pgc->cell_playback[i].playback_time);
-  }
-  tm += this->cur_cell_time;
-
-  return tm;
-}
- 
-dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
-					    int32_t *event, int32_t *len) {
-  dvd_state_t *state;
-  int32_t result;
-
-  pthread_mutex_lock(&this->vm_lock);
-  
-  if(!this->started) {
-    /* Start the VM */
-    if (!vm_start(this->vm)) {
-      printerr("Encrypted or faulty DVD");
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_ERR;
-    }
-    this->started = 1;
-  }
-
-  state = &(this->vm->state);
-  (*event) = DVDNAV_NOP;
-  (*len) = 0;
- 
-  /* Check the STOP flag */
-  if(this->vm->stopped) {
-    vm_stop(this->vm);
-    (*event) = DVDNAV_STOP;
-    this->started = 0;
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-
-  vm_position_get(this->vm, &this->position_next);
-  
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: POS-NEXT ");
-  vm_position_print(this->vm, &this->position_next);
-  fprintf(MSG_OUT, "libdvdnav: POS-CUR  ");
-  vm_position_print(this->vm, &this->position_current);
-#endif
-
-  /* did we hop? */
-  if(this->position_current.hop_channel != this->position_next.hop_channel) {
-    (*event) = DVDNAV_HOP_CHANNEL;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: HOP_CHANNEL\n");
-#endif
-    if (this->position_next.hop_channel - this->position_current.hop_channel >= HOP_SEEK) {
-      int32_t num_angles = 0, current;
-      
-      /* we seeked -> check for multiple angles */
-      vm_get_angle_info(this->vm, &current, &num_angles);
-      if (num_angles > 1) {
-        int32_t result, block;
-	/* we have to skip the first VOBU when seeking in a multiangle feature,
-	 * because it might belong to the wrong angle */
-	block = this->position_next.cell_start + this->position_next.block;
-	result = dvdnav_read_cache_block(this->cache, block, 1, buf);
-	if(result <= 0) {
-	  printerr("Error reading NAV packet.");
-	  pthread_mutex_unlock(&this->vm_lock); 
-	  return DVDNAV_STATUS_ERR;
-	}
-	/* Decode nav into pci and dsi. Then get next VOBU info. */
-	if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) {
-	  printerr("Expected NAV packet but none found.");
-	  pthread_mutex_unlock(&this->vm_lock); 
-	  return DVDNAV_STATUS_ERR;
-	}
-	dvdnav_get_vobu(this, &this->dsi, &this->pci, &this->vobu);
-	/* skip to next, if there is a next */
-	if (this->vobu.vobu_next != SRI_END_OF_CELL) {
-	  this->vobu.vobu_start += this->vobu.vobu_next;
-	  this->vobu.vobu_next   = 0;
-	}
-	/* update VM state */
-	this->vm->state.blockN = this->vobu.vobu_start - this->position_next.cell_start;
-      }
-    }
-    this->position_current.hop_channel = this->position_next.hop_channel;
-    /* update VOBU info */
-    this->vobu.vobu_start  = this->position_next.cell_start + this->position_next.block;
-    this->vobu.vobu_next   = 0;
-    /* Make blockN == vobu_length to do expected_nav */
-    this->vobu.vobu_length = 0;
-    this->vobu.blockN      = 0;
-    this->sync_wait        = 0;
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-
-  /* Check the HIGHLIGHT flag */
-  if(this->position_current.button != this->position_next.button) {
-    dvdnav_highlight_event_t *hevent = (dvdnav_highlight_event_t *)*buf;
-
-    (*event) = DVDNAV_HIGHLIGHT;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: HIGHLIGHT\n");
-#endif
-    (*len) = sizeof(dvdnav_highlight_event_t);
-    hevent->display = 1;
-    hevent->buttonN = this->position_next.button;
-    this->position_current.button = this->position_next.button;
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-  
-  /* Check the WAIT flag */
-  if(this->sync_wait) {
-    (*event) = DVDNAV_WAIT;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: WAIT\n");
-#endif
-    (*len) = 0;
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_OK;
-  }
-
-  /* Check to see if we need to change the currently opened VOB */
-  if((this->position_current.vts != this->position_next.vts) || 
-     (this->position_current.domain != this->position_next.domain)) {
-    dvd_read_domain_t domain;
-    int32_t vtsN;
-    dvdnav_vts_change_event_t *vts_event = (dvdnav_vts_change_event_t *)*buf;
-    
-    if(this->file) {
-      DVDCloseFile(this->file);
-      this->file = NULL;
-    }
-
-    vts_event->old_vtsN = this->position_current.vts;
-    vts_event->old_domain = this->position_current.domain;
-     
-    /* Use the DOMAIN to find whether to open menu or title VOBs */
-    switch(this->position_next.domain) {
-    case FP_DOMAIN:
-    case VMGM_DOMAIN:
-      domain = DVD_READ_MENU_VOBS;
-      vtsN = 0;
-      break;
-    case VTSM_DOMAIN:
-      domain = DVD_READ_MENU_VOBS;
-      vtsN = this->position_next.vts; 
-      break;
-    case VTS_DOMAIN:
-      domain = DVD_READ_TITLE_VOBS;
-      vtsN = this->position_next.vts; 
-      break;
-    default:
-      printerr("Unknown domain when changing VTS.");
-      pthread_mutex_unlock(&this->vm_lock); 
-      return DVDNAV_STATUS_ERR;
-    }
-    
-    this->position_current.vts = this->position_next.vts; 
-    this->position_current.domain = this->position_next.domain;
-    dvdnav_read_cache_clear(this->cache);
-    this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), vtsN, domain);
-    vts_event->new_vtsN = this->position_next.vts; 
-    vts_event->new_domain = this->position_next.domain; 
-
-    /* If couldn't open the file for some reason, moan */
-    if(this->file == NULL) {
-      printerrf("Error opening vtsN=%i, domain=%i.", vtsN, domain);
-      pthread_mutex_unlock(&this->vm_lock); 
-      return DVDNAV_STATUS_ERR;
-    }
-
-    /* File opened successfully so return a VTS change event */
-    (*event) = DVDNAV_VTS_CHANGE;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: VTS_CHANGE\n");
-#endif
-    (*len) = sizeof(dvdnav_vts_change_event_t);
-
-    this->spu_clut_changed = 1;
-    this->position_current.cell = -1; /* Force an update */
-    this->position_current.spu_channel = -1; /* Force an update */
-    this->position_current.audio_channel = -1; /* Force an update */;
-     
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-
-  /* Check if the cell changed */  
-  if( (this->position_current.cell != this->position_next.cell) ||
-      (this->position_current.cell_restart != this->position_next.cell_restart) ||
-      (this->position_current.cell_start != this->position_next.cell_start) ) {
-    dvdnav_cell_change_event_t *cell_event = (dvdnav_cell_change_event_t *)*buf;
-    int32_t first_cell_nr, last_cell_nr, i;
-    dvd_state_t *state = &this->vm->state;
-    
-    this->cur_cell_time = 0;
-    (*event) = DVDNAV_CELL_CHANGE;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: CELL_CHANGE\n");
-#endif
-    (*len) = sizeof(dvdnav_cell_change_event_t);
-    
-    cell_event->cellN = state->cellN;
-    cell_event->pgN   = state->pgN;
-    cell_event->cell_length =
-      dvdnav_convert_time(&state->pgc->cell_playback[state->cellN-1].playback_time);
-
-    cell_event->pg_length = 0;
-    /* Find start cell of program. */
-    first_cell_nr = state->pgc->program_map[state->pgN-1];
-    /* Find end cell of program */
-    if(state->pgN < state->pgc->nr_of_programs)
-      last_cell_nr = state->pgc->program_map[state->pgN] - 1;
-    else
-      last_cell_nr = state->pgc->nr_of_cells;
-    for (i = first_cell_nr; i <= last_cell_nr; i++)
-      cell_event->pg_length +=
-        dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time);
-    cell_event->pgc_length = dvdnav_convert_time(&state->pgc->playback_time);
-
-    cell_event->cell_start = 0;
-    for (i = 1; i < state->cellN; i++)
-      cell_event->cell_start +=
-        dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time);
-
-    cell_event->pg_start = 0;
-    for (i = 1; i < state->pgc->program_map[state->pgN-1]; i++)
-      cell_event->pg_start +=
-        dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time);
-
-    this->position_current.cell         = this->position_next.cell;
-    this->position_current.cell_restart = this->position_next.cell_restart;
-    this->position_current.cell_start   = this->position_next.cell_start;
-    this->position_current.block        = this->position_next.block;
-    
-    /* vobu info is used for mid cell resumes */
-    this->vobu.vobu_start               = this->position_next.cell_start + this->position_next.block;
-    this->vobu.vobu_next                = 0;
-    /* Make blockN == vobu_length to do expected_nav */
-    this->vobu.vobu_length = 0;
-    this->vobu.blockN      = 0;
-    
-    /* update the spu palette at least on PGC changes */
-    this->spu_clut_changed = 1;
-    this->position_current.spu_channel = -1; /* Force an update */
-    this->position_current.audio_channel = -1; /* Force an update */
-
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
- 
-  /* has the CLUT changed? */
-  if(this->spu_clut_changed) {
-    (*event) = DVDNAV_SPU_CLUT_CHANGE;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: SPU_CLUT_CHANGE\n");
-#endif
-    (*len) = 16 * sizeof(uint32_t);
-    memcpy(*buf, &(state->pgc->palette), 16 * sizeof(uint32_t));
-    this->spu_clut_changed = 0;
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-
-  /* has the SPU channel changed? */  
-  if(this->position_current.spu_channel != this->position_next.spu_channel) {
-    dvdnav_spu_stream_change_event_t *stream_change = (dvdnav_spu_stream_change_event_t *)*buf;
-
-    (*event) = DVDNAV_SPU_STREAM_CHANGE;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE\n");
-#endif
-    (*len) = sizeof(dvdnav_spu_stream_change_event_t);
-    stream_change->physical_wide      = vm_get_subp_active_stream(this->vm, 0);
-    stream_change->physical_letterbox = vm_get_subp_active_stream(this->vm, 1);
-    stream_change->physical_pan_scan  = vm_get_subp_active_stream(this->vm, 2);
-    this->position_current.spu_channel = this->position_next.spu_channel;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_wide=%d\n",stream_change->physical_wide);
-    fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_letterbox=%d\n",stream_change->physical_letterbox);
-    fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_pan_scan=%d\n",stream_change->physical_pan_scan);
-    fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE returning DVDNAV_STATUS_OK\n");
-#endif
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-
-  /* has the audio channel changed? */  
-  if(this->position_current.audio_channel != this->position_next.audio_channel) {
-    dvdnav_audio_stream_change_event_t *stream_change = (dvdnav_audio_stream_change_event_t *)*buf;
-    
-    (*event) = DVDNAV_AUDIO_STREAM_CHANGE;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: AUDIO_STREAM_CHANGE\n");
-#endif
-    (*len) = sizeof(dvdnav_audio_stream_change_event_t);
-    stream_change->physical = vm_get_audio_active_stream( this->vm );
-    this->position_current.audio_channel = this->position_next.audio_channel;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: AUDIO_STREAM_CHANGE stream_id=%d returning DVDNAV_STATUS_OK\n",stream_change->physical);
-#endif
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-     
-  /* Check the STILLFRAME flag */
-  if(this->position_current.still != 0) {
-    dvdnav_still_event_t *still_event = (dvdnav_still_event_t *)*buf;
-
-    (*event) = DVDNAV_STILL_FRAME;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: STILL_FRAME\n");
-#endif
-    (*len) = sizeof(dvdnav_still_event_t);
-    still_event->length = this->position_current.still;
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-
-  /* Have we reached the end of a VOBU? */
-  if (this->vobu.blockN >= this->vobu.vobu_length) {
-
-    /* Have we reached the end of a cell? */
-    if(this->vobu.vobu_next == SRI_END_OF_CELL) {
-      /* End of Cell from NAV DSI info */
-#ifdef LOG_DEBUG
-      fprintf(MSG_OUT, "libdvdnav: Still set to %x\n", this->position_next.still);
-#endif
-      this->position_current.still = this->position_next.still;
-
-      /* we are about to leave a cell, so a lot of state changes could occur;
-       * under certain conditions, the application should get in sync with us before this,
-       * otherwise it might show stills or menus too shortly */
-      if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip) {
-        this->sync_wait = 1;
-      } else {
-	if( this->position_current.still == 0 || this->skip_still ) {
-	  /* no active cell still -> get us to the next cell */
-	  vm_get_next_cell(this->vm);
-	  this->position_current.still = 0; /* still gets activated at end of cell */
-	  this->skip_still = 0;
-	  this->sync_wait_skip = 0;
-	}
-      }
-      /* handle related state changes in next iteration */
-      (*event) = DVDNAV_NOP;
-      (*len) = 0;
-      pthread_mutex_unlock(&this->vm_lock); 
-      return DVDNAV_STATUS_OK;
-    }
-
-    /* Perform remapping jump if necessary (this is always a 
-     * VOBU boundary). */
-    if (this->vm->map) {
-      this->vobu.vobu_next = remap_block( this->vm->map,
-        this->vm->state.domain, this->vm->state.TTN_REG,
-        this->vm->state.pgN,
-        this->vobu.vobu_start, this->vobu.vobu_next);
-    }
-
-    /* at the start of the next VOBU -> expecting NAV packet */
-    result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf);
-
-    if(result <= 0) {
-      printerr("Error reading NAV packet.");
-      pthread_mutex_unlock(&this->vm_lock); 
-      return DVDNAV_STATUS_ERR;
-    }
-    /* Decode nav into pci and dsi. Then get next VOBU info. */
-    if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) {
-      printerr("Expected NAV packet but none found.");
-      pthread_mutex_unlock(&this->vm_lock); 
-      return DVDNAV_STATUS_ERR;
-    }
-    /* We need to update the vm state->blockN with which VOBU we are in.
-     * This is so RSM resumes to the VOBU level and not just the CELL level.
-     */
-    this->vm->state.blockN = this->vobu.vobu_start - this->position_current.cell_start;
-
-    dvdnav_get_vobu(this, &this->dsi, &this->pci, &this->vobu); 
-    this->vobu.blockN = 0;
-    /* Give the cache a hint about the size of next VOBU.
-     * This improves pre-caching, because the VOBU will almost certainly be read entirely.
-     */
-    dvdnav_pre_cache_blocks(this->cache, this->vobu.vobu_start+1, this->vobu.vobu_length+1);
-    
-    /* release NAV menu filter, when we reach the same NAV packet again */
-    if (this->last_cmd_nav_lbn == this->pci.pci_gi.nv_pck_lbn)
-      this->last_cmd_nav_lbn = SRI_END_OF_CELL;
-    
-    /* Successfully got a NAV packet */
-    (*event) = DVDNAV_NAV_PACKET;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: NAV_PACKET\n");
-#endif
-    (*len) = 2048; 
-    this->cur_cell_time = dvdnav_convert_time(&this->dsi.dsi_gi.c_eltm);
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  }
-  
-  /* If we've got here, it must just be a normal block. */
-  if(!this->file) {
-    printerr("Attempting to read without opening file.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_ERR;
-  }
-
-  this->vobu.blockN++;
-  result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.blockN, 1, buf);
-  if(result <= 0) {
-    printerr("Error reading from DVD.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_ERR;
-  }
-  (*event) = DVDNAV_BLOCK_OK;
-  (*len) = 2048;
-
-  pthread_mutex_unlock(&this->vm_lock); 
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_get_title_string(dvdnav_t *this, const char **title_str) {
-  (*title_str) = this->vm->dvd_name;
-  return DVDNAV_STATUS_OK;
-}
-
-uint8_t dvdnav_get_video_aspect(dvdnav_t *this) {
-  uint8_t         retval;
-
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-
-  pthread_mutex_lock(&this->vm_lock);
-  retval = (uint8_t)vm_get_video_aspect(this->vm);
-  pthread_mutex_unlock(&this->vm_lock);
-  
-  return retval;
-}
-
-uint8_t dvdnav_get_video_scale_permission(dvdnav_t *this) {
-  uint8_t         retval;
-  
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock);
-  retval = (uint8_t)vm_get_video_scale_permission(this->vm);
-  pthread_mutex_unlock(&this->vm_lock);
-  
-  return retval;
-}
-
-uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *this, uint8_t stream) {
-  audio_attr_t  attr;
-  
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock); 
-  attr = vm_get_audio_attr(this->vm, stream);
-  pthread_mutex_unlock(&this->vm_lock); 
-  
-  if(attr.lang_type != 1)
-    return 0xffff;
-  
-  return attr.lang_code;
-}
-
-uint16_t dvdnav_audio_stream_format(dvdnav_t *this, uint8_t stream) {
-  audio_attr_t  attr;
-  uint16_t format;
-  
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1; /* 0xffff */
-  }
-  
-  pthread_mutex_lock(&this->vm_lock); 
-  attr = vm_get_audio_attr(this->vm, stream);
-  pthread_mutex_unlock(&this->vm_lock); 
-  
-  switch(attr.audio_format) {
-  case 0:
-    format = DVDNAV_FORMAT_AC3;
-    break;
-  case 2: /* MPEG-1 or MPEG-2 without extension bitstream. */
-  case 3: /* MPEG-2 with extension bitstream. */
-    format = DVDNAV_FORMAT_MPEGAUDIO;
-    break;
-  case 4:
-    format = DVDNAV_FORMAT_LPCM;
-    break;
-  case 6:
-    format = DVDNAV_FORMAT_DTS;
-    break;
-  case 7:
-    format = DVDNAV_FORMAT_SDDS;
-    break;
-  default: 
-    format = 0xffff;
-    break;
-  }
-  
-  return format;
-}
-
-uint16_t dvdnav_audio_stream_channels(dvdnav_t *this, uint8_t stream) {
-  audio_attr_t  attr;
-
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1; /* 0xffff */
-  }
-
-  pthread_mutex_lock(&this->vm_lock);
-  attr = vm_get_audio_attr(this->vm, stream);
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return attr.channels + 1;
-}
-
-uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) {
-  subp_attr_t  attr;
-  
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock); 
-  attr = vm_get_subp_attr(this->vm, stream);
-  pthread_mutex_unlock(&this->vm_lock); 
-  
-  if(attr.type != 1)
-    return 0xffff;
-  
-  return attr.lang_code;
-}
-
-int8_t dvdnav_get_audio_logical_stream(dvdnav_t *this, uint8_t audio_num) {
-  int8_t       retval;
-  
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock);
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return -1;
-  }
-  retval = vm_get_audio_stream(this->vm, audio_num);
-  pthread_mutex_unlock(&this->vm_lock); 
-
-  return retval;
-}
-
-dvdnav_status_t dvdnav_get_audio_attr(dvdnav_t *this, uint8_t audio_num, audio_attr_t *audio_attr) {
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  pthread_mutex_lock(&this->vm_lock);
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return -1;
-  }
-  *audio_attr=vm_get_audio_attr(this->vm, audio_num);
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
-
-int8_t dvdnav_get_spu_logical_stream(dvdnav_t *this, uint8_t subp_num) {
-  int8_t       retval;
-
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-
-  pthread_mutex_lock(&this->vm_lock);
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return -1;
-  }
-  retval = vm_get_subp_stream(this->vm, subp_num, 0);
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return retval;
-}
-
-dvdnav_status_t dvdnav_get_spu_attr(dvdnav_t *this, uint8_t audio_num, subp_attr_t *subp_attr) {
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  pthread_mutex_lock(&this->vm_lock);
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return -1;
-  }
-  *subp_attr=vm_get_subp_attr(this->vm, audio_num);
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_OK;
-}
-
-int8_t dvdnav_get_active_audio_stream(dvdnav_t *this) {
-  int8_t        retval;
-
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock); 
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return -1;
-  }
-  retval = vm_get_audio_active_stream(this->vm);
-  pthread_mutex_unlock(&this->vm_lock); 
-  
-  return retval;
-}
-
-int8_t dvdnav_get_active_spu_stream(dvdnav_t *this) {
-  int8_t        retval;
-
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock); 
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return -1;
-  }
-  retval = vm_get_subp_active_stream(this->vm, 0);
-  pthread_mutex_unlock(&this->vm_lock); 
-  
-  return retval;
-}
-
-static int8_t dvdnav_is_domain(dvdnav_t *this, domain_t domain) {
-  int8_t        retval;
-  
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return -1;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock);
-  retval = (this->vm->state.domain == domain);
-  pthread_mutex_unlock(&this->vm_lock);
-  
-  return retval;
-}
-
-/* First Play domain. (Menu) */
-int8_t dvdnav_is_domain_fp(dvdnav_t *this) {
-  return dvdnav_is_domain(this, FP_DOMAIN);
-}
-/* Video management Menu domain. (Menu) */
-int8_t dvdnav_is_domain_vmgm(dvdnav_t *this) {
-  return dvdnav_is_domain(this, VMGM_DOMAIN);
-}
-/* Video Title Menu domain (Menu) */
-int8_t dvdnav_is_domain_vtsm(dvdnav_t *this) {
-  return dvdnav_is_domain(this, VTSM_DOMAIN);
-}
-/* Video Title domain (playing movie). */
-int8_t dvdnav_is_domain_vts(dvdnav_t *this) { 
-  return dvdnav_is_domain(this, VTS_DOMAIN);
-}
-
-/* Generally delegate angle information handling to VM */
-dvdnav_status_t dvdnav_angle_change(dvdnav_t *this, int32_t angle) {
-  int32_t num, current;
-  
-  pthread_mutex_lock(&this->vm_lock);
-  vm_get_angle_info(this->vm, &current, &num);
-  /* Set angle SPRM if valid */
-  if((angle > 0) && (angle <= num)) {
-    this->vm->state.AGL_REG = angle;
-  } else {
-    printerr("Passed an invalid angle number.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *this, int32_t *current_angle,
-				      int32_t *number_of_angles) {
-  pthread_mutex_lock(&this->vm_lock);
-  vm_get_angle_info(this->vm, current_angle, number_of_angles);
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
-
-pci_t* dvdnav_get_current_nav_pci(dvdnav_t *this) {
-  if(!this) return 0;
-  return &this->pci;
-}
-
-dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *this) {
-  if(!this) return 0;
-  return &this->dsi;
-}
-
-uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) {
-  if(!this) return -1;
-  return this->position_next.still;
-}
-
-user_ops_t dvdnav_get_restrictions(dvdnav_t* this) {
-  /* 
-   * user_ops_t is a structure of 32 bits.  We want to compute 
-   * the union of two of those bitfields so to make this quicker 
-   * than performing 32 ORs, we will access them as 32bits words.
-   */
-  union {
-    user_ops_t ops_struct;
-    uint32_t   ops_int;
-  } ops;
-  
-  ops.ops_int = 0;
-  
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return ops.ops_struct;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock); 
-  ops.ops_int |= *(uint32_t*)&this->pci.pci_gi.vobu_uop_ctl;
-  
-  if(this->vm && this->vm->state.pgc)
-    ops.ops_int |= *(uint32_t*)&this->vm->state.pgc->prohibited_ops;
-  pthread_mutex_unlock(&this->vm_lock); 
-    
-  return ops.ops_struct;
-}
--- a/dvdnav.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,684 +0,0 @@
-/* 
- * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-/*
- * This is the main header file applications should include if they want
- * to access dvdnav functionality.
- */
-
-#ifndef DVDNAV_H_INCLUDED
-#define DVDNAV_H_INCLUDED
-
-#define MP_DVDNAV 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef DVDNAV_COMPILE
-#  include <dvdnav/dvd_types.h>
-#  include <libdvdread/dvd_reader.h>
-#  include <libdvdread/nav_types.h>
-#  include <libdvdread/ifo_types.h> /* For vm_cmd_t */
-#  include <dvdnav/dvdnav_events.h>
-#endif
-
-
-
-/*********************************************************************
- * dvdnav data types                                                 *
- *********************************************************************/
-
-/*
- * Opaque data-type can be viewed as a 'DVD handle'. You should get
- * a pointer to a dvdnav_t from the dvdnav_open() function.
- * Never call free() on the pointer, you have to give it back with
- * dvdnav_close().
- */
-typedef struct dvdnav_s dvdnav_t;
-
-/* Status as reported by most of libdvdnav's functions */
-typedef int32_t dvdnav_status_t;
-
-/*
- * Unless otherwise stated, all functions return DVDNAV_STATUS_OK if
- * they succeeded, otherwise DVDNAV_STATUS_ERR is returned and the error may
- * be obtained by calling dvdnav_err_to_string().
- */
-#define DVDNAV_STATUS_ERR 0
-#define DVDNAV_STATUS_OK  1
-
-#define DVDNAV_FORMAT_AC3 0
-#define DVDNAV_FORMAT_MPEGAUDIO 3
-#define DVDNAV_FORMAT_LPCM 4
-#define DVDNAV_FORMAT_DTS 5
-#define DVDNAV_FORMAT_SDDS 6
-
-/*********************************************************************
- * initialisation & housekeeping functions                           *
- *********************************************************************/
-
-/*
- * These functions allow you to open a DVD device and associate it
- * with a dvdnav_t.
- */
-
-/*
- * Attempts to open the DVD drive at the specified path and pre-cache
- * the CSS-keys. libdvdread is used to access the DVD, so any source
- * supported by libdvdread can be given with "path". Currently,
- * libdvdread can access: DVD drives, DVD image files, DVD file-by-file
- * copies.
- *
- * The resulting dvdnav_t handle will be written to *dest.
- */
-dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path);
-
-/*
- * Closes a dvdnav_t previously opened with dvdnav_open(), freeing any 
- * memory associated with it.
- */
-dvdnav_status_t dvdnav_close(dvdnav_t *self);
-
-/*
- * Resets the DVD virtual machine and cache buffers.
- */
-dvdnav_status_t dvdnav_reset(dvdnav_t *self);
-
-/*
- * Fills a pointer with a value pointing to a string describing
- * the path associated with an open dvdnav_t. It assigns *path to NULL
- * on error.
- */
-dvdnav_status_t dvdnav_path(dvdnav_t *self, const char **path);
-
-/*
- * Returns a human-readable string describing the last error.
- */
-const char* dvdnav_err_to_string(dvdnav_t *self);
-
-
-/*********************************************************************
- * changing and reading DVD player characteristics                   *
- *********************************************************************/
-
-/*
- * These functions allow you to manipulate the various global characteristics
- * of the DVD playback engine.
- */
-
-/*
- * Sets the region mask (bit 0 set implies region 1, bit 1 set implies
- * region 2, etc) of the virtual machine. Generally you will only need to set
- * this if you are playing RCE discs which query the virtual machine as to its
- * region setting. 
- *
- * This has _nothing_ to do with the region setting of the DVD drive.
- */
-dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *self, int32_t region_mask);
-
-/*
- * Returns the region mask (bit 0 set implies region 1, bit 1 set implies
- * region 2, etc) of the virtual machine.
- *
- * This has _nothing_ to do with the region setting of the DVD drive.
- */
-dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *self, int32_t *region_mask);
-
-/*
- * Specify whether read-ahead caching should be used. You may not want this if your
- * decoding engine does its own buffering.
- *
- * The default read-ahead cache does not use an additional thread for the reading
- * (see read_cache.c for a threaded cache, but note that this code is currently
- * unmaintained). It prebuffers on VOBU level by reading ahead several buffers
- * on every read request. The speed of this prebuffering has been optimized to
- * also work on slow DVD drives.
- *
- * If in addition you want to prevent memcpy's to improve performance, have a look
- * at dvdnav_get_next_cache_block().
- */
-dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *self, int32_t read_ahead_flag);
-
-/*
- * Query whether read-ahead caching/buffering will be used.
- */
-dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *self, int32_t *read_ahead_flag);
-
-/*
- * Specify whether the positioning works PGC or PG based.
- * Programs (PGs) on DVDs are similar to Chapters and a program chain (PGC)
- * usually covers a whole feature. This affects the behaviour of the
- * functions dvdnav_get_position() and dvdnav_sector_search(). See there.
- * Default is PG based positioning.
- */
-dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *self, int32_t pgc_based_flag);
-
-/*
- * Query whether positioning is PG or PGC based.
- */
-dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int32_t *pgc_based_flag);
-
-
-/*********************************************************************
- * reading data                                                      *
- *********************************************************************/
-
-/*
- * These functions are used to poll the playback enginge and actually get data 
- * off the DVD.
- */
-
-/*
- * Attempts to get the next block off the DVD and copies it into the buffer 'buf'. 
- * If there is any special actions that may need to be performed, the value
- * pointed to by 'event' gets set accordingly.
- *
- * If 'event' is DVDNAV_BLOCK_OK then 'buf' is filled with the next block
- * (note that means it has to be at /least/ 2048 bytes big). 'len' is
- * then set to 2048.
- *
- * Otherwise, buf is filled with an appropriate event structure and
- * len is set to the length of that structure.
- *
- * See the dvdnav_events.h header for information on the various events.
- */
-dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, uint8_t *buf,
-				      int32_t *event, int32_t *len);
-
-/*
- * This basically does the same as dvdnav_get_next_block. The only difference is
- * that it avoids a memcopy, when the requested block was found in the cache.
- * I such a case (cache hit) this function will return a different pointer than
- * the one handed in, pointing directly into the relevant block in the cache.
- * Those pointers must _never_ be freed but instead returned to the library via
- * dvdnav_free_cache_block().
- */
-dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *self, uint8_t **buf,
-					    int32_t *event, int32_t *len);
-
-/*
- * All buffers which came from the internal cache (when dvdnav_get_next_cache_block()
- * returned a buffer different from the one handed in) have to be freed with this
- * function. Although handing in other buffers not from the cache doesn't cause any harm.
- */
-dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf);
-
-/*
- * If we are currently in a still-frame this function skips it.
- *
- * See also the DVDNAV_STILL_FRAME event.
- */
-dvdnav_status_t dvdnav_still_skip(dvdnav_t *self);
-
-/*
- * If we are currently in WAIT state, that is: the application is required to
- * wait for its fifos to become empty, calling this signals libdvdnav that this
- * is achieved and that it can continue.
- *
- * See also the DVDNAV_WAIT event.
- */
-dvdnav_status_t dvdnav_wait_skip(dvdnav_t *self);
-
-/*
- * Returns the still time from the currently playing cell.
- * The still time is given in seconds with 0xff meaning an indefinite still.
- *
- * This function can be used to detect still frames before they are reached.
- * Some players might need this to prepare for a frame to be shown for a
- * longer time than usual.
- */
-uint32_t dvdnav_get_next_still_flag(dvdnav_t *self);
-
-/*
- * Stops playback. The next event obtained with one of the get_next_block
- * functions will be a DVDNAV_STOP event.
- *
- * It is not required to call this before dvdnav_close().
- */
-dvdnav_status_t dvdnav_stop(dvdnav_t *self);
-
-
-/*********************************************************************
- * title/part navigation                                             *
- *********************************************************************/
-
-/*
- * Returns the number of titles on the disk.
- */
-dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *self, int32_t *titles);
-
-/*
- * Returns the number of parts within the given title.
- */
-dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *self, int32_t title, int32_t *parts);
-
-/*
- * Plays the specified title of the DVD from its beginning (that is: part 1).
- */
-dvdnav_status_t dvdnav_title_play(dvdnav_t *self, int32_t title);
-
-/*
- * Plays the specified title, starting from the specified part.
- */
-dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int32_t title, int32_t part);
-
-/*
- * Stores in *times an array (that the application *must* free) of
- * dvdtimes corresponding to the chapter times for the chosen title.
- * *duration will have the duration of the title
- * The number of entries in *times is the result of the function.
- * On error *times is NULL and the output is 0
- */
-uint32_t dvdnav_describe_title_chapters(dvdnav_t *this, int32_t title, uint64_t **times, uint64_t *duration);
-
-/*
- * Play the specified amount of parts of the specified title of
- * the DVD then STOP.
- *
- * Currently unimplemented!
- */
-dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *self, int32_t title,
-					   int32_t part, int32_t parts_to_play);
-
-/*
- * Play the specified title starting from the specified time.
- *
- * Currently unimplemented!
- */
-dvdnav_status_t dvdnav_time_play(dvdnav_t *self, int32_t title,
-				 uint64_t time);
-
-/*
- * Stop playing the current position and jump to the specified menu.
- *
- * See also DVDMenuID_t from libdvdread
- */
-dvdnav_status_t dvdnav_menu_call(dvdnav_t *self, DVDMenuID_t menu);
-
-/*
- * Return the title number and part currently being played.
- * A title of 0 indicates, we are in a menu. In this case, part
- * is set to the current menu's ID.
- */
-dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int32_t *title,
-					  int32_t *part);
-
-/*
- * Return the current position (in blocks) within the current
- * title and the length (in blocks) of said title.
- * 
- * Current implementation is wrong and likely to behave unpredictably!
- * Use is discouraged!
- */
-dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self,
-					     uint32_t *pos,
-					     uint32_t *len);
-
-/*
- * This function is only available for compatibility reasons.
- *
- * Stop playing the current position and start playback of the current title
- * from the specified part.
- */
-dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int32_t part);
-
-
-/*********************************************************************
- * program chain/program navigation                                  *
- *********************************************************************/
-
-/*
- * Stop playing the current position and start playback from the last
- * VOBU boundary before the given sector. The sector number is not
- * meant to be an absolute physical DVD sector, but a relative sector
- * in the current program. This function cannot leave the current
- * program and will fail, if asked to do so.
- *
- * If program chain based positioning is enabled
- * (see dvdnav_set_PGC_positioning_flag()), this will seek to the relative
- * sector inside the current program chain.
- *
- * 'origin' can be one of SEEK_SET, SEEK_CUR, SEEK_END as defined in
- * fcntl.h.
- */
-dvdnav_status_t dvdnav_sector_search(dvdnav_t *self, 
-				     uint64_t offset, int32_t origin);
-
-/*
- returns the current stream time in PTS ticks as reported by the IFO structures
- divide it by 90000 to get the current play time in seconds
- */
-int64_t dvdnav_get_current_time(dvdnav_t *self);
-
-/*
- * Stop playing the current position and start playback of the title
- * from the specified timecode.
- *
- * Currently unimplemented!
- */
-dvdnav_status_t dvdnav_time_search(dvdnav_t *self, 
-				   uint64_t time);
-
-/*
- * Stop playing current position and play the "GoUp"-program chain.
- * (which generally leads to the title menu or a higer-level menu).
- */
-dvdnav_status_t dvdnav_go_up(dvdnav_t *self);
-
-/*
- * Stop playing the current position and start playback at the
- * previous program (if it exists).
- */
-dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *self);
-
-/*
- * Stop playing the current position and start playback at the
- * first program.
- */
-dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *self);
-
-/*
- * Stop playing the current position and start playback at the
- * next program (if it exists).
- */
-dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *self);
-
-/*
- * Return the current position (in blocks) within the current
- * program and the length (in blocks) of current program.
- *
- * If program chain based positioning is enabled
- * (see dvdnav_set_PGC_positioning_flag()), this will return the
- * relative position in and the length of the current program chain.
- */
-dvdnav_status_t dvdnav_get_position(dvdnav_t *self, uint32_t *pos,
-				    uint32_t *len);
-
-
-/*********************************************************************
- * menu highlights                                                   *
- *********************************************************************/
-
-/*
- * Most functions related to highlights take a NAV PCI packet as a parameter.
- * While you can get the such a packet from libdvdnav, for players with internal
- * FIFOs, this will result in errors, because due to the FIFO length, libdvdnav will
- * be ahead in the stream compared to what the user is seeing on screen.
- * Therefore, player applications who have a NAV packet available, which is
- * better in sync with the actual playback should always pass this one to these
- * functions.
- */
-
-/*
- * Get the currently highlighted button 
- * number (1..36) or 0 if no button is highlighted.
- */
-dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *self, int32_t *button);
-
-/*
- * Returns the Presentation Control Information (PCI) structure associated
- * with the current position.
- *
- * Read the general notes above.
- * See also libdvdreads nav_types.h for definition of pci_t.
- */
-pci_t* dvdnav_get_current_nav_pci(dvdnav_t *self);
-
-/*
- * Returns the DSI (data search information) structure associated
- * with the current position.
- *
- * Read the general notes above.
- * See also libdvdreads nav_types.h for definition of dsi_t.
- */
-dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *self);
-
-/*
- * Get the area associated with a certain button.
- */
-dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode,
-					  dvdnav_highlight_area_t *highlight);
-
-/*
- * Move button highlight around as suggested by function name (e.g. with arrow keys).
- */
-dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self, pci_t *pci);
-dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self, pci_t *pci);
-dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self, pci_t *pci);
-dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self, pci_t *pci);
-
-/*
- * Activate ("press") the currently highlighted button.
- */
-dvdnav_status_t dvdnav_button_activate(dvdnav_t *self, pci_t *pci);
-
-/*
- * Highlight a specific button.
- */
-dvdnav_status_t dvdnav_button_select(dvdnav_t *self, pci_t *pci, int32_t button);
-
-/*
- * Activate ("press") specified button.
- */
-dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, pci_t *pci, int32_t button);
-
-/*
- * Activate (press) a button and execute specified command.
- */
-dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *self, int32_t button, vm_cmd_t *cmd);
-
-/*
- * Select button at specified video frame coordinates.
- */
-dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, pci_t *pci, int32_t x, int32_t y);
-
-/*
- * Activate ("press") button at specified video frame coordinates.
- */
-dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, pci_t *pci, int32_t x, int32_t y);
-
-
-/*********************************************************************
- * languages                                                         *
- *********************************************************************/
-
-/* 
- * The language codes expected by these functions are two character
- * codes as defined in ISO639.
- */
-
-/*
- * Set which menu language we should use per default.
- */
-dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *self,
-					   char *code);
-
-/*
- * Set which audio language we should use per default.
- */
-dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *self,
-					    char *code);
-
-/*
- * Set which spu language we should use per default.
- */
-dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *self,
-					  char *code);
-
-
-/*********************************************************************
- * obtaining stream attributes                                       *
- *********************************************************************/
-
-/*
- * Return a string describing the title of the DVD.
- * This is an ID string encoded on the disc by the author. In many cases
- * this is a descriptive string such as `THE_MATRIX' but sometimes is sigularly
- * uninformative such as `PDVD-011421'. Some DVD authors even forget to set this,
- * so you may also read the default of the authoring software they used, like
- * `DVDVolume'.
- */
-dvdnav_status_t dvdnav_get_title_string(dvdnav_t *self, const char **title_str);
-
-/*
- * Get video aspect code.
- * The aspect code does only change on VTS boundaries.
- * See the DVDNAV_VTS_CHANGE event.
- * 
- * 0 -- 4:3, 2 -- 16:9
- */
-uint8_t dvdnav_get_video_aspect(dvdnav_t *self);
-
-/*
- * Get video scaling permissions.
- * The scaling permission does only change on VTS boundaries.
- * See the DVDNAV_VTS_CHANGE event.
- *
- * bit0 set = deny letterboxing, bit1 set = deny pan&scan
- */
-uint8_t dvdnav_get_video_scale_permission(dvdnav_t *self);
-
-/*
- * Converts a *logical* audio stream id into language code
- * (returns 0xffff if no such stream).
- */
-uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream);
-
-/*
- * Returns the format of *logical* audio stream 'stream'
- * (returns 0xffff if no such stream).
- */
-uint16_t dvdnav_audio_stream_format(dvdnav_t *self, uint8_t stream);
-
-/*
- * Returns number of channelsn in *logical* audio stream 'stream'
- * (returns 0xffff if no such stream).
- */
-uint16_t dvdnav_audio_stream_channels(dvdnav_t *self, uint8_t stream);
-
-/*
- * Converts a *logical* subpicture stream id into country code 
- * (returns 0xffff if no such stream).
- */
-uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *self, uint8_t stream);
-
-/*
- * Converts a *physical* (MPEG) audio stream id into a logical stream number.
- */
-int8_t dvdnav_get_audio_logical_stream(dvdnav_t *self, uint8_t audio_num);
-
-#define HAVE_GET_AUDIO_ATTR
-/*
- * Get audio attr
- */
-dvdnav_status_t dvdnav_get_audio_attr(dvdnav_t *self, uint8_t audio_mum, audio_attr_t *audio_attr);
-
-/*
- * Converts a *physical* (MPEG) subpicture stream id into a logical stream number.
- */
-int8_t dvdnav_get_spu_logical_stream(dvdnav_t *self, uint8_t subp_num);
-
-#define HAVE_GET_SPU_ATTR
-/*
- * Get spu attr
- */
-dvdnav_status_t dvdnav_get_spu_attr(dvdnav_t *self, uint8_t audio_mum, subp_attr_t *subp_attr);
-
-/*
- * Get active audio stream.
- */
-int8_t dvdnav_get_active_audio_stream(dvdnav_t *self);
-
-/*
- * Get active spu stream.
- */
-int8_t dvdnav_get_active_spu_stream(dvdnav_t *self);
-
-/* 
- * Get the set of user operations that are currently prohibited.
- * There are potentially new restrictions right after 
- * DVDNAV_CHANNEL_HOP and DVDNAV_NAV_PACKET.
- */
-user_ops_t dvdnav_get_restrictions(dvdnav_t *self);
-
-
-/*********************************************************************
- * multiple angles                                                   *
- *********************************************************************/
-
-/*
- * The libdvdnav library abstracts away the difference between seamless and
- * non-seamless angles. From the point of view of the programmer you just set the
- * angle number and all is well in the world. You will always see only the
- * selected angle coming from the get_next_block functions.
- *
- * Note:
- * It is quite possible that some tremendously strange DVD feature might change the
- * angle number from under you. Generally you should always view the results from
- * dvdnav_get_angle_info() as definitive only up to the next time you call
- * dvdnav_get_next_block().
- */
-
-/*
- * Sets the current angle. If you try to follow a non existant angle
- * the call fails.
- */
-dvdnav_status_t dvdnav_angle_change(dvdnav_t *self, int32_t angle);
-
-/*
- * Returns the current angle and number of angles present.
- */
-dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int32_t *current_angle,
-				      int32_t *number_of_angles);
-
-/*********************************************************************
- * domain queries                                                    *
- *********************************************************************/
-
-/*
- * Are we in the First Play domain?
- */
-int8_t dvdnav_is_domain_fp(dvdnav_t *self);
-
-/*
- * Are we in the Video management Menu domain?
- */
-int8_t dvdnav_is_domain_vmgm(dvdnav_t *self);
-
-/*
- * Are we in the Video Title Menu domain?
- */
-int8_t dvdnav_is_domain_vtsm(dvdnav_t *self);
-
-/*
- * Are we in the Video Title Set domain?
- */
-int8_t dvdnav_is_domain_vts(dvdnav_t *self);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* DVDNAV_H_INCLUDED */
--- a/dvdnav_events.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-/* 
- * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-/*
- * This header defines events and event types 
- */
-
-#ifndef DVDNAV_EVENTS_H_INCLUDED
-#define DVDNAV_EVENTS_H_INCLUDED
-
-/*
- * DVDNAV_BLOCK_OK
- *
- * A regular data block from the DVD has been returned.
- * This one should be demuxed and decoded for playback.
- */
-#define DVDNAV_BLOCK_OK			 0
-
-
-/*
- * DVDNAV_NOP
- *
- * Just ignore this.
- */
-#define DVDNAV_NOP			 1
-
-
-/*
- * DVDNAV_STILL_FRAME
- *
- * We have reached a still frame. The player application should wait
- * the amount of time specified by the still's length while still handling
- * user input to make menus and other interactive stills work.
- * The last delivered frame should be kept showing.
- * Once the still has timed out, call dvdnav_skip_still().
- * A length of 0xff means an infinite still which has to be skipped
- * indirectly by some user interaction.
- */
-#define DVDNAV_STILL_FRAME		 2
-
-typedef struct {
-  /* The length (in seconds) the still frame should be displayed for,
-   * or 0xff if infinite. */
-  int length;
-} dvdnav_still_event_t;
-
-
-/*
- * DVDNAV_SPU_STREAM_CHANGE
- *
- * Inform the SPU decoding/overlaying engine to switch SPU channels.
- */
-#define DVDNAV_SPU_STREAM_CHANGE	 3
-
-typedef struct {
-  /* The physical (MPEG) stream number for widescreen SPU display.
-   * Use this, if you blend the SPU on an anamorphic image before
-   * unsqueezing it. */
-  int physical_wide;
-
-  /* The physical (MPEG) stream number for letterboxed display.
-   * Use this, if you blend the SPU on an anamorphic image after
-   * unsqueezing it. */
-  int physical_letterbox;
-
-  /* The physical (MPEG) stream number for pan&scan display.
-   * Use this, if you blend the SPU on an anamorphic image after
-   * unsqueezing it the pan&scan way. */
-  int physical_pan_scan;
-  
-  /* The logical (DVD) stream number. */
-  int logical;
-} dvdnav_spu_stream_change_event_t;
-
-
-/*
- * DVDNAV_AUDIO_STREAM_CHANGE
- *
- * Inform the audio decoder to switch channels.
- */
-#define DVDNAV_AUDIO_STREAM_CHANGE	 4
-
-typedef struct {
-  /* The physical (MPEG) stream number. */
-  int physical;
-
-  /* The logical (DVD) stream number. */
-  int logical;
-} dvdnav_audio_stream_change_event_t;
-
-
-/*
- * DVDNAV_VTS_CHANGE
- *
- * Some status information like video aspect and video scale permissions do
- * not change inside a VTS. Therefore this event can be used to query such
- * information only when necessary and update the decoding/displaying
- * accordingly.
- */
-#define DVDNAV_VTS_CHANGE		 5
-
-typedef struct {
-  int old_vtsN;                 /* the old VTS number */
-  dvd_read_domain_t old_domain; /* the old domain */
-  int new_vtsN;                 /* the new VTS number */
-  dvd_read_domain_t new_domain; /* the new domain */
-} dvdnav_vts_change_event_t;
-
-
-/*
- * DVDNAV_CELL_CHANGE
- *
- * Some status information like the current Title and Part numbers do not
- * change inside a cell. Therefore this event can be used to query such
- * information only when necessary and update the decoding/displaying
- * accordingly.
- * Some useful information for accurate time display is also reported
- * together with this event.
- */
-#define DVDNAV_CELL_CHANGE		 6
-
-typedef struct {
-  int     cellN;       /* the new cell number */
-  int     pgN;         /* the current program number */
-  int64_t cell_length; /* the length of the current cell in PTS ticks */
-  int64_t pg_length;   /* the length of the current program in PTS ticks */
-  int64_t pgc_length;  /* the length of the current program chain in PTS ticks */
-  int64_t cell_start;  /* the start time of the current cell relatively to the PGC in PTS ticks */
-  int64_t pg_start;    /* the start time of the current PG relatively to the PGC in PTS ticks */
-} dvdnav_cell_change_event_t;
-
-
-/*
- * DVDNAV_NAV_PACKET
- *
- * NAV packets are useful for various purposes. They define the button
- * highlight areas and VM commands of DVD menus, so they should in any
- * case be sent to the SPU decoder/overlaying engine for the menus to work.
- * NAV packets also provide a way to detect PTS discontinuities, because
- * they carry the start and end PTS values for the current VOBU.
- * (pci.vobu_s_ptm and pci.vobu_e_ptm) Whenever the start PTS of the
- * current NAV does not match the end PTS of the previous NAV, a PTS
- * discontinuity has occured.
- * NAV packets can also be used for time display, because they are
- * timestamped relatively to the current Cell.
- */
-#define DVDNAV_NAV_PACKET		 7
-
-
-/*
- * DVDNAV_STOP
- *
- * Applications should end playback here. A subsequent dvdnav_get_next_block()
- * call will restart the VM from the beginning of the DVD.
- */
-#define DVDNAV_STOP			 8
-
-
-/*
- * DVDNAV_HIGHLIGHT
- *
- * The current button highlight changed. Inform the overlaying engine to
- * highlight a different button. Please note, that at the moment only mode 1
- * highlights are reported this way. That means, when the button highlight
- * has been moved around by some function call, you will receive an event
- * telling you the new button. But when a button gets activated, you have
- * to handle the mode 2 highlighting (that is some different colour the
- * button turns to on activation) in your application.
- */
-#define DVDNAV_HIGHLIGHT		 9
-
-typedef struct {
-  /* highlight mode: 0 - hide, 1 - show, 2 - activate, currently always 1 */
-  int display;
-
-  /* FIXME: these fields are currently not set */
-  uint32_t palette;     /* The CLUT entries for the highlight palette 
-			   (4-bits per entry -> 4 entries) */
-  uint16_t sx,sy,ex,ey; /* The start/end x,y positions */
-  uint32_t pts;         /* Highlight PTS to match with SPU */
-
-  /* button number for the SPU decoder/overlaying engine */
-  uint32_t buttonN;
-} dvdnav_highlight_event_t;
-
-
-/*
- * DVDNAV_SPU_CLUT_CHANGE
- *
- * Inform the SPU decoder/overlaying engine to update its colour lookup table.
- * The CLUT is given as 16 uint32_t's in the buffer.
- */
-#define DVDNAV_SPU_CLUT_CHANGE		10
-
-
-/*
- * DVDNAV_HOP_CHANNEL
- *
- * A non-seamless operation has been performed. Applications can drop all
- * their internal fifo's content, which will speed up the response.
- */
-#define DVDNAV_HOP_CHANNEL		12
-
-
-/*
- * DVDNAV_WAIT
- *
- * We have reached a point in DVD playback, where timing is critical.
- * Player application with internal fifos can introduce state
- * inconsistencies, because libdvdnav is always the fifo's length
- * ahead in the stream compared to what the application sees.
- * Such applications should wait until their fifos are empty
- * when they receive this type of event.
- * Once this is achieved, call dvdnav_skip_wait().
- */
-#define DVDNAV_WAIT			13
-
-
-#endif /* DVDNAV_EVENTS_H_INCLUDED */
--- a/dvdnav_internal.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/* 
- * Copyright (C) 2001-2004 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifndef DVDNAV_INTERNAL_H_INCLUDED
-#define DVDNAV_INTERNAL_H_INCLUDED
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef WIN32
-
-/* pthread_mutex_* wrapper for win32 */
-#include <windows.h>
-#include <process.h>
-typedef CRITICAL_SECTION pthread_mutex_t;
-#define pthread_mutex_init(a, b) InitializeCriticalSection(a)
-#define pthread_mutex_lock(a)    EnterCriticalSection(a)
-#define pthread_mutex_unlock(a)  LeaveCriticalSection(a)
-#define pthread_mutex_destroy(a)
-
-/* replacement gettimeofday implementation */
-#include <sys/timeb.h>
-static inline int _private_gettimeofday( struct timeval *tv, void *tz )
-{
-  struct timeb t;
-  ftime( &t );
-  tv->tv_sec = t.time;
-  tv->tv_usec = t.millitm * 1000;
-  return 0;
-}
-#define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ))
-#include <io.h> /* read() */
-#define lseek64 _lseeki64
-
-#else
-
-#include <pthread.h>
-
-#endif /* WIN32 */
-
-/* where should libdvdnav write its messages (stdout/stderr) */
-#define MSG_OUT stdout
-
-/* Maximum length of an error string */
-#define MAX_ERR_LEN 255
-
-/* Use the POSIX PATH_MAX if available */
-#ifdef PATH_MAX
-#define MAX_PATH_LEN PATH_MAX
-#else
-#define MAX_PATH_LEN 255 /* Arbitrary */
-#endif
-
-#ifndef DVD_VIDEO_LB_LEN
-#define DVD_VIDEO_LB_LEN 2048
-#endif
-
-typedef struct read_cache_s read_cache_t;
-
-/*
- * These are defined here because they are
- * not in ifo_types.h, they maybe one day 
- */
-
-#ifndef audio_status_t
-typedef struct {
-#ifdef WORDS_BIGENDIAN
-  unsigned int available     : 1;
-  unsigned int zero1         : 4;
-  unsigned int stream_number : 3;
-  uint8_t zero2;
-#else
-  uint8_t zero2;
-  unsigned int stream_number : 3;
-  unsigned int zero1         : 4;  
-  unsigned int available     : 1;
-#endif
-} ATTRIBUTE_PACKED audio_status_t;
-#endif
-
-#ifndef spu_status_t
-typedef struct {
-#ifdef WORDS_BIGENDIAN
-  unsigned int available               : 1;
-  unsigned int zero1                   : 2;
-  unsigned int stream_number_4_3       : 5;
-  unsigned int zero2                   : 3;
-  unsigned int stream_number_wide      : 5;
-  unsigned int zero3                   : 3;
-  unsigned int stream_number_letterbox : 5;
-  unsigned int zero4                   : 3;
-  unsigned int stream_number_pan_scan  : 5;
-#else
-  unsigned int stream_number_pan_scan  : 5;
-  unsigned int zero4                   : 3;
-  unsigned int stream_number_letterbox : 5;
-  unsigned int zero3                   : 3;
-  unsigned int stream_number_wide      : 5;
-  unsigned int zero2                   : 3;
-  unsigned int stream_number_4_3       : 5;
-  unsigned int zero1                   : 2;
-  unsigned int available               : 1;
-#endif
-} ATTRIBUTE_PACKED spu_status_t;
-#endif
-
-typedef struct dvdnav_vobu_s {
-  int32_t vobu_start;  /* Logical Absolute. MAX needed is 0x300000 */
-  int32_t vobu_length;
-  int32_t blockN;      /* Relative offset */
-  int32_t vobu_next;   /* Relative offset */
-} dvdnav_vobu_t;  
-   
-/** The main DVDNAV type **/
-
-struct dvdnav_s {
-  /* General data */
-  char        path[MAX_PATH_LEN]; /* Path to DVD device/dir */
-  dvd_file_t *file;               /* Currently opened file */
- 
-  /* Position data */
-  vm_position_t position_next;
-  vm_position_t position_current;
-  dvdnav_vobu_t vobu;  
-
-  /* NAV data */
-  pci_t pci;
-  dsi_t dsi;
-  uint32_t last_cmd_nav_lbn;      /* detects when a command is issued on an already left NAV */
-  
-  /* Flags */
-  int skip_still;                 /* Set when skipping a still */
-  int sync_wait;                  /* applications should wait till they are in sync with us */
-  int sync_wait_skip;             /* Set when skipping wait state */
-  int spu_clut_changed;           /* The SPU CLUT changed */ 
-  int started;                    /* vm_start has been called? */
-  int use_read_ahead;             /* 1 - use read-ahead cache, 0 - don't */
-  int pgc_based;                  /* positioning works PGC based instead of PG based */
-  int cur_cell_time;              /* time expired since the beginning of the current cell, read from the dsi */
-  
-  /* VM */
-  vm_t *vm;
-  pthread_mutex_t vm_lock;
-
-  /* Read-ahead cache */
-  read_cache_t *cache;
-
-  /* Errors */
-  char err_str[MAX_ERR_LEN];
-};
-
-/** HELPER FUNCTIONS **/
-
-/* converts a dvd_time_t to PTS ticks */
-int64_t dvdnav_convert_time(dvd_time_t *time);
-
-/** USEFUL MACROS **/
-
-#ifdef __GNUC__
-#define printerrf(format, args...) \
-	do { if (this) snprintf(this->err_str, MAX_ERR_LEN, format, ## args); } while (0)
-#else
-#ifdef _MSC_VER
-#define printerrf(str) \
-	do { if (this) snprintf(this->err_str, MAX_ERR_LEN, str); } while (0)
-#else
-#define printerrf(...) \
-	do { if (this) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); } while (0)
-#endif /* WIN32 */
-#endif
-#define printerr(str) \
-	do { if (this) strncpy(this->err_str, str, MAX_ERR_LEN - 1); } while (0)
-
-#endif /* DVDNAV_INTERNAL_H_INCLUDED */
--- a/highlight.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,497 +0,0 @@
-/* 
- * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-#include <string.h>
-#include <sys/time.h>
-#include "nav_types.h"
-#include "dvd_types.h"
-#include "remap.h"
-#include "vm/decoder.h"
-#include "vm/vm.h"
-#include "vm/vmcmd.h"
-#include "dvdnav_internal.h"
-#include "dvdnav.h"
-
-/*
-#define BUTTON_TESTING
-*/
-
-#ifdef BUTTON_TESTING
-
-#include "nav_print.h"
-
-static void print_time(dvd_time_t *dtime) {
-  const char *rate;
-
-  assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
-  assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
-  assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
-  assert((dtime->frame_u&0xf) < 0xa);
-
-  fprintf(MSG_OUT,"%02x:%02x:%02x.%02x",
-         dtime->hour,
-         dtime->minute,
-         dtime->second,
-         dtime->frame_u & 0x3f);
-  switch((dtime->frame_u & 0xc0) >> 6) {
-  case 1:
-    rate = "25.00";
-    break;
-  case 3:
-    rate = "29.97";
-    break;
-  default:
-    rate = "(please send a bug report)";
-    break;
-  }
-  fprintf(MSG_OUT," @ %s fps", rate);
-}
-
-static void nav_print_PCI_GI(pci_gi_t *pci_gi) {
-  int32_t i;
-
-  fprintf(MSG_OUT,"libdvdnav: pci_gi:\n");
-  fprintf(MSG_OUT,"libdvdnav: nv_pck_lbn    0x%08x\n", pci_gi->nv_pck_lbn);
-  fprintf(MSG_OUT,"libdvdnav: vobu_cat      0x%04x\n", pci_gi->vobu_cat);
-  fprintf(MSG_OUT,"libdvdnav: vobu_uop_ctl  0x%08x\n", *(uint32_t*)&pci_gi->vobu_uop_ctl);
-  fprintf(MSG_OUT,"libdvdnav: vobu_s_ptm    0x%08x\n", pci_gi->vobu_s_ptm);
-  fprintf(MSG_OUT,"libdvdnav: vobu_e_ptm    0x%08x\n", pci_gi->vobu_e_ptm);
-  fprintf(MSG_OUT,"libdvdnav: vobu_se_e_ptm 0x%08x\n", pci_gi->vobu_se_e_ptm);
-  fprintf(MSG_OUT,"libdvdnav: e_eltm        ");
-  print_time(&pci_gi->e_eltm);
-  fprintf(MSG_OUT,"\n");
-
-  fprintf(MSG_OUT,"libdvdnav: vobu_isrc     \"");
-  for(i = 0; i < 32; i++) {
-    char c = pci_gi->vobu_isrc[i];
-    if((c >= ' ') && (c <= '~'))
-      fprintf(MSG_OUT,"%c", c);
-    else
-      fprintf(MSG_OUT,".");
-  }
-  fprintf(MSG_OUT,"\"\n");
-}
-
-static void nav_print_NSML_AGLI(nsml_agli_t *nsml_agli) {
-  int32_t i, j = 0;
-
-  for(i = 0; i < 9; i++)
-    j |= nsml_agli->nsml_agl_dsta[i];
-  if(j == 0)
-    return;
-
-  fprintf(MSG_OUT,"libdvdnav: nsml_agli:\n");
-  for(i = 0; i < 9; i++)
-    if(nsml_agli->nsml_agl_dsta[i])
-      fprintf(MSG_OUT,"libdvdnav: nsml_agl_c%d_dsta  0x%08x\n", i + 1,
-             nsml_agli->nsml_agl_dsta[i]);
-}
-
-static void nav_print_HL_GI(hl_gi_t *hl_gi, int32_t *btngr_ns, int32_t *btn_ns) {
-
-  if((hl_gi->hli_ss & 0x03) == 0)
-    return;
-
-  fprintf(MSG_OUT,"libdvdnav: hl_gi:\n");
-  fprintf(MSG_OUT,"libdvdnav: hli_ss        0x%01x\n", hl_gi->hli_ss & 0x03);
-  fprintf(MSG_OUT,"libdvdnav: hli_s_ptm     0x%08x\n", hl_gi->hli_s_ptm);
-  fprintf(MSG_OUT,"libdvdnav: hli_e_ptm     0x%08x\n", hl_gi->hli_e_ptm);
-  fprintf(MSG_OUT,"libdvdnav: btn_se_e_ptm  0x%08x\n", hl_gi->btn_se_e_ptm);
-
-  *btngr_ns = hl_gi->btngr_ns;
-  fprintf(MSG_OUT,"libdvdnav: btngr_ns      %d\n",  hl_gi->btngr_ns);
-  fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty    0x%02x\n", 1, hl_gi->btngr1_dsp_ty);
-  fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty    0x%02x\n", 2, hl_gi->btngr2_dsp_ty);
-  fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty    0x%02x\n", 3, hl_gi->btngr3_dsp_ty);
-
-  fprintf(MSG_OUT,"libdvdnav: btn_ofn       %d\n", hl_gi->btn_ofn);
-  *btn_ns = hl_gi->btn_ns;
-  fprintf(MSG_OUT,"libdvdnav: btn_ns        %d\n", hl_gi->btn_ns);
-  fprintf(MSG_OUT,"libdvdnav: nsl_btn_ns    %d\n", hl_gi->nsl_btn_ns);
-  fprintf(MSG_OUT,"libdvdnav: fosl_btnn     %d\n", hl_gi->fosl_btnn);
-  fprintf(MSG_OUT,"libdvdnav: foac_btnn     %d\n", hl_gi->foac_btnn);
-}
-
-static void nav_print_BTN_COLIT(btn_colit_t *btn_colit) {
-  int32_t i, j;
-
-  j = 0;
-  for(i = 0; i < 6; i++)
-    j |= btn_colit->btn_coli[i/2][i&1];
-  if(j == 0)
-    return;
-
-  fprintf(MSG_OUT,"libdvdnav: btn_colit:\n");
-  for(i = 0; i < 3; i++)
-    for(j = 0; j < 2; j++)
-      fprintf(MSG_OUT,"libdvdnav: btn_cqoli %d  %s_coli:  %08x\n",
-             i, (j == 0) ? "sl" : "ac",
-             btn_colit->btn_coli[i][j]);
-}
-
-static void nav_print_BTNIT(btni_t *btni_table, int32_t btngr_ns, int32_t btn_ns) {
-  int32_t i, j, k;
-
-  fprintf(MSG_OUT,"libdvdnav: btnit:\n");
-  fprintf(MSG_OUT,"libdvdnav: btngr_ns: %i\n", btngr_ns);
-  fprintf(MSG_OUT,"libdvdnav: btn_ns: %i\n", btn_ns);
-
-  if(btngr_ns == 0)
-    return;
-
-  for(i = 0; i < btngr_ns; i++) {
-    for(j = 0; j < (36 / btngr_ns); j++) {
-      if(j < btn_ns) {
-        btni_t *btni = &btni_table[(36 / btngr_ns) * i + j];
-
-        fprintf(MSG_OUT,"libdvdnav: group %d btni %d:  ", i+1, j+1);
-        fprintf(MSG_OUT,"btn_coln %d, auto_action_mode %d\n",
-               btni->btn_coln, btni->auto_action_mode);
-        fprintf(MSG_OUT,"libdvdnav: coords   (%d, %d) .. (%d, %d)\n",
-               btni->x_start, btni->y_start, btni->x_end, btni->y_end);
-
-        fprintf(MSG_OUT,"libdvdnav: up %d, ", btni->up);
-        fprintf(MSG_OUT,"down %d, ", btni->down);
-        fprintf(MSG_OUT,"left %d, ", btni->left);
-        fprintf(MSG_OUT,"right %d\n", btni->right);
-        for(k = 0; k < 8; k++) {
-          fprintf(MSG_OUT, "libdvdnav: %02x ", btni->cmd.bytes[k]);
-        }
-        fprintf(MSG_OUT, "| ");
-#ifdef TRACE
-        vm_print_mnemonic(&btni->cmd);
-#endif
-        fprintf(MSG_OUT, "\n");
-      }
-    }
-  }
-}
-
-static void nav_print_HLI(hli_t *hli) {
-  int32_t btngr_ns = 0, btn_ns = 0;
-
-  fprintf(MSG_OUT,"libdvdnav: hli:\n");
-  nav_print_HL_GI(&hli->hl_gi, & btngr_ns, & btn_ns);
-  nav_print_BTN_COLIT(&hli->btn_colit);
-  nav_print_BTNIT(hli->btnit, btngr_ns, btn_ns);
-}
-
-void nav_print_PCI(pci_t *pci) {
-  fprintf(MSG_OUT,"libdvdnav: pci packet:\n");
-  nav_print_PCI_GI(&pci->pci_gi);
-  nav_print_NSML_AGLI(&pci->nsml_agli);
-  nav_print_HLI(&pci->hli);
-}
-
-#endif
-
-
-/* Highlighting API calls */
-
-dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int32_t *button) {
-  /* Simply return the appropriate value based on the SPRM */
-  if(((*button) = this->position_current.button) == -1)
-    (*button) = this->vm->state.HL_BTNN_REG >> 10;
-  
-  return DVDNAV_STATUS_OK;
-}
-
-static btni_t *get_current_button(dvdnav_t *this, pci_t *pci) {
-  int32_t button = 0;
-
-  if(!pci->hli.hl_gi.hli_ss) {
-    printerr("Not in a menu.");
-    return NULL;
-  }
-  if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
-    printerr("This NAV has already been left.");
-    return NULL;
-  }
-
-  button = this->vm->state.HL_BTNN_REG >> 10;
-#ifdef BUTTON_TESTING
-  nav_print_PCI(pci);
-#endif
-  
-  return &(pci->hli.btnit[button-1]);
-}
-
-static dvdnav_status_t button_auto_action(dvdnav_t *this, pci_t *pci) {
-  if (get_current_button(this, pci)->auto_action_mode)
-    return dvdnav_button_activate(this, pci);
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this, pci_t *pci) {
-  btni_t *button_ptr;
-  
-  if(!(button_ptr = get_current_button(this, pci)))
-    return DVDNAV_STATUS_ERR;
-
-  dvdnav_button_select(this, pci, button_ptr->up);
-  return button_auto_action(this, pci);
-}
-
-dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this, pci_t *pci) {
-  btni_t *button_ptr;
-  
-  if(!(button_ptr = get_current_button(this, pci)))
-    return DVDNAV_STATUS_ERR;
-
-  dvdnav_button_select(this, pci, button_ptr->down);
-  return button_auto_action(this, pci);
-}
-
-dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this, pci_t *pci) {
-  btni_t *button_ptr;
-  
-  if(!(button_ptr = get_current_button(this, pci)))
-    return DVDNAV_STATUS_ERR;
-
-  dvdnav_button_select(this, pci, button_ptr->right);
-  return button_auto_action(this, pci);
-}
-
-dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) {
-  btni_t *button_ptr;
-  
-  if(!(button_ptr = get_current_button(this, pci)))
-    return DVDNAV_STATUS_ERR;
-
-  dvdnav_button_select(this, pci, button_ptr->left);
-  return button_auto_action(this, pci);
-}
-
-dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode, 
-					  dvdnav_highlight_area_t *highlight) {
-  btni_t *button_ptr;
-
-#ifdef BUTTON_TESTING
-  fprintf(MSG_OUT, "libdvdnav: Button get_highlight_area %i\n", button);
-#endif
-  
-  if(!nav_pci->hli.hl_gi.hli_ss)
-    return DVDNAV_STATUS_ERR;
-  if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns))
-    return DVDNAV_STATUS_ERR;
-
-
-  button_ptr = &nav_pci->hli.btnit[button-1];
-
-  highlight->sx = button_ptr->x_start;
-  highlight->sy = button_ptr->y_start;
-  highlight->ex = button_ptr->x_end;
-  highlight->ey = button_ptr->y_end;
-  if(button_ptr->btn_coln != 0) {
-    highlight->palette = nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode];
-  } else {
-    highlight->palette = 0;
-  }
-  highlight->pts = nav_pci->hli.hl_gi.hli_s_ptm;
-  highlight->buttonN = button;
-#ifdef BUTTON_TESTING
-  fprintf(MSG_OUT, "libdvdnav: highlight: Highlight area is (%u,%u)-(%u,%u), display = %i, button = %u\n",
-               button_ptr->x_start, button_ptr->y_start,
-               button_ptr->x_end, button_ptr->y_end,
-               1,
-               button);
-#endif
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) {
-  int32_t button;
-  btni_t *button_ptr = NULL;
-
-  if(!pci->hli.hl_gi.hli_ss) {
-    printerr("Not in a menu.");
-    return DVDNAV_STATUS_ERR;
-  }
-  if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
-    printerr("This NAV has already been left.");
-    return DVDNAV_STATUS_ERR;
-  }
-  pthread_mutex_lock(&this->vm_lock); 
-
-  button = this->vm->state.HL_BTNN_REG >> 10;
-
-  if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
-    /* Special code to handle still menus with no buttons.
-     * The navigation is expected to report to the application that a STILL is
-     * underway. In turn, the application is supposed to report to the user
-     * that the playback is paused. The user is then expected to undo the pause,
-     * ie: hit play. At that point, the navigation should release the still and
-     * go to the next Cell.
-     * Explanation by Mathieu Lacage <mathieu_lacage@realmagic.fr>
-     * Code added by jcdutton.
-     */
-    if (this->position_current.still != 0) {
-      /* In still, but no buttons. */
-      vm_get_next_cell(this->vm);
-      this->position_current.still = 0;
-      this->sync_wait = 0;
-      this->last_cmd_nav_lbn = pci->pci_gi.nv_pck_lbn;
-      pthread_mutex_unlock(&this->vm_lock);
-      /* clear error message */
-      printerr("");
-      return DVDNAV_STATUS_OK;
-    }
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_ERR;
-  }
-  
-  button_ptr = get_current_button(this, pci);
-  /* Finally, make the VM execute the appropriate code and probably
-   * scedule a jump */
-#ifdef BUTTON_TESTING
-  fprintf(MSG_OUT, "libdvdnav: Evaluating Button Activation commands.\n");
-#endif
-  if(vm_exec_cmd(this->vm, &(button_ptr->cmd)) == 1) {
-    /* Command caused a jump */
-    this->vm->hop_channel++;
-    this->position_current.still = 0;
-    this->last_cmd_nav_lbn = pci->pci_gi.nv_pck_lbn;
-  }
-  
-  pthread_mutex_unlock(&this->vm_lock); 
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *this, int32_t button, vm_cmd_t *cmd)
-{
-  pthread_mutex_lock(&this->vm_lock);
-  /* make the VM execute the appropriate code and probably
-   * schedule a jump */
-#ifdef BUTTON_TESTING
-  fprintf(MSG_OUT, "libdvdnav: dvdnav_button_activate_cmd: Evaluating Button Activation commands.\n");
-#endif
-  if(button > 0) {
-    this->vm->state.HL_BTNN_REG = (button << 10);
-    if(vm_exec_cmd(this->vm, cmd) == 1) {
-      /* Command caused a jump */
-      this->vm->hop_channel++;
-    }
-  }
-  /* Always remove still, because some still menus have no buttons. */
-  this->position_current.still = 0;
-  this->sync_wait = 0;
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_OK;
-}  
-
-dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int32_t button) {
-  if(!pci->hli.hl_gi.hli_ss) {
-    printerr("Not in a menu.");
-    return DVDNAV_STATUS_ERR;
-  }
-  if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
-    printerr("This NAV has already been left.");
-    return DVDNAV_STATUS_ERR;
-  }
- 
-#ifdef BUTTON_TESTING
-  fprintf(MSG_OUT, "libdvdnav: Button select %i\n", button); 
-#endif
-  
-  if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
-    printerr("Button does not exist.");
-    return DVDNAV_STATUS_ERR;
-  }
-  
-  this->vm->state.HL_BTNN_REG = (button << 10);
-  this->position_current.button = -1; /* Force Highligh change */
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci, 
-						  int32_t button) {
-  /* A trivial function */
-  if(dvdnav_button_select(this, pci, button) != DVDNAV_STATUS_ERR)
-    return dvdnav_button_activate(this, pci);
-  return DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, pci_t *pci, int32_t x, int32_t y) {
-  int32_t button, cur_button;
-  int32_t best,dist,d;
-  int32_t mx,my,dx,dy;
-
-  if(!pci->hli.hl_gi.hli_ss) {
-    printerr("Not in a menu.");
-    return DVDNAV_STATUS_ERR;
-  }
-  if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) {
-    printerr("This NAV has already been left.");
-    return DVDNAV_STATUS_ERR;
-  }
-
-  cur_button = this->vm->state.HL_BTNN_REG >> 10;
-
-  best = 0;
-  dist = 0x08000000; /* >> than  (720*720)+(567*567); */
-  
-  /* Loop through all buttons */
-  for(button = 1; button <= pci->hli.hl_gi.btn_ns; button++) {
-    btni_t *button_ptr = &(pci->hli.btnit[button-1]);
-
-    if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) &&
-       (y >= button_ptr->y_start) && (y <= button_ptr->y_end)) {
-      mx = (button_ptr->x_start + button_ptr->x_end)/2;
-      my = (button_ptr->y_start + button_ptr->y_end)/2;
-      dx = mx - x;
-      dy = my - y;
-      d = (dx*dx) + (dy*dy);
-      /* If the mouse is within the button and the mouse is closer
-       * to the center of this button then it is the best choice. */
-      if(d < dist) {
-        dist = d;
-        best = button;
-      }
-    }
-  }
-  /* As an efficiency measure, only re-select the button
-   * if it is different to the previously selected one. */
-  if (best != 0 && best != cur_button)
-    dvdnav_button_select(this, pci, best);
-
-  /* return DVDNAV_STATUS_OK only if we actually found a matching button */
-  return best ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, pci_t *pci, int32_t x, int32_t y) {
-  /* A trivial function */
-  if(dvdnav_mouse_select(this, pci, x,y) != DVDNAV_STATUS_ERR)
-    return dvdnav_button_activate(this, pci);
-  return DVDNAV_STATUS_ERR;
-}
--- a/navigation.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-/* 
- * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
-#include <sys/time.h>
-#include "dvd_types.h"
-#include "nav_types.h"
-#include "ifo_types.h"
-#include "remap.h"
-#include "vm/decoder.h"
-#include "vm/vm.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-
-/* Navigation API calls */
-
-dvdnav_status_t dvdnav_still_skip(dvdnav_t *this) {
-  this->position_current.still = 0;
-  this->skip_still = 1;
-  this->sync_wait = 0;
-  this->sync_wait_skip = 1;
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_wait_skip(dvdnav_t *this) {
-  this->sync_wait = 0;
-  this->sync_wait_skip = 1;
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *this, int32_t *titles) {
-  if (!this->vm->vmgi) {
-    printerr("Bad VM state.");
-    return DVDNAV_STATUS_ERR;
-  }
-
-  (*titles) = vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts;
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *this, int32_t title, int32_t *parts) {
-  if (!this->vm->vmgi) {
-    printerr("Bad VM state.");
-    return DVDNAV_STATUS_ERR;
-  }
-  if ((title < 1) || (title > vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts) ) {
-    printerr("Passed a title number out of range.");
-    return DVDNAV_STATUS_ERR;
-  }
-
-  (*parts) = vm_get_vmgi(this->vm)->tt_srpt->title[title-1].nr_of_ptts;
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int32_t *title, int32_t *part) {
-  int32_t retval;
-  
-  pthread_mutex_lock(&this->vm_lock);
-  if (!this->vm->vtsi || !this->vm->vmgi) {
-    printerr("Bad VM state.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  if (!this->started) {
-    printerr("Virtual DVD machine not started.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  if ( (this->vm->state.domain == VTSM_DOMAIN)
-      || (this->vm->state.domain == VMGM_DOMAIN) ) {
-    /* Get current Menu ID: into *part. */
-    if(! vm_get_current_menu(this->vm, part)) {
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_ERR;
-    }
-    if (*part > -1) {
-      *title = 0;
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_OK;
-    }
-  }
-  if (this->vm->state.domain == VTS_DOMAIN) {
-    retval = vm_get_current_title_part(this->vm, title, part);
-    pthread_mutex_unlock(&this->vm_lock);
-    return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
-  }
-  printerr("Not in a title or menu.");
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int32_t title) {
-  return dvdnav_part_play(this, title, 1);
-}
-
-dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) {
-  int32_t retval;
-
-  pthread_mutex_lock(&this->vm_lock);
-  if (!this->vm->vmgi) {
-    printerr("Bad VM state.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  if (!this->started) {
-    /* don't report an error but be nice */
-    vm_start(this->vm);
-    this->started = 1;
-  }
-  if (!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) {
-    printerr("Title out of range.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  if((part < 1) || (part > this->vm->vmgi->tt_srpt->title[title-1].nr_of_ptts)) {
-    printerr("Part out of range.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-
-  retval = vm_jump_title_part(this->vm, title, part);
-  if (retval)
-    this->vm->hop_channel++;
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *this, int32_t title,
-					   int32_t part, int32_t parts_to_play) {
-  /* FIXME: Implement auto-stop */
- if (dvdnav_part_play(this, title, part) == DVDNAV_STATUS_OK)
-   printerr("Not implemented yet.");
- return DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_time_play(dvdnav_t *this, int32_t title,
-				 uint64_t time) {
-  /* FIXME: Implement */
-  printerr("Not implemented yet.");
-  return DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_stop(dvdnav_t *this) {
-  pthread_mutex_lock(&this->vm_lock);
-  this->vm->stopped = 1;
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_go_up(dvdnav_t *this) {
-  /* A nice easy function... delegate to the VM */
-  pthread_mutex_lock(&this->vm_lock);
-  vm_jump_up(this->vm);
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
--- a/read_cache.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
- *               2001-2004 the dvdnav project
- *
- * This file is part of libdvdnav, a DVD navigation library.
- *
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-/*
- * There was a multithreaded read ahead cache in here for some time, but
- * it had only been used for a short time. If you want to have a look at it,
- * search the CVS attic.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <sys/time.h>
-#include <time.h>
-#include "dvd_types.h"
-#include "nav_types.h"
-#include "ifo_types.h"
-#include "remap.h"
-#include "vm/decoder.h"
-#include "vm/vm.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-#include "read_cache.h"
-
-#define READ_CACHE_CHUNKS 10
-
-/* all cache chunks must be memory aligned to allow use of raw devices */
-#define ALIGNMENT 2048
-
-#define READ_AHEAD_SIZE_MIN 4
-#define READ_AHEAD_SIZE_MAX 512
-
-typedef struct read_cache_chunk_s {
-  uint8_t     *cache_buffer;
-  uint8_t     *cache_buffer_base;  /* used in malloc and free for alignment */
-  int32_t      cache_start_sector; /* -1 means cache invalid */
-  int32_t      cache_read_count;   /* this many sectors are already read */
-  size_t       cache_block_count;  /* this many sectors will go in this chunk */
-  size_t       cache_malloc_size;
-  int          cache_valid;
-  int          usage_count;  /* counts how many buffers where issued from this chunk */
-} read_cache_chunk_t;
-
-struct read_cache_s {
-  read_cache_chunk_t  chunk[READ_CACHE_CHUNKS];
-  int                 current;
-  int                 freeing;  /* is set to one when we are about to dispose the cache */
-  uint32_t            read_ahead_size;
-  int                 read_ahead_incr;
-  int                 last_sector;
-  pthread_mutex_t     lock;
-
-  /* Bit of strange cross-linking going on here :) -- Gotta love C :) */
-  dvdnav_t           *dvd_self;
-};
-
-/*
-#define READ_CACHE_TRACE 0
-*/
-
-#ifdef __GNUC__
-# if READ_CACHE_TRACE
-#  define dprintf(fmt, args...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt,  __func__ , ## args)
-# else
-#  define dprintf(fmt, args...) /* Nowt */
-# endif
-#else
-# if READ_CACHE_TRACE
-#  define dprintf(fmt, ...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt,  __func__ , __VA_ARGS__)
-# else
-#ifdef _MSC_VER
-#  define dprintf(fmt, str) /* Nowt */
-#else
-#  define dprintf(fmt, ...) /* Nowt */
-#endif /* _MSC_VER */
-# endif
-#endif
-
-
-read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) {
-  read_cache_t *self;
-  int i;
-
-  self = (read_cache_t *)malloc(sizeof(read_cache_t));
-
-  if(self) {
-    self->current = 0;
-    self->freeing = 0;
-    self->dvd_self = dvd_self;
-    self->last_sector = 0;
-    self->read_ahead_size = READ_AHEAD_SIZE_MIN;
-    self->read_ahead_incr = 0;
-    pthread_mutex_init(&self->lock, NULL);
-    dvdnav_read_cache_clear(self);
-    for (i = 0; i < READ_CACHE_CHUNKS; i++) {
-      self->chunk[i].cache_buffer = NULL;
-      self->chunk[i].usage_count = 0;
-    }
-  }
-
-  return self;
-}
-
-void dvdnav_read_cache_free(read_cache_t* self) {
-  dvdnav_t *tmp;
-  int i;
-
-  pthread_mutex_lock(&self->lock);
-  self->freeing = 1;
-  for (i = 0; i < READ_CACHE_CHUNKS; i++)
-    if (self->chunk[i].cache_buffer && self->chunk[i].usage_count == 0) {
-      free(self->chunk[i].cache_buffer_base);
-      self->chunk[i].cache_buffer = NULL;
-    }
-  pthread_mutex_unlock(&self->lock);
-
-  for (i = 0; i < READ_CACHE_CHUNKS; i++)
-    if (self->chunk[i].cache_buffer) return;
-
-  /* all buffers returned, free everything */
-  tmp = self->dvd_self;
-  pthread_mutex_destroy(&self->lock);
-  free(self);
-  free(tmp);
-}
-
-/* This function MUST be called whenever self->file changes. */
-void dvdnav_read_cache_clear(read_cache_t *self) {
-  int i;
-
-  if(!self)
-   return;
-
-  pthread_mutex_lock(&self->lock);
-  for (i = 0; i < READ_CACHE_CHUNKS; i++)
-    self->chunk[i].cache_valid = 0;
-  pthread_mutex_unlock(&self->lock);
-}
-
-/* This function is called just after reading the NAV packet. */
-void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count) {
-  int i, use;
-
-  if(!self)
-    return;
-
-  if(!self->dvd_self->use_read_ahead)
-    return;
-
-  pthread_mutex_lock(&self->lock);
-
-  /* find a free cache chunk that best fits the required size */
-  use = -1;
-  for (i = 0; i < READ_CACHE_CHUNKS; i++)
-    if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer &&
-        self->chunk[i].cache_malloc_size >= block_count &&
-        (use == -1 || self->chunk[use].cache_malloc_size > self->chunk[i].cache_malloc_size))
-      use = i;
-
-  if (use == -1) {
-    /* we haven't found a cache chunk, so we try to reallocate an existing one */
-    for (i = 0; i < READ_CACHE_CHUNKS; i++)
-      if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer &&
-          (use == -1 || self->chunk[use].cache_malloc_size < self->chunk[i].cache_malloc_size))
-        use = i;
-    if (use >= 0) {
-      self->chunk[use].cache_buffer_base = realloc(self->chunk[use].cache_buffer_base,
-        block_count * DVD_VIDEO_LB_LEN + ALIGNMENT);
-      self->chunk[use].cache_buffer =
-        (uint8_t *)(((uintptr_t)self->chunk[use].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT);
-      dprintf("pre_cache DVD read realloc happened\n");
-      self->chunk[use].cache_malloc_size = block_count;
-    } else {
-      /* we still haven't found a cache chunk, let's allocate a new one */
-      for (i = 0; i < READ_CACHE_CHUNKS; i++)
-        if (!self->chunk[i].cache_buffer) {
-	  use = i;
-	  break;
-	}
-      if (use >= 0) {
-        /* We start with a sensible figure for the first malloc of 500 blocks.
-         * Some DVDs I have seen venture to 450 blocks.
-         * This is so that fewer realloc's happen if at all.
-         */
-	self->chunk[i].cache_buffer_base =
-	  malloc((block_count > 500 ? block_count : 500) * DVD_VIDEO_LB_LEN + ALIGNMENT);
-	self->chunk[i].cache_buffer =
-	  (uint8_t *)(((uintptr_t)self->chunk[i].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT);
-	self->chunk[i].cache_malloc_size = block_count > 500 ? block_count : 500;
-	dprintf("pre_cache DVD read malloc %d blocks\n",
-	  (block_count > 500 ? block_count : 500 ));
-      }
-    }
-  }
-
-  if (use >= 0) {
-    self->chunk[use].cache_start_sector = sector;
-    self->chunk[use].cache_block_count = block_count;
-    self->chunk[use].cache_read_count = 0;
-    self->chunk[use].cache_valid = 1;
-    self->current = use;
-  } else {
-    dprintf("pre_caching was impossible, no cache chunk available\n");
-  }
-  pthread_mutex_unlock(&self->lock);
-}
-
-int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf) {
-  int i, use;
-  int start;
-  int size;
-  int incr;
-  uint8_t *read_ahead_buf;
-  int32_t res;
-
-  if(!self)
-    return 0;
-
-  use = -1;
-
-  if(self->dvd_self->use_read_ahead) {
-    /* first check, if sector is in current chunk */
-    read_cache_chunk_t cur = self->chunk[self->current];
-    if (cur.cache_valid && sector >= cur.cache_start_sector &&
-        sector <= (cur.cache_start_sector + cur.cache_read_count) &&
-        sector + block_count <= cur.cache_start_sector + cur.cache_block_count)
-      use = self->current;
-    else
-      for (i = 0; i < READ_CACHE_CHUNKS; i++)
-        if (self->chunk[i].cache_valid &&
-            sector >= self->chunk[i].cache_start_sector &&
-            sector <= (self->chunk[i].cache_start_sector + self->chunk[i].cache_read_count) &&
-            sector + block_count <= self->chunk[i].cache_start_sector + self->chunk[i].cache_block_count)
-            use = i;
-  }
-
-  if (use >= 0) {
-    read_cache_chunk_t *chunk;
-    
-    /* Increment read-ahead size if sector follows the last sector */
-    if (sector == (self->last_sector + 1)) {
-      if (self->read_ahead_incr < READ_AHEAD_SIZE_MAX)
-        self->read_ahead_incr++;
-    } else {
-      self->read_ahead_size = READ_AHEAD_SIZE_MIN;
-      self->read_ahead_incr = 0;
-    }
-    self->last_sector = sector;
-
-    /* The following resources need to be protected by a mutex :
-     *   self->chunk[*].cache_buffer
-     *   self->chunk[*].cache_malloc_size
-     *   self->chunk[*].usage_count
-     */
-    pthread_mutex_lock(&self->lock);
-    chunk = &self->chunk[use];
-    read_ahead_buf = chunk->cache_buffer + chunk->cache_read_count * DVD_VIDEO_LB_LEN;
-    *buf = chunk->cache_buffer + (sector - chunk->cache_start_sector) * DVD_VIDEO_LB_LEN;
-    chunk->usage_count++;
-    pthread_mutex_unlock(&self->lock);
-
-    dprintf("libdvdnav: sector=%d, start_sector=%d, last_sector=%d\n", sector, chunk->cache_start_sector, chunk->cache_start_sector + chunk->cache_block_count);
-
-    /* read_ahead_size */
-    incr = self->read_ahead_incr >> 1;
-    if ((self->read_ahead_size + incr) > READ_AHEAD_SIZE_MAX) {
-      self->read_ahead_size = READ_AHEAD_SIZE_MAX;
-    } else {
-      self->read_ahead_size += incr;
-    }
-
-    /* real read size */
-    start = chunk->cache_start_sector + chunk->cache_read_count;
-    if (chunk->cache_read_count + self->read_ahead_size > chunk->cache_block_count) {
-      size = chunk->cache_block_count - chunk->cache_read_count;
-    } else {
-      size = self->read_ahead_size;
-      /* ensure that the sector we want will be read */
-      if (sector >= chunk->cache_start_sector + chunk->cache_read_count + size)
-        size = sector - chunk->cache_start_sector - chunk->cache_read_count;
-    }
-    dprintf("libdvdnav: read_ahead_size=%d, size=%d\n", self->read_ahead_size, size);
-
-    if (size)
-      chunk->cache_read_count += DVDReadBlocks(self->dvd_self->file,
-                                               start,
-                                               size,
-                                               read_ahead_buf);
-
-    res = DVD_VIDEO_LB_LEN * block_count;
-
-  } else {
-
-    if (self->dvd_self->use_read_ahead)
-      dprintf("cache miss on sector %d\n", sector);
-
-    res = DVDReadBlocks(self->dvd_self->file,
-                        sector,
-                        block_count,
-                        *buf) * DVD_VIDEO_LB_LEN;
-  }
-
-  return res;
-
-}
-
-dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf) {
-  read_cache_t *cache;
-  int i;
-
-  if (!self)
-    return DVDNAV_STATUS_ERR;
-
-  cache = self->cache;
-  if (!cache)
-    return DVDNAV_STATUS_ERR;
-
-  pthread_mutex_lock(&cache->lock);
-  for (i = 0; i < READ_CACHE_CHUNKS; i++) {
-    if (cache->chunk[i].cache_buffer && buf >= cache->chunk[i].cache_buffer &&
-        buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN) {
-      cache->chunk[i].usage_count--;
-    }
-  }
-  pthread_mutex_unlock(&cache->lock);
-
-  if (cache->freeing)
-    /* when we want to dispose the cache, try freeing it now */
-    dvdnav_read_cache_free(cache);
-
-  return DVDNAV_STATUS_OK;
-}
--- a/read_cache.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/* 
- * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifndef __DVDNAV_READ_CACHE_H
-#define __DVDNAV_READ_CACHE_H
-
-/* Opaque cache type -- defined in dvdnav_internal.h */
-/* typedef struct read_cache_s read_cache_t; */
-
-/* EXPERIMENTAL: Setting the following to 1 will use an experimental multi-threaded
- *               read-ahead cache. 
- */
-#define _MULTITHREAD_ 0
-
-/* Constructor/destructors */
-read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self);
-void dvdnav_read_cache_free(read_cache_t* self);
-
-/* This function MUST be called whenever self->file changes. */
-void dvdnav_read_cache_clear(read_cache_t *self);
-/* This function is called just after reading the NAV packet. */
-void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count);
-/* This function will do the cache read.
- * The buffer handed in must be malloced to take one dvd block.
- * On a cache hit, a different buffer will be returned though.
- * Those buffers must _never_ be freed. */
-int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf);
-
-#endif /* __DVDNAV_READ_CACHE_H */
--- a/remap.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,265 +0,0 @@
-/*
- * This file is part of libdvdnav, a DVD navigation library.
- *
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifndef _MSC_VER 
-#include <sys/param.h>
-#include <sys/fcntl.h>
-#else
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 255
-#endif
-#endif /* _MSC_VER */
-
-#include <assert.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <sys/time.h>
-#include "dvd_types.h"
-#include "nav_types.h"
-#include "ifo_types.h"
-#include "remap.h"
-#include "vm/decoder.h"
-#include "vm/vm.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-
-struct block_s {
-    int domain;
-    int title;
-    int program;
-    unsigned long start_block;
-    unsigned long end_block;
-};
-
-struct remap_s {
-    char *title;
-    int maxblocks;
-    int nblocks;
-    int debug;
-    struct block_s *blocks;
-};
-
-static remap_t* remap_new( char *title) {
-    remap_t *map = malloc( sizeof(remap_t));
-    map->title = strdup(title);
-    map->maxblocks = 0;
-    map->nblocks = 0;
-    map->blocks = NULL;
-    map->debug = 0;
-    return map;
-}
-
-static int compare_block( block_t *a, block_t *b) {
-    /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */
-    if (a->domain < b->domain) {
-	return -1;
-    } else if (a->domain > b->domain) {
-	return 1;
-    }
-
-    if (a->title < b->title) {
-	return -1;
-    } else if (a->title > b->title) {
-	return 1;
-    }
-
-    if (a->program < b->program) {
-	return -1;
-    } else if (a->program > b->program) {
-	return 1;
-    }
-
-    if (a->end_block < b->start_block) {
-	return -1;
-    } else if (a->start_block > b->end_block) {
-	/*
-	 * if a->start_block == b->end_block then the two regions
-	 * aren't strictly overlapping, but they should be merged 
-	 * anyway since there are zero blocks between them
-	 */
-	return 1;
-    }
-
-    return 0;
-}
-
-static block_t *findblock( remap_t *map, block_t *key) {
-    int lb = 0;
-    int ub = map->nblocks - 1;
-    int mid;
-    int res;
-
-    while (lb <= ub) {
-	mid = lb + (ub - lb)/2;
-	res = compare_block( key, &map->blocks[mid]);
-	if (res < 0) {
-	    ub = mid-1;
-	} else if (res > 0) {
-	    lb = mid+1;
-	} else {
-	    return &map->blocks[mid];
-	}
-    }
-    return NULL;
-}
-
-static void mergeblock( block_t *b, block_t tmp) {
-    if (tmp.start_block < b->start_block) b->start_block = tmp.start_block;
-    if (tmp.end_block > b->end_block) b->end_block = tmp.end_block;
-}
-
-static void remap_add_node( remap_t *map, block_t block) {
-    block_t *b;
-    int n;
-    b = findblock( map, &block);
-    if (b) {
-	/* overlaps an existing block */
-	mergeblock( b, block);
-    } else {
-        /* new block */
-	if (map->nblocks >= map->maxblocks) {
-	    map->maxblocks += 20;
-	    map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);
-	}
-	n = map->nblocks++;
-	while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
-	    map->blocks[ n] = map->blocks[ n-1];
-	    n--;
-	}
-	map->blocks[ n] = block;
-    }
-}
-
-static int parseblock(char *buf, int *dom, int *tt, int *pg, 
-		      unsigned long *start, unsigned long *end) {
-    long tmp;
-    char *tok;
-    char *epos;
-    char *marker[]={"domain", "title", "program", "start", "end"};
-    int st = 0;
-    tok = strtok( buf, " ");
-    while (st < 5) {
-        if (strcmp(tok, marker[st])) return -st-1000;
-        tok = strtok( NULL, " ");
-        if (!tok) return -st-2000;
-        tmp = strtol( tok, &epos, 0);
-        if (*epos != 0 && *epos != ',') return -st-3000;
-        switch (st) {
-	    case 0:
-		*dom = (int)tmp;
-		break;
-	    case 1:
-		*tt = (int)tmp;
-		break;
-	    case 2:
-		*pg = (int)tmp;
-		break;
-	    case 3:
-		*start = tmp;
-		break;
-	    case 4:
-		*end = tmp;
-		break;
-	} 
-	st++;
-        tok = strtok( NULL, " ");
-    }
-    return st;
-}
-
-remap_t* remap_loadmap( char *title) {
-    char buf[160];
-    char fname[MAXPATHLEN];
-    char *home;
-    int res;
-    FILE *fp;
-    block_t tmp;
-    remap_t *map;
-
-    /* Build the map filename */
-    home = getenv("HOME"); assert(home);
-    snprintf(fname, sizeof(fname), "%s/.dvdnav/%s.map", home, title);
-
-    /* Open the map file */
-    fp = fopen( fname, "r");
-    if (!fp) {
-	fprintf(MSG_OUT, "libdvdnav: Unable to find map file '%s'\n", fname);
-	return NULL;
-    }
-
-    /* Load the map file */
-    map = remap_new( title);
-    while (fgets( buf, sizeof(buf), fp) != NULL) {
-        if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;
-        if (strncasecmp( buf, "debug", 5) == 0) {
-	    map->debug = 1;
-	} else {
-	    res = parseblock( buf, 
-		&tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);
-	    if (res != 5) {
-		fprintf(MSG_OUT, "libdvdnav: Ignoring map line (%d): %s\n", res, buf);
-		continue;
-	    }
-	    remap_add_node( map, tmp);
-	}
-    }
-    fclose(fp);
-
-    if (map->nblocks == 0 && map->debug == 0) {
-        free(map);
-        return NULL;
-    }
-    return map;
-}
-
-unsigned long remap_block( 
-	remap_t *map, int domain, int title, int program, 
-	unsigned long cblock, unsigned long offset) 
-{
-    block_t key;
-    block_t *b;
-
-    if (map->debug) {
-	fprintf(MSG_OUT, "libdvdnav: %s: domain %d, title %d, program %d, start %lx, next %lx\n",
-	    map->title, domain, title, program, cblock, cblock+offset);
-    }
-
-    key.domain = domain;
-    key.title = title;
-    key.program = program;
-    key.start_block = key.end_block = cblock + offset;
-    b = findblock( map, &key);
-    
-    if (b) {
-       if (map->debug) {
-	   fprintf(MSG_OUT, "libdvdnav: Redirected to %lx\n", b->end_block);
-       }
-       return b->end_block - cblock;
-    }
-    return offset;
-}
--- a/remap.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/* 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- */
-
-#ifndef __REMAP__H
-#define __REMAP__H
-typedef struct block_s block_t;
-
-typedef struct remap_s remap_t;
-
-remap_t* remap_loadmap( char *title);
-
-unsigned long remap_block( 
-	remap_t *map, int domain, int title, int program, 
-	unsigned long cblock, unsigned long offset);
-
-#endif
--- a/searching.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include "dvd_types.h"
-#include "nav_types.h"
-#include "ifo_types.h"
-#include "remap.h"
-#include "vm/decoder.h"
-#include "vm/vm.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-
-/*
-#define LOG_DEBUG
-*/
-
-/* Searching API calls */
-
-/* Scan the ADMAP for a particular block number. */
-/* Return placed in vobu. */
-/* Returns error status */
-/* FIXME: Maybe need to handle seeking outside current cell. */
-static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_t seekto_block, uint32_t *vobu) {
-  vobu_admap_t *admap = NULL;
-
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: Seeking to target %u ...\n", seekto_block);
-#endif
-  *vobu = -1;
-
-  /* Search through the VOBU_ADMAP for the nearest VOBU
-   * to the target block */
-  switch(domain) {
-  case FP_DOMAIN:
-  case VMGM_DOMAIN:
-    admap = this->vm->vmgi->menu_vobu_admap;
-    break;
-  case VTSM_DOMAIN:
-    admap = this->vm->vtsi->menu_vobu_admap;
-    break;
-  case VTS_DOMAIN:
-    admap = this->vm->vtsi->vts_vobu_admap;
-    break;
-  default:
-    fprintf(MSG_OUT, "libdvdnav: Error: Unknown domain for seeking.\n");
-  }
-  if(admap) {
-    uint32_t address = 0;
-    uint32_t vobu_start, next_vobu;
-    int admap_entries = (admap->last_byte + 1 - VOBU_ADMAP_SIZE)/VOBU_ADMAP_SIZE;
-
-    /* Search through ADMAP for best sector */
-    vobu_start = SRI_END_OF_CELL;
-    /* FIXME: Implement a faster search algorithm */
-    while(address < admap_entries) {
-      next_vobu = admap->vobu_start_sectors[address];
-
-      /* fprintf(MSG_OUT, "libdvdnav: Found block %u\n", next_vobu); */
-
-      if(vobu_start <= seekto_block && next_vobu > seekto_block)
-        break;
-      vobu_start = next_vobu;
-      address++;
-    }
-    *vobu = vobu_start;
-    return DVDNAV_STATUS_OK;
-  }
-  fprintf(MSG_OUT, "libdvdnav: admap not located\n");
-  return DVDNAV_STATUS_ERR;
-}
-
-/* FIXME: right now, this function does not use the time tables but interpolates
-   only the cell times */
-dvdnav_status_t dvdnav_time_search(dvdnav_t *this,
-				   uint64_t time) {
-  
-  uint64_t target = time;
-  uint64_t length = 0;
-  uint32_t first_cell_nr, last_cell_nr, cell_nr;
-  int32_t found;
-  cell_playback_t *cell;
-  dvd_state_t *state;
-
-  if(this->position_current.still != 0) {
-    printerr("Cannot seek in a still frame.");
-    return DVDNAV_STATUS_ERR;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock);
-  state = &(this->vm->state);
-  if(!state->pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-
-  
-  this->cur_cell_time = 0;  
-  if (this->pgc_based) {
-    first_cell_nr = 1;
-    last_cell_nr = state->pgc->nr_of_cells;
-  } else {
-    /* Find start cell of program. */
-    first_cell_nr = state->pgc->program_map[state->pgN-1];
-    /* Find end cell of program */
-    if(state->pgN < state->pgc->nr_of_programs)
-      last_cell_nr = state->pgc->program_map[state->pgN] - 1;
-    else
-      last_cell_nr = state->pgc->nr_of_cells;
-  }
-
-  found = 0;
-  for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) {
-    cell =  &(state->pgc->cell_playback[cell_nr-1]);
-    if(cell->block_type == BLOCK_TYPE_ANGLE_BLOCK && cell->block_mode != BLOCK_MODE_FIRST_CELL)
-      continue;
-    length = dvdnav_convert_time(&cell->playback_time);
-    if (target >= length) {
-      target -= length;
-    } else {
-      /* FIXME: there must be a better way than interpolation */
-      target = target * (cell->last_sector - cell->first_sector + 1) / length;
-      target += cell->first_sector;
-      
-      found = 1;
-      break;
-    }
-  }
-
-  if(found) {
-    uint32_t vobu;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n",
-	    cell_nr, first_cell_nr, last_cell_nr);
-#endif
-    if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) {
-      uint32_t start = state->pgc->cell_playback[cell_nr-1].first_sector;
-      
-      if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) {
-#ifdef LOG_DEBUG
-        fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" ,
-          state->cellN, state->blockN, target, vobu, start);
-#endif
-        this->vm->hop_channel += HOP_SEEK;
-        pthread_mutex_unlock(&this->vm_lock);
-        return DVDNAV_STATUS_OK;
-      }
-    }
-  }
-  
-  fprintf(MSG_OUT, "libdvdnav: Error when seeking\n");
-  printerr("Error when seeking.");
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_sector_search(dvdnav_t *this,
-				     uint64_t offset, int32_t origin) {
-  uint32_t target = 0;
-  uint32_t length = 0;
-  uint32_t first_cell_nr, last_cell_nr, cell_nr;
-  int32_t found;
-  cell_playback_t *cell;
-  dvd_state_t *state;
-  dvdnav_status_t result;
-
-  if(this->position_current.still != 0) {
-    printerr("Cannot seek in a still frame.");
-    return DVDNAV_STATUS_ERR;
-  }
-  
-  result = dvdnav_get_position(this, &target, &length);
-  if(!result) {
-    return DVDNAV_STATUS_ERR;
-  }
- 
-  pthread_mutex_lock(&this->vm_lock);
-  state = &(this->vm->state);
-  if(!state->pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lu pos=%u length=%u\n", offset, target, length); 
-  fprintf(MSG_OUT, "libdvdnav: Before cellN=%u blockN=%u\n", state->cellN, state->blockN);
-#endif
-
-  switch(origin) {
-   case SEEK_SET:
-    if(offset >= length) {
-      printerr("Request to seek behind end.");
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_ERR;
-    }
-    target = offset;
-    break;
-   case SEEK_CUR:
-    if(target + offset >= length) {
-      printerr("Request to seek behind end.");
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_ERR;
-    }
-    target += offset;
-    break;
-   case SEEK_END:
-    if(length < offset) {
-      printerr("Request to seek before start.");
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_ERR;
-    }
-    target = length - offset;
-    break;
-   default:
-    /* Error occured */
-    printerr("Illegal seek mode.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  
-  this->cur_cell_time = 0;
-  if (this->pgc_based) {
-    first_cell_nr = 1;
-    last_cell_nr = state->pgc->nr_of_cells;
-  } else {
-    /* Find start cell of program. */
-    first_cell_nr = state->pgc->program_map[state->pgN-1];
-    /* Find end cell of program */
-    if(state->pgN < state->pgc->nr_of_programs)
-      last_cell_nr = state->pgc->program_map[state->pgN] - 1;
-    else
-      last_cell_nr = state->pgc->nr_of_cells;
-  }
-
-  found = 0;
-  for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) {
-    cell =  &(state->pgc->cell_playback[cell_nr-1]);
-    if(cell->block_type == BLOCK_TYPE_ANGLE_BLOCK && cell->block_mode != BLOCK_MODE_FIRST_CELL)
-      continue;
-    length = cell->last_sector - cell->first_sector + 1;
-    if (target >= length) {
-      target -= length;
-    } else {
-      /* convert the target sector from Cell-relative to absolute physical sector */
-      target += cell->first_sector;
-      found = 1;
-      break;
-    }
-  }
-
-  if(found) {
-    int32_t vobu;
-#ifdef LOG_DEBUG
-    fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n",
-	    cell_nr, first_cell_nr, last_cell_nr);
-#endif
-    if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) {
-      int32_t start = state->pgc->cell_playback[cell_nr-1].first_sector;
-      
-      if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) {
-#ifdef LOG_DEBUG
-        fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" ,
-          state->cellN, state->blockN, target, vobu, start);
-#endif
-        this->vm->hop_channel += HOP_SEEK;
-        pthread_mutex_unlock(&this->vm_lock);
-        return DVDNAV_STATUS_OK;
-      }
-    }
-  }
-  
-  fprintf(MSG_OUT, "libdvdnav: Error when seeking\n");
-  fprintf(MSG_OUT, "libdvdnav: FIXME: Implement seeking to location %u\n", target); 
-  printerr("Error when seeking.");
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int32_t part) {
-  int32_t title, old_part;
-  
-  if (dvdnav_current_title_info(this, &title, &old_part) == DVDNAV_STATUS_OK)
-    return dvdnav_part_play(this, title, part);
-  return DVDNAV_STATUS_ERR;
-}
-
-dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *this) {
-  pthread_mutex_lock(&this->vm_lock);
-  if(!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: previous chapter\n");
-#endif
-  if (!vm_jump_prev_pg(this->vm)) {
-    fprintf(MSG_OUT, "libdvdnav: previous chapter failed.\n");
-    printerr("Skip to previous chapter failed.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  this->cur_cell_time = 0;
-  this->position_current.still = 0;
-  this->vm->hop_channel++;
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: previous chapter done\n");
-#endif
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) {
-  pthread_mutex_lock(&this->vm_lock);
-  if(!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: top chapter\n");
-#endif
-  if (!vm_jump_top_pg(this->vm)) {
-    fprintf(MSG_OUT, "libdvdnav: top chapter failed.\n");
-    printerr("Skip to top chapter failed.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  this->cur_cell_time = 0;
-  this->position_current.still = 0;
-  this->vm->hop_channel++;
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: top chapter done\n");
-#endif
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) {
-  vm_t *try_vm;
-
-  pthread_mutex_lock(&this->vm_lock);
-  if(!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: next chapter\n");
-#endif
-  /* make a copy of current VM and try to navigate the copy to the next PG */
-  try_vm = vm_new_copy(this->vm);
-  if (!vm_jump_next_pg(try_vm) || try_vm->stopped) {
-    vm_free_copy(try_vm);
-    /* next_pg failed, try to jump at least to the next cell */
-    try_vm = vm_new_copy(this->vm);
-    vm_get_next_cell(try_vm);
-    if (try_vm->stopped) {
-      vm_free_copy(try_vm);
-      fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n");
-      printerr("Skip to next chapter failed.");
-      pthread_mutex_unlock(&this->vm_lock);
-      return DVDNAV_STATUS_ERR;
-    }
-  }
-  this->cur_cell_time = 0;
-  /* merge changes on success */
-  vm_merge(this->vm, try_vm);
-  vm_free_copy(try_vm);
-  this->position_current.still = 0;
-  this->vm->hop_channel++;
-#ifdef LOG_DEBUG
-  fprintf(MSG_OUT, "libdvdnav: next chapter done\n");
-#endif
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) {
-  vm_t *try_vm;
-  
-  pthread_mutex_lock(&this->vm_lock);
-  if(!this->vm->state.pgc) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  
-  this->cur_cell_time = 0;
-  /* make a copy of current VM and try to navigate the copy to the menu */
-  try_vm = vm_new_copy(this->vm);
-  if ( (menu == DVD_MENU_Escape) && (this->vm->state.domain != VTS_DOMAIN)) {
-    /* Try resume */
-    if (vm_jump_resume(try_vm) && !try_vm->stopped) {
-        /* merge changes on success */
-        vm_merge(this->vm, try_vm);
-        vm_free_copy(try_vm);
-        this->position_current.still = 0;
-        this->vm->hop_channel++;
-        pthread_mutex_unlock(&this->vm_lock); 
-        return DVDNAV_STATUS_OK;
-    }
-  }
-  if (menu == DVD_MENU_Escape) menu = DVD_MENU_Root;
- 
-  if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) {
-    /* merge changes on success */
-    vm_merge(this->vm, try_vm);
-    vm_free_copy(try_vm);
-    this->position_current.still = 0;
-    this->vm->hop_channel++;
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_OK;
-  } else {
-    vm_free_copy(try_vm);
-    printerr("No such menu or menu not reachable.");
-    pthread_mutex_unlock(&this->vm_lock); 
-    return DVDNAV_STATUS_ERR;
-  }
-}
-
-dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos,
-				    uint32_t *len) {
-  uint32_t cur_sector;
-  int32_t cell_nr, first_cell_nr, last_cell_nr;
-  cell_playback_t *cell;
-  dvd_state_t *state;
-
-  if(!this->started) {
-    printerr("Virtual DVD machine not started.");
-    return DVDNAV_STATUS_ERR;
-  }
-
-  pthread_mutex_lock(&this->vm_lock);
-  state = &(this->vm->state);
-  if(!state->pgc || this->vm->stopped) {
-    printerr("No current PGC.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-  if (this->position_current.hop_channel  != this->vm->hop_channel ||
-      this->position_current.domain       != state->domain         ||
-      this->position_current.vts          != state->vtsN           ||
-      this->position_current.cell_restart != state->cell_restart) {
-    printerr("New position not yet determined.");
-    pthread_mutex_unlock(&this->vm_lock);
-    return DVDNAV_STATUS_ERR;
-  }
-
-  /* Get current sector */
-  cur_sector = this->vobu.vobu_start + this->vobu.blockN;
-
-  if (this->pgc_based) {
-    first_cell_nr = 1;
-    last_cell_nr = state->pgc->nr_of_cells;
-  } else {
-    /* Find start cell of program. */
-    first_cell_nr = state->pgc->program_map[state->pgN-1];
-    /* Find end cell of program */
-    if(state->pgN < state->pgc->nr_of_programs)
-      last_cell_nr = state->pgc->program_map[state->pgN] - 1;
-    else
-      last_cell_nr = state->pgc->nr_of_cells;
-  }
-
-  *pos = -1;
-  *len = 0;
-  for (cell_nr = first_cell_nr; cell_nr <= last_cell_nr; cell_nr++) {
-    cell = &(state->pgc->cell_playback[cell_nr-1]);
-    if (cell_nr == state->cellN) {
-      /* the current sector is in this cell,
-       * pos is length of PG up to here + sector's offset in this cell */
-      *pos = *len + cur_sector - cell->first_sector;
-    }
-    *len += cell->last_sector - cell->first_sector + 1;
-  }
-  
-  assert((signed)*pos != -1);
-
-  pthread_mutex_unlock(&this->vm_lock);
-
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this,
-					     uint32_t *pos,
-					     uint32_t *len) {
-  uint32_t cur_sector;
-  uint32_t first_cell_nr;
-  uint32_t last_cell_nr;
-  cell_playback_t *first_cell;
-  cell_playback_t *last_cell;
-  dvd_state_t *state;
-
-  state = &(this->vm->state);
-  if(!state->pgc) {
-    printerr("No current PGC.");
-    return DVDNAV_STATUS_ERR;
-  }
-
-  /* Get current sector */
-  cur_sector = this->vobu.vobu_start + this->vobu.blockN;
-
-  /* Now find first and last cells in title. */
-  first_cell_nr = state->pgc->program_map[0];
-  first_cell = &(state->pgc->cell_playback[first_cell_nr-1]);
-  last_cell_nr = state->pgc->nr_of_cells;
-  last_cell = &(state->pgc->cell_playback[last_cell_nr-1]);
-  
-  *pos = cur_sector - first_cell->first_sector;
-  *len = last_cell->last_sector - first_cell->first_sector;
-  
-  return DVDNAV_STATUS_OK;
-}
-
-uint32_t dvdnav_describe_title_chapters(dvdnav_t *this, int32_t title, uint64_t **times, uint64_t *duration) {
-  int32_t retval=0;
-  uint16_t parts, i;
-  title_info_t *ptitle = NULL;
-  ptt_info_t *ptt = NULL;
-  ifo_handle_t *ifo;
-  pgc_t *pgc;
-  cell_playback_t *cell;
-  uint64_t length, *tmp=NULL;
-
-  *times = NULL;
-  *duration = 0;
-  pthread_mutex_lock(&this->vm_lock);
-  if(!this->vm->vmgi) {
-    printerr("Bad VM state or missing VTSI.");
-    goto fail;
-  }
-  if(!this->started) {
-    /* don't report an error but be nice */
-    vm_start(this->vm);
-    this->started = 1;
-  }
-  ifo = vm_get_title_ifo(this->vm, title);
-  if(!ifo || !ifo->vts_pgcit) {
-    printerr("Couldn't open IFO for chosen title, exit.");
-    goto fail;
-  }
-  
-  ptitle = &this->vm->vmgi->tt_srpt->title[title-1];
-  parts = ptitle->nr_of_ptts;
-  ptt = ifo->vts_ptt_srpt->title[ptitle->vts_ttn-1].ptt;
-  
-  tmp = calloc(1, sizeof(uint64_t)*parts);
-  if(!tmp)
-    goto fail;
- 
-  length = 0;
-  for(i=0; i<parts; i++) {
-    uint32_t cellnr, endcellnr;
-    pgc = ifo->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc;
-    if(ptt[i].pgn > pgc->nr_of_programs) {
-      printerr("WRONG part number.");
-      goto fail;
-    }
- 
-    cellnr = pgc->program_map[ptt[i].pgn-1];
-    if(ptt[i].pgn < pgc->nr_of_programs)
-      endcellnr = pgc->program_map[ptt[i].pgn];
-    else
-      endcellnr = 0;
- 
-    do {
-      cell = &pgc->cell_playback[cellnr-1];
-      if(!(cell->block_type == BLOCK_TYPE_ANGLE_BLOCK &&
-           cell->block_mode != BLOCK_MODE_FIRST_CELL
-      ))
-      {
-        tmp[i] = length + dvdnav_convert_time(&cell->playback_time);
-        length = tmp[i];
-      }
-      cellnr++;
-    } while(cellnr < endcellnr);
-  }
-  *duration = length;
-  vm_ifo_close(ifo);
-  retval = parts;
-  *times = tmp;
-
-fail:
-  pthread_mutex_unlock(&this->vm_lock);
-  if(!retval && tmp)
-    free(tmp);
-  return retval;
-}
--- a/settings.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/* 
- * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
-#include <sys/time.h>
-#include "dvd_types.h"
-#include "nav_types.h"
-#include "ifo_types.h"
-#include "remap.h"
-#include "vm/decoder.h"
-#include "vm/vm.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-
-/* Characteristics/setting API calls */
-
-dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *this, int32_t *region) {
-  (*region) = this->vm->state.registers.SPRM[20];
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *this, int32_t mask) {
-  pthread_mutex_lock(&this->vm_lock);
-  this->vm->state.registers.SPRM[20] = (mask & 0xff);
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *this, int32_t use_readahead) {
-  this->use_read_ahead = use_readahead;
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int32_t *flag) {
-  (*flag) = this->use_read_ahead;
-  return DVDNAV_STATUS_OK;
-}
-
-static dvdnav_status_t set_language_register(dvdnav_t *this, char *code, int reg) {
-  if(!code[0] || !code[1]) {
-    printerr("Passed illegal language code.");
-    return DVDNAV_STATUS_ERR;
-  }
-  
-  pthread_mutex_lock(&this->vm_lock);
-  this->vm->state.registers.SPRM[reg] = (code[0] << 8) | code[1];
-  pthread_mutex_unlock(&this->vm_lock);
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *this, char *code) {
-  return set_language_register(this, code, 0);
-}
-
-dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *this, char *code) {
-  return set_language_register(this, code, 16);
-}
-
-dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *this, char *code) {
-  return set_language_register(this, code, 18);
-}
-
-dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *this, int32_t pgc) {
-  this->pgc_based = pgc;
-  return DVDNAV_STATUS_OK;
-}
-
-dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *this, int32_t *flag) {
-  (*flag) = this->pgc_based;
-  return DVDNAV_STATUS_OK;
-}
--- a/vm/Makefile.am	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-include $(top_srcdir)/misc/Makefile.common
-
-includedir = ${prefix}/include/dvdnav
-
-AM_CPPFLAGS = -DDVDNAV_COMPILE $(THREAD_CFLAGS) \
-	-I$(top_srcdir)/src -I$(top_srcdir)/src/libdvdread
-
-noinst_LTLIBRARIES = libdvdvm.la
-
-libdvdvm_la_SOURCES = decoder.c vm.c vmcmd.c
-
-libdvdvm_la_LDFLAGS = $(THREAD_LIBS)
-
-include_HEADERS = 
-
-noinst_HEADERS = decoder.h vm.h vmcmd.h
--- a/vm/decoder.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,788 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
- *               2002-2004 the dvdnav project
- * 
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>  /* For memset */
-#include <sys/time.h>
-#include "nav_types.h"
-#include "ifo_types.h" /* vm_cmd_t */
-
-#include "dvd_types.h"
-#include "remap.h"
-#include "decoder.h"
-#include "vm.h"
-#include "vmcmd.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-
-uint32_t vm_getbits(command_t *command, int32_t start, int32_t count) {
-  uint64_t result = 0;
-  uint64_t bit_mask = 0;
-  uint64_t examining = 0;
-  int32_t  bits;
-  
-  if (count == 0) return 0;
-
-  if ( ((start - count) < -1) ||
-       (count > 32) ||
-       (start > 63) ||
-       (count < 0) ||
-       (start < 0) ) {
-    fprintf(MSG_OUT, "libdvdnav: Bad call to vm_getbits. Parameter out of range\n");
-    abort();
-  }
-  /* all ones, please */
-  bit_mask = ~bit_mask;
-  bit_mask >>= 63 - start;
-  bits = start + 1 - count;
-  examining = ((bit_mask >> bits) << bits );
-  command->examined |= examining;
-  result = (command->instruction & bit_mask) >> bits;
-  return (uint32_t) result;
-}
-
-static uint16_t get_GPRM(registers_t* registers, uint8_t reg) {
-  if (registers->GPRM_mode[reg] & 0x01) {
-    struct timeval current_time, time_offset;
-    uint16_t result;
-    /* Counter mode */
-    /* fprintf(MSG_OUT, "libdvdnav: Getting counter %d\n",reg);*/
-    gettimeofday(&current_time, NULL);
-    time_offset.tv_sec = current_time.tv_sec - registers->GPRM_time[reg].tv_sec;
-    time_offset.tv_usec = current_time.tv_usec - registers->GPRM_time[reg].tv_usec;
-    if (time_offset.tv_usec < 0) { 
-      time_offset.tv_sec--; 
-      time_offset.tv_usec += 1000000;
-    }
-    result = (uint16_t) (time_offset.tv_sec & 0xffff);
-    registers->GPRM[reg]=result;
-    return result; 
-
-  } else {
-    /* Register mode */
-    return registers->GPRM[reg];
-  }
-  
-}
-
-static void set_GPRM(registers_t* registers, uint8_t reg, uint16_t value) {
-  if (registers->GPRM_mode[reg] & 0x01) {
-    struct timeval current_time;
-    /* Counter mode */
-    /* fprintf(MSG_OUT, "libdvdnav: Setting counter %d\n",reg); */
-    gettimeofday(&current_time, NULL);
-    registers->GPRM_time[reg] = current_time;
-    registers->GPRM_time[reg].tv_sec -= value;
-  }
-  registers->GPRM[reg] = value;
-}
-
-/* Eval register code, can either be system or general register.
-   SXXX_XXXX, where S is 1 if it is system register. */
-static uint16_t eval_reg(command_t* command, uint8_t reg) {
-  if(reg & 0x80) {
-    if ((reg & 0x1f) == 20) {
-      fprintf(MSG_OUT, "libdvdnav: Suspected RCE Region Protection!!!\n");
-    }
-    return command->registers->SPRM[reg & 0x1f]; /*  FIXME max 24 not 32 */
-  } else {
-    return get_GPRM(command->registers, reg & 0x0f) ;
-  }
-}
-
-/* Eval register or immediate data.
-   AAAA_AAAA BBBB_BBBB, if immediate use all 16 bits for data else use
-   lower eight bits for the system or general purpose register. */
-static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t start) {
-  if(imm) { /*  immediate */
-    return vm_getbits(command, start, 16);
-  } else {
-    return eval_reg(command, vm_getbits(command, (start - 8), 8));
-  }
-}
-
-/* Eval register or immediate data.
-   xBBB_BBBB, if immediate use all 7 bits for data else use
-   lower four bits for the general purpose register number. */
-/* Evaluates gprm or data depending on bit, data is in byte n */
-static uint16_t eval_reg_or_data_2(command_t* command, 
-				   int32_t imm, int32_t start) {
-  if(imm) /* immediate */
-    return vm_getbits(command, (start - 1), 7);
-  else
-    return get_GPRM(command->registers, (vm_getbits(command, (start - 4), 4)) );
-}
-
-
-/* Compare data using operation, return result from comparison. 
-   Helper function for the different if functions. */
-static int32_t eval_compare(uint8_t operation, uint16_t data1, uint16_t data2) {
-  switch(operation) {
-    case 1:
-      return data1 & data2;
-    case 2:
-      return data1 == data2;
-    case 3:
-      return data1 != data2;
-    case 4:
-      return data1 >= data2;
-    case 5:
-      return data1 >  data2;
-    case 6:
-      return data1 <= data2;
-    case 7:
-      return data1 <  data2;
-  }
-  fprintf(MSG_OUT, "libdvdnav: eval_compare: Invalid comparison code\n");
-  return 0;
-}
-
-
-/* Evaluate if version 1.
-   Has comparison data in byte 3 and 4-5 (immediate or register) */
-static int32_t eval_if_version_1(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  if(op) {
-    return eval_compare(op, eval_reg(command, vm_getbits(command, 39, 8)), 
-                            eval_reg_or_data(command, vm_getbits(command, 55, 1), 31));
-  }
-  return 1;
-}
-
-/* Evaluate if version 2.
-   This version only compares register which are in byte 6 and 7 */
-static int32_t eval_if_version_2(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  if(op) {
-    return eval_compare(op, eval_reg(command, vm_getbits(command, 15, 8)), 
-                            eval_reg(command, vm_getbits(command, 7, 8)));
-  }
-  return 1;
-}
-
-/* Evaluate if version 3.
-   Has comparison data in byte 2 and 6-7 (immediate or register) */
-static int32_t eval_if_version_3(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  if(op) {
-    return eval_compare(op, eval_reg(command, vm_getbits(command, 47, 8)), 
-                            eval_reg_or_data(command, vm_getbits(command, 55, 1), 15));
-  }
-  return 1;
-}
-
-/* Evaluate if version 4.
-   Has comparison data in byte 1 and 4-5 (immediate or register) 
-   The register in byte 1 is only the lowe nibble (4 bits) */
-static int32_t eval_if_version_4(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  if(op) {
-    return eval_compare(op, eval_reg(command, vm_getbits(command, 51, 4)), 
-                            eval_reg_or_data(command, vm_getbits(command, 55, 1), 31));
-  }
-  return 1;
-}
-
-/* Evaluate special instruction.... returns the new row/line number,
-   0 if no new row and 256 if Break. */
-static int32_t eval_special_instruction(command_t* command, int32_t cond) {
-  int32_t line, level;
-  
-  switch(vm_getbits(command, 51, 4)) {
-    case 0: /*  NOP */
-      line = 0;
-      return cond ? line : 0;
-    case 1: /*  Goto line */
-      line = vm_getbits(command, 7, 8);
-      return cond ? line : 0;
-    case 2: /*  Break */
-      /*  max number of rows < 256, so we will end this set */
-      line = 256;
-      return cond ? 256 : 0;
-    case 3: /*  Set temporary parental level and goto */
-      line = vm_getbits(command, 7, 8); 
-      level = vm_getbits(command, 11, 4);
-      if(cond) {
-	/*  This always succeeds now, if we want real parental protection */
-	/*  we need to ask the user and have passwords and stuff. */
-	command->registers->SPRM[13] = level;
-      }
-      return cond ? line : 0;
-  }
-  return 0;
-}
-
-/* Evaluate link by subinstruction.
-   Return 1 if link, or 0 if no link
-   Actual link instruction is in return_values parameter */
-static int32_t eval_link_subins(command_t* command, int32_t cond, link_t *return_values) {
-  uint16_t button = vm_getbits(command, 15, 6);
-  uint8_t  linkop = vm_getbits(command, 4, 5);
-  
-  if(linkop > 0x10)
-    return 0;    /*  Unknown Link by Sub-Instruction command */
-
-  /*  Assumes that the link_cmd_t enum has the same values as the LinkSIns codes */
-  return_values->command = linkop;
-  return_values->data1 = button;
-  return cond;
-}
-
-
-/* Evaluate link instruction.
-   Return 1 if link, or 0 if no link
-   Actual link instruction is in return_values parameter */
-static int32_t eval_link_instruction(command_t* command, int32_t cond, link_t *return_values) {
-  uint8_t op = vm_getbits(command, 51, 4);
-  
-  switch(op) {
-    case 1:
-	return eval_link_subins(command, cond, return_values);
-    case 4:
-	return_values->command = LinkPGCN;
-	return_values->data1   = vm_getbits(command, 14, 15);
-	return cond;
-    case 5:
-	return_values->command = LinkPTTN;
-	return_values->data1 = vm_getbits(command, 9, 10);
-	return_values->data2 = vm_getbits(command, 15, 6);
-	return cond;
-    case 6:
-	return_values->command = LinkPGN;
-	return_values->data1 = vm_getbits(command, 6, 7);
-	return_values->data2 = vm_getbits(command, 15, 6);
-	return cond;
-    case 7:
-	return_values->command = LinkCN;
-	return_values->data1 = vm_getbits(command, 7, 8);
-	return_values->data2 = vm_getbits(command, 15, 6);
-	return cond;
-  }
-  return 0;
-}
-
-
-/* Evaluate a jump instruction.
-   returns 1 if jump or 0 if no jump
-   actual jump instruction is in return_values parameter */
-static int32_t eval_jump_instruction(command_t* command, int32_t cond, link_t *return_values) {
-  
-  switch(vm_getbits(command, 51, 4)) {
-    case 1:
-      return_values->command = Exit;
-      return cond;
-    case 2:
-      return_values->command = JumpTT;
-      return_values->data1 = vm_getbits(command, 22, 7);
-      return cond;
-    case 3:
-      return_values->command = JumpVTS_TT;
-      return_values->data1 = vm_getbits(command, 22, 7);
-      return cond;
-    case 5:
-      return_values->command = JumpVTS_PTT;
-      return_values->data1 = vm_getbits(command, 22, 7);
-      return_values->data2 = vm_getbits(command, 41, 10);
-      return cond;
-    case 6:
-      switch(vm_getbits(command, 23, 2)) {
-        case 0:
-          return_values->command = JumpSS_FP;
-          return cond;
-        case 1:
-          return_values->command = JumpSS_VMGM_MENU;
-          return_values->data1 =  vm_getbits(command, 19, 4);
-          return cond;
-        case 2:
-          return_values->command = JumpSS_VTSM;
-          return_values->data1 =  vm_getbits(command, 31, 8);
-          return_values->data2 =  vm_getbits(command, 39, 8);
-          return_values->data3 =  vm_getbits(command, 19, 4);
-          return cond;
-        case 3:
-          return_values->command = JumpSS_VMGM_PGC;
-          return_values->data1 =  vm_getbits(command, 46, 15);
-          return cond;
-        }
-      break;
-    case 8:
-      switch(vm_getbits(command, 23, 2)) {
-        case 0:
-          return_values->command = CallSS_FP;
-          return_values->data1 = vm_getbits(command, 31, 8);
-          return cond;
-        case 1:
-          return_values->command = CallSS_VMGM_MENU;
-          return_values->data1 = vm_getbits(command, 19, 4);
-          return_values->data2 = vm_getbits(command, 31, 8);
-          return cond;
-        case 2:
-          return_values->command = CallSS_VTSM;
-          return_values->data1 = vm_getbits(command, 19, 4);
-          return_values->data2 = vm_getbits(command, 31, 8);
-          return cond;
-        case 3:
-          return_values->command = CallSS_VMGM_PGC;
-          return_values->data1 = vm_getbits(command, 46, 15);
-          return_values->data2 = vm_getbits(command, 31, 8);
-          return cond;
-      }
-      break;
-  }
-  return 0;
-}
-
-/* Evaluate a set sytem register instruction 
-   May contain a link so return the same as eval_link */
-static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_values) {
-  int32_t i;
-  uint16_t data, data2;
-  
-  switch(vm_getbits(command, 59, 4)) {
-    case 1: /*  Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */
-      for(i = 1; i <= 3; i++) {
-        if(vm_getbits(command, 63 - ((2 + i)*8), 1)) {
-          data = eval_reg_or_data_2(command, vm_getbits(command, 60, 1), (47 - (i*8)));
-          if(cond) {
-            command->registers->SPRM[i] = data;
-          }
-        }
-      }
-      break;
-    case 2: /*  Set system reg 9 & 10 (Navigation timer, Title PGC number) */
-      data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
-      data2 = vm_getbits(command, 23, 8); /*  ?? size */
-      if(cond) {
-	command->registers->SPRM[9] = data; /*  time */
-	command->registers->SPRM[10] = data2; /*  pgcN */
-      }
-      break;
-    case 3: /*  Mode: Counter / Register + Set */
-      data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
-      data2 = vm_getbits(command, 19, 4);
-      if(vm_getbits(command, 23, 1)) {
-	command->registers->GPRM_mode[data2] |= 1; /* Set bit 0 */
-      } else {
-	command->registers->GPRM_mode[data2] &= ~ 0x01; /* Reset bit 0 */
-      }
-      if(cond) {
-        set_GPRM(command->registers, data2, data);
-      }
-      break;
-    case 6: /*  Set system reg 8 (Highlighted button) */
-      data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); /*  Not system reg!! */
-      if(cond) {
-	command->registers->SPRM[8] = data;
-      }
-      break;
-  }
-  if(vm_getbits(command, 51, 4)) {
-    return eval_link_instruction(command, cond, return_values);
-  }
-  return 0;
-}
-
-
-/* Evaluate set operation
-   Sets the register given to the value indicated by op and data.
-   For the swap case the contents of reg is stored in reg2.
-*/
-static void eval_set_op(command_t* command, int32_t op, int32_t reg, int32_t reg2, int32_t data) {
-  static const int32_t shortmax = 0xffff;
-  int32_t     tmp; 
-  switch(op) {
-    case 1:
-      set_GPRM(command->registers, reg, data);
-      break;
-    case 2: /* SPECIAL CASE - SWAP! */
-      set_GPRM(command->registers, reg2, get_GPRM(command->registers, reg));
-      set_GPRM(command->registers, reg, data);
-      break;
-    case 3:
-      tmp = get_GPRM(command->registers, reg) + data;
-      if(tmp > shortmax) tmp = shortmax;
-      set_GPRM(command->registers, reg, (uint16_t)tmp);
-      break;
-    case 4:
-      tmp = get_GPRM(command->registers, reg) - data;
-      if(tmp < 0) tmp = 0;
-      set_GPRM(command->registers, reg, (uint16_t)tmp);
-      break;
-    case 5:
-      tmp = get_GPRM(command->registers, reg) * data;
-      if(tmp > shortmax) tmp = shortmax;
-      set_GPRM(command->registers, reg, (uint16_t)tmp);
-      break;
-    case 6:
-      if (data != 0) {
-        set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) / data) );
-      } else {
-        set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */
-      }
-      break;
-    case 7:
-      if (data != 0) {
-        set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) );
-      } else {
-        set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */
-      }
-      break;
-    case 8: /* SPECIAL CASE - RND! Return numbers between 1 and data. */
-      set_GPRM(command->registers, reg, 1 + ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) );
-      break;
-    case 9:
-      set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) & data) );
-      break;
-    case 10:
-      set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) | data) );
-      break;
-    case 11:
-      set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) ^ data) );
-      break;
-  }
-}
-
-/* Evaluate set instruction, combined with either Link or Compare. */
-static void eval_set_version_1(command_t* command, int32_t cond) {
-  uint8_t  op   = vm_getbits(command, 59, 4);
-  uint8_t  reg  = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */
-  uint8_t  reg2 = vm_getbits(command, 19, 4);
-  uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31);
-
-  if(cond) {
-    eval_set_op(command, op, reg, reg2, data);
-  }
-}
-
-
-/* Evaluate set instruction, combined with both Link and Compare. */
-static void eval_set_version_2(command_t* command, int32_t cond) {
-  uint8_t  op   = vm_getbits(command, 59, 4);
-  uint8_t  reg  = vm_getbits(command, 51, 4);
-  uint8_t  reg2 = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */
-  uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
-
-  if(cond) {
-    eval_set_op(command, op, reg, reg2, data);
-  }
-}
-
-
-/* Evaluate a command
-   returns row number of goto, 0 if no goto, -1 if link.
-   Link command in return_values */
-static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *return_values) {
-  int32_t cond, res = 0;
-  command_t command;
-  command.instruction =( (uint64_t) bytes[0] << 56 ) |
-        ( (uint64_t) bytes[1] << 48 ) |
-        ( (uint64_t) bytes[2] << 40 ) |
-        ( (uint64_t) bytes[3] << 32 ) |
-        ( (uint64_t) bytes[4] << 24 ) |
-        ( (uint64_t) bytes[5] << 16 ) |
-        ( (uint64_t) bytes[6] <<  8 ) |
-          (uint64_t) bytes[7] ;
-  command.examined = 0;
-  command.registers = registers;
-  memset(return_values, 0, sizeof(link_t));
-
-  switch(vm_getbits(&command, 63, 3)) { /* three first old_bits */
-    case 0: /*  Special instructions */
-      cond = eval_if_version_1(&command);
-      res = eval_special_instruction(&command, cond);
-      if(res == -1) {
-	fprintf(MSG_OUT, "libdvdnav: Unknown Instruction!\n");
-	abort();
-      }
-      break;
-    case 1: /*  Link/jump instructions */
-      if(vm_getbits(&command, 60, 1)) {
-        cond = eval_if_version_2(&command);
-        res = eval_jump_instruction(&command, cond, return_values);
-      } else {
-        cond = eval_if_version_1(&command);
-        res = eval_link_instruction(&command, cond, return_values);
-      }
-      if(res)
-	res = -1;
-      break;
-    case 2: /*  System set instructions */
-      cond = eval_if_version_2(&command);
-      res = eval_system_set(&command, cond, return_values);
-      if(res)
-	res = -1;
-      break;
-    case 3: /*  Set instructions, either Compare or Link may be used */
-      cond = eval_if_version_3(&command);
-      eval_set_version_1(&command, cond);
-      if(vm_getbits(&command, 51, 4)) {
-	res = eval_link_instruction(&command, cond, return_values);
-      }
-      if(res)
-	res = -1;
-      break;
-    case 4: /*  Set, Compare -> Link Sub-Instruction */
-      eval_set_version_2(&command, /*True*/ 1);
-      cond = eval_if_version_4(&command);
-      res = eval_link_subins(&command, cond, return_values);
-      if(res)
-	res = -1;
-      break;
-    case 5: /*  Compare -> (Set and Link Sub-Instruction) */
-      /* FIXME: These are wrong. Need to be updated from vmcmd.c */
-      cond = eval_if_version_4(&command);
-      eval_set_version_2(&command, cond);
-      res = eval_link_subins(&command, cond, return_values);
-      if(res)
-	res = -1;
-      break;
-    case 6: /*  Compare -> Set, allways Link Sub-Instruction */
-      /* FIXME: These are wrong. Need to be updated from vmcmd.c */
-      cond = eval_if_version_4(&command);
-      eval_set_version_2(&command, cond);
-      res = eval_link_subins(&command, /*True*/ 1, return_values);
-      if(res)
-	res = -1;
-      break;
-    default: /* Unknown command */
-      fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command=%x\n", vm_getbits(&command, 63, 3));
-      abort();
-  }
-  /*  Check if there are bits not yet examined */
-
-  if(command.instruction & ~ command.examined) {
-    fprintf(MSG_OUT, "libdvdnav: decoder.c: [WARNING, unknown bits:");
-    fprintf(MSG_OUT, " %08"PRIx64, (command.instruction & ~ command.examined) );
-    fprintf(MSG_OUT, "]\n");
-  }
-
-  return res;
-}
-
-/* Evaluate a set of commands in the given register set (which is modified) */
-int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, 
-	       registers_t *registers, link_t *return_values) {
-  int32_t i = 0;
-  int32_t total = 0;
-  
-#ifdef TRACE
-  /*  DEBUG */
-  fprintf(MSG_OUT, "libdvdnav: Registers before transaction\n");
-  vm_print_registers( registers );
-  fprintf(MSG_OUT, "libdvdnav: Full list of commands to execute\n");
-  for(i = 0; i < num_commands; i++)
-    vm_print_cmd(i, &commands[i]);
-  fprintf(MSG_OUT, "libdvdnav: --------------------------------------------\n");
-  fprintf(MSG_OUT, "libdvdnav: Single stepping commands\n");
-#endif
-
-  i = 0; 
-  while(i < num_commands && total < 100000) {
-    int32_t line;
-    
-#ifdef TRACE
-    vm_print_cmd(i, &commands[i]);
-#endif
-
-    line = eval_command(&commands[i].bytes[0], registers, return_values);
-    
-    if (line < 0) { /*  Link command */
-#ifdef TRACE
-      fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");
-      vm_print_registers( registers );
-      fprintf(MSG_OUT, "libdvdnav: eval: Doing Link/Jump/Call\n"); 
-#endif
-      return 1;
-    }
-    
-    if (line > 0) /*  Goto command */
-      i = line - 1;
-    else /*  Just continue on the next line */
-      i++;
-
-    total++;
-  }
-  
-  memset(return_values, 0, sizeof(link_t));
-#ifdef TRACE
-  fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");
-  vm_print_registers( registers );
-#endif
-  return 0;
-}
-
-#ifdef TRACE
-
-static char *linkcmd2str(link_cmd_t cmd) {
-  switch(cmd) {
-  case LinkNoLink:
-    return "LinkNoLink";
-  case LinkTopC:
-    return "LinkTopC";
-  case LinkNextC:
-    return "LinkNextC";
-  case LinkPrevC:
-    return "LinkPrevC";
-  case LinkTopPG:
-    return "LinkTopPG";
-  case LinkNextPG:
-    return "LinkNextPG";
-  case LinkPrevPG:
-    return "LinkPrevPG";
-  case LinkTopPGC:
-    return "LinkTopPGC";
-  case LinkNextPGC:
-    return "LinkNextPGC";
-  case LinkPrevPGC:
-    return "LinkPrevPGC";
-  case LinkGoUpPGC:
-    return "LinkGoUpPGC";
-  case LinkTailPGC:
-    return "LinkTailPGC";
-  case LinkRSM:
-    return "LinkRSM";
-  case LinkPGCN:
-    return "LinkPGCN";
-  case LinkPTTN:
-    return "LinkPTTN";
-  case LinkPGN:
-    return "LinkPGN";
-  case LinkCN:
-    return "LinkCN";
-  case Exit:
-    return "Exit";
-  case JumpTT:
-    return "JumpTT";
-  case JumpVTS_TT:
-    return "JumpVTS_TT";
-  case JumpVTS_PTT:
-    return "JumpVTS_PTT";
-  case JumpSS_FP:
-    return "JumpSS_FP";
-  case JumpSS_VMGM_MENU:
-    return "JumpSS_VMGM_MENU";
-  case JumpSS_VTSM:
-    return "JumpSS_VTSM";
-  case JumpSS_VMGM_PGC:
-    return "JumpSS_VMGM_PGC";
-  case CallSS_FP:
-    return "CallSS_FP";
-  case CallSS_VMGM_MENU:
-    return "CallSS_VMGM_MENU";
-  case CallSS_VTSM:
-    return "CallSS_VTSM";
-  case CallSS_VMGM_PGC:
-    return "CallSS_VMGM_PGC";
-  case PlayThis:
-    return "PlayThis";
-  }
-  return "*** (bug)";
-}
-
-void vm_print_link(link_t value) {
-  char *cmd = linkcmd2str(value.command);
-    
-  switch(value.command) {
-  case LinkNoLink:
-  case LinkTopC:
-  case LinkNextC:
-  case LinkPrevC:
-  case LinkTopPG:
-  case LinkNextPG:
-  case LinkPrevPG:
-  case LinkTopPGC:
-  case LinkNextPGC:
-  case LinkPrevPGC:
-  case LinkGoUpPGC:
-  case LinkTailPGC:
-  case LinkRSM:
-    fprintf(MSG_OUT, "libdvdnav: %s (button %d)\n", cmd, value.data1);
-    break;
-  case LinkPGCN:
-  case JumpTT:
-  case JumpVTS_TT:
-  case JumpSS_VMGM_MENU: /*  == 2 -> Title Menu */
-  case JumpSS_VMGM_PGC:
-    fprintf(MSG_OUT, "libdvdnav: %s %d\n", cmd, value.data1);
-    break;
-  case LinkPTTN:
-  case LinkPGN:
-  case LinkCN:
-    fprintf(MSG_OUT, "libdvdnav: %s %d (button %d)\n", cmd, value.data1, value.data2);
-    break;
-  case Exit:
-  case JumpSS_FP:
-  case PlayThis: /*  Humm.. should we have this at all.. */
-    fprintf(MSG_OUT, "libdvdnav: %s\n", cmd);
-    break;
-  case JumpVTS_PTT:
-    fprintf(MSG_OUT, "libdvdnav: %s %d:%d\n", cmd, value.data1, value.data2);
-    break;
-  case JumpSS_VTSM:
-    fprintf(MSG_OUT, "libdvdnav: %s vts %d title %d menu %d\n", 
-	    cmd, value.data1, value.data2, value.data3);
-    break;
-  case CallSS_FP:
-    fprintf(MSG_OUT, "libdvdnav: %s resume cell %d\n", cmd, value.data1);
-    break;
-  case CallSS_VMGM_MENU: /*  == 2 -> Title Menu */
-  case CallSS_VTSM:
-    fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);
-    break;
-  case CallSS_VMGM_PGC:
-    fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);
-    break;
-  }
- }
-
-void vm_print_registers( registers_t *registers ) {
-  int32_t i;
-  fprintf(MSG_OUT, "libdvdnav:    #   ");
-  for(i = 0; i < 24; i++)
-    fprintf(MSG_OUT, " %2d |", i);
-  fprintf(MSG_OUT, "\nlibdvdnav: SRPMS: ");
-  for(i = 0; i < 24; i++)
-    fprintf(MSG_OUT, "%04x|", registers->SPRM[i]);
-  fprintf(MSG_OUT, "\nlibdvdnav: GRPMS: ");
-  for(i = 0; i < 16; i++)
-    fprintf(MSG_OUT, "%04x|", get_GPRM(registers, i) );
-  fprintf(MSG_OUT, "\nlibdvdnav: Gmode: ");
-  for(i = 0; i < 16; i++)
-    fprintf(MSG_OUT, "%04x|", registers->GPRM_mode[i]);
-  fprintf(MSG_OUT, "\nlibdvdnav: Gtime: ");
-  for(i = 0; i < 16; i++)
-    fprintf(MSG_OUT, "%04lx|", registers->GPRM_time[i].tv_sec & 0xffff);
-  fprintf(MSG_OUT, "\n");
-}
-
-#endif
-
--- a/vm/decoder.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
- * 
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifndef DECODER_H_INCLUDED
-#define DECODER_H_INCLUDED
-
-/* link command types */
-typedef enum {
-  LinkNoLink  = 0,
-
-  LinkTopC    = 1,
-  LinkNextC   = 2,
-  LinkPrevC   = 3,
-
-  LinkTopPG   = 5,
-  LinkNextPG  = 6,
-  LinkPrevPG  = 7,
-
-  LinkTopPGC  = 9,
-  LinkNextPGC = 10,
-  LinkPrevPGC = 11,
-  LinkGoUpPGC = 12,
-  LinkTailPGC = 13,
-
-  LinkRSM     = 16,
-
-  LinkPGCN,
-  LinkPTTN,
-  LinkPGN,
-  LinkCN,
-
-  Exit,
-
-  JumpTT, /* 22 */
-  JumpVTS_TT,
-  JumpVTS_PTT,
-
-  JumpSS_FP,
-  JumpSS_VMGM_MENU,
-  JumpSS_VTSM,
-  JumpSS_VMGM_PGC,
-
-  CallSS_FP, /* 29 */
-  CallSS_VMGM_MENU,
-  CallSS_VTSM,
-  CallSS_VMGM_PGC,
-
-  PlayThis
-} link_cmd_t;
-
-/* a link's data set */
-typedef struct {
-  link_cmd_t command;
-  uint16_t   data1;
-  uint16_t   data2;
-  uint16_t   data3;
-} link_t;
-
-/* the VM registers */
-typedef struct {
-  uint16_t SPRM[24];
-  uint16_t GPRM[16];
-  uint8_t  GPRM_mode[16];  /* Need to have some thing to indicate normal/counter mode for every GPRM */
-  struct timeval GPRM_time[16]; /* For counter mode */
-} registers_t;
-
-/* a VM command data set */
-typedef struct {
-  uint64_t instruction;
-  uint64_t examined;
-  registers_t *registers;
-} command_t;
-
-/* the big VM function, executing the given commands and writing
- * the link where to continue, the return value indicates if a jump
- * has been performed */
-int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, 
-	       registers_t *registers, link_t *return_values);
-
-/* extracts some bits from the command */
-uint32_t vm_getbits(command_t* command, int32_t start, int32_t count);
-
-#ifdef TRACE
-/* for debugging: prints a link in readable form */
-void vm_print_link(link_t value);
-
-/* for debugging: dumps VM registers */
-void vm_print_registers( registers_t *registers );
-#endif
-
-#endif /* DECODER_H_INCLUDED */
--- a/vm/vm.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1886 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Håkan Hjort
- * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
- *               2002-2004 the dvdnav project
- * 
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <fcntl.h>
-
-#include "nav_types.h"
-#include "ifo_types.h"
-#include "ifo_read.h"
-#include "dvd_types.h"
-
-#include "decoder.h"
-#include "remap.h"
-#include "vm.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-
-#ifdef _MSC_VER
-#include <io.h>   /* read() */
-#endif /* _MSC_VER */
-
-/*
-#define STRICT
-*/
-
-/* Local prototypes */
-
-/* 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);
-
-/* Process link - returns 1 if a hop has been performed */
-static int process_command(vm_t *vm,link_t link_values);
-
-/* Set */
-static int  set_TT(vm_t *vm, int tt);
-static int  set_PTT(vm_t *vm, int tt, int ptt);
-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);
-
-/* 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_PGCN(vm_t *vm);
-
-static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
-static pgcit_t* get_PGCIT(vm_t *vm);
-
-
-/* Helper functions */
-
-#ifdef TRACE
-static void vm_print_current_domain_state(vm_t *vm) {
-  switch((vm->state).domain) {
-    case VTS_DOMAIN:
-      fprintf(MSG_OUT, "libdvdnav: Video Title Domain: -\n");
-      break;
-
-    case VTSM_DOMAIN:
-      fprintf(MSG_OUT, "libdvdnav: Video Title Menu Domain: -\n");
-      break;
-
-    case VMGM_DOMAIN:
-      fprintf(MSG_OUT, "libdvdnav: Video Manager Menu Domain: -\n");
-      break;
-
-    case FP_DOMAIN: 
-      fprintf(MSG_OUT, "libdvdnav: First Play Domain: -\n");
-      break;
-
-    default:
-      fprintf(MSG_OUT, "libdvdnav: Unknown Domain: -\n");
-      break;
-  }
-  fprintf(MSG_OUT, "libdvdnav: VTS:%d PGC:%d PG:%u CELL:%u BLOCK:%u VTS_TTN:%u TTN:%u TT_PGCN:%u\n", 
-                   (vm->state).vtsN,
-                   get_PGCN(vm),
-                   (vm->state).pgN,
-                   (vm->state).cellN,
-                   (vm->state).blockN,
-                   (vm->state).VTS_TTN_REG,
-                   (vm->state).TTN_REG,
-                   (vm->state).TT_PGCN_REG);
-}
-#endif
-
-static void dvd_read_name(char *name, const char *device) {
-    /* Because we are compiling with _FILE_OFFSET_BITS=64
-     * all off_t are 64bit.
-     */
-    off_t off;
-    int fd, i;
-    uint8_t data[DVD_VIDEO_LB_LEN];
-
-    /* Read DVD name */
-    fd = open(device, O_RDONLY);
-    if (fd > 0) { 
-      off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET );
-      if( off == ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) {
-        off = read( fd, data, DVD_VIDEO_LB_LEN ); 
-        close(fd);
-        if (off == ( (off_t) DVD_VIDEO_LB_LEN )) {
-          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(MSG_OUT, "%c", data[i]);
-            } else {
-              fprintf(MSG_OUT, " ");
-            }
-          }
-          strncpy(name, &data[25], 48);
-          name[48] = 0;
-          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(MSG_OUT, "%c", data[i]);
-            } else {
-              fprintf(MSG_OUT, " ");
-            } 
-          }
-          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(MSG_OUT, "%c", data[i]);
-            } else {
-              fprintf(MSG_OUT, " ");
-            }
-          }
-          fprintf(MSG_OUT, "\n");
-        } else {
-          fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n");
-        }
-      } else {
-        fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 );
-      }
-      close(fd);
-    } else {
-    fprintf(MSG_OUT, "NAME OPEN FAILED\n");
-  }
-}
-
-static int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) {
-  if((vm->state).vtsN == vtsN) {
-    return 1; /*  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\n");
-    return 0;
-  }
-  if(!ifoRead_VTS_PTT_SRPT(vm->vtsi)) {
-    fprintf(MSG_OUT, "libdvdnav: ifoRead_VTS_PTT_SRPT failed\n");
-    return 0;
-  }
-  if(!ifoRead_PGCIT(vm->vtsi)) {
-    fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCIT failed\n");
-    return 0;
-  }
-  if(!ifoRead_PGCI_UT(vm->vtsi)) {
-    fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCI_UT failed\n");
-    return 0;
-  }
-  if(!ifoRead_VOBU_ADMAP(vm->vtsi)) {
-    fprintf(MSG_OUT, "libdvdnav: ifoRead_VOBU_ADMAP vtsi failed\n");
-    return 0;
-  }
-  if(!ifoRead_TITLE_VOBU_ADMAP(vm->vtsi)) {
-    fprintf(MSG_OUT, "libdvdnav: ifoRead_TITLE_VOBU_ADMAP vtsi failed\n");
-    return 0;
-  }
-  (vm->state).vtsN = vtsN;
-  
-  return 1;
-}
-
-
-/* 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;
-}
-
-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 */
-
-int vm_start(vm_t *vm) {
-  /* Set pgc to FP (First Play) pgc */
-  set_FP_PGC(vm);
-  process_command(vm, play_PGC(vm));
-  return !vm->stopped;
-}
-
-void vm_stop(vm_t *vm) {
-  if(vm->vmgi) {
-    ifoClose(vm->vmgi);
-    vm->vmgi=NULL;
-  }
-  if(vm->vtsi) {
-    ifoClose(vm->vtsi);
-    vm->vtsi=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((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 */
-  (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).domain             = FP_DOMAIN;
-  (vm->state).rsm_vtsN           = 0;
-  (vm->state).rsm_cellN          = 0;
-  (vm->state).rsm_blockN         = 0;
-  
-  (vm->state).vtsN               = -1;
-  
-  if (vm->dvd && dvdroot) {
-    /* a new dvd device has been requested */
-    vm_stop(vm);
-  }
-  if (!vm->dvd) {
-    vm->dvd = DVDOpen(dvdroot);
-    if(!vm->dvd) {
-      fprintf(MSG_OUT, "libdvdnav: vm: failed to open/read the DVD\n");
-      return 0;
-    }
-    dvd_read_name(vm->dvd_name, dvdroot);
-    vm->map  = remap_loadmap(vm->dvd_name);
-    vm->vmgi = ifoOpenVMGI(vm->dvd);
-    if(!vm->vmgi) {
-      fprintf(MSG_OUT, "libdvdnav: vm: failed to read VIDEO_TS.IFO\n");
-      return 0;
-    }
-    if(!ifoRead_FP_PGC(vm->vmgi)) {
-      fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_FP_PGC failed\n");
-      return 0;
-    }
-    if(!ifoRead_TT_SRPT(vm->vmgi)) {
-      fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_TT_SRPT failed\n");
-      return 0;
-    }
-    if(!ifoRead_PGCI_UT(vm->vmgi)) {
-      fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_PGCI_UT failed\n");
-      return 0;
-    }
-    if(!ifoRead_PTL_MAIT(vm->vmgi)) {
-      fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_PTL_MAIT failed\n");
-      /* return 0; Not really used for now.. */
-    }
-    if(!ifoRead_VTS_ATRT(vm->vmgi)) {
-      fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_VTS_ATRT failed\n");
-      /* 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 0; Not really used for now.. */
-    }
-    /* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
-  }
-  if (vm->vmgi) {
-    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 1;
-}
-
-
-/* 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;
-  if (vtsN > 0) {
-    (target->state).vtsN = 0;
-    if (!ifoOpenNewVTSI(target, target->dvd, vtsN))
-      assert(0);
-  
-    /* 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) {
-  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->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->block = (vm->state).blockN;
-
-  /* handle PGC stills at PGC end */
-  if ((vm->state).cellN == (vm->state).pgc->nr_of_cells)
-    position->still += (vm->state).pgc->still_time;
-  /* still already determined */
-  if (position->still)
-    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
-   * indication of a still is a cell playback time higher than the time the frames
-   * in this cell actually take to play (like 1 frame with 1 minute playback time).
-   * On the said BTTF disc, for these cells last_sector and last_vobu_start_sector
-   * are equal and the cells are very short, so we abuse these conditions to
-   * detect such discs. I consider these discs broken, so the fix is somewhat
-   * broken, too. */
-  if (((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector ==
-       (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_vobu_start_sector) &&
-      ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector -
-       (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector < 1024)) {
-    int time;
-    int size = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector -
-	       (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector;
-    time  = ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour   >> 4  ) * 36000;
-    time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour   & 0x0f) * 3600;
-    time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute >> 4  ) * 600;
-    time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0x0f) * 60;
-    time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second >> 4  ) * 10;
-    time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0x0f) * 1;
-    if (!time || size / time > 30)
-      /* datarate is too high, it might be a very short, but regular cell */
-      return;
-    if (time > 0xff) time = 0xff;
-    position->still = time;
-  }
-}
-
-void vm_get_next_cell(vm_t *vm) {
-  process_command(vm, play_Cell_post(vm));
-}
-
-
-/* Jumping */
-
-int vm_jump_pg(vm_t *vm, int pg) {
-  (vm->state).pgN = pg;
-  process_command(vm, play_PG(vm));
-  return 1;
-}
-
-int vm_jump_cell_block(vm_t *vm, int cell, int block) {
-  (vm->state).cellN = cell;
-  process_command(vm, play_Cell(vm));
-  /* play_Cell can jump to a different cell in case of angles */
-  if ((vm->state).cellN == cell)
-    (vm->state).blockN = block;
-  return 1;
-}
-
-int vm_jump_title_part(vm_t *vm, int title, int part) {
-  link_t link;
-  
-  if(!set_PTT(vm, title, part))
-    return 0;
-  /* Some DVDs do not want us to jump directly into a title and have
-   * PGC pre commands taking us back to some menu. Since we do not like that,
-   * we do not execute PGC pre commands that would do a jump. */
-  /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */
-  link = play_PGC_PG(vm, (vm->state).pgN);
-  if (link.command != PlayThis)
-    /* jump occured -> ignore it and play the PG anyway */
-    process_command(vm, play_PG(vm));
-  else
-    process_command(vm, link);
-  return 1;
-}
-
-int vm_jump_top_pg(vm_t *vm) {
-  process_command(vm, play_PG(vm));
-  return 1;
-}
-
-int vm_jump_next_pg(vm_t *vm) {
-  if((vm->state).pgN >= (vm->state).pgc->nr_of_programs) {
-    /* last program -> move to TailPGC */
-    process_command(vm, play_PGC_post(vm));
-    return 1;
-  } else {
-    vm_jump_pg(vm, (vm->state).pgN + 1);
-    return 1;
-  }
-}
-
-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 && 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;
-  } else {
-    vm_jump_pg(vm, (vm->state).pgN - 1);
-    return 1;
-  }
-}
-
-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 0;
-}
-
-int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) {
-  domain_t old_domain = (vm->state).domain;
-  
-  switch ((vm->state).domain) {
-  case VTS_DOMAIN:
-    set_RSMinfo(vm, 0, (vm->state).blockN);
-    /* FALL THROUGH */
-  case VTSM_DOMAIN:
-  case VMGM_DOMAIN:
-    switch(menuid) {
-    case DVD_MENU_Title:
-    case DVD_MENU_Escape:
-      (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;
-    }
-    break;
-  case FP_DOMAIN: /* FIXME XXX $$$ What should we do here? */
-    break;
-  }
-  
-  return 0;
-}
-
-int vm_jump_resume(vm_t *vm) {
-  link_t link_values = { LinkRSM, 0, 0, 0 };
-
-  if (!(vm->state).rsm_vtsN) /* Do we have resume info? */
-    return 0;
-  if (!process_command(vm, link_values))
-    return 0;
-  return 1;
-}
-
-int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd) {
-  link_t link_values;
-  
-  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_menu(vm_t *vm, int *menuid) {
-  pgcit_t* pgcit;
-  int pgcn;
-  pgcn = (vm->state).pgcN;
-  pgcit = get_PGCIT(vm);
-  if(pgcit==NULL) return 0;
-  *menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ;
-  return 1;
-}
-
-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) {
-	if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn  == pgN) {
-	  found = 1;
-          break;
-	}
-	if (part > 0 && vts_ptt_srpt->title[vts_ttn].ptt[part].pgn > pgN &&
-	    vts_ptt_srpt->title[vts_ttn].ptt[part - 1].pgn < pgN) {
-	  part--;
-	  found = 1;
-	  break;
-	}
-      }
-    }
-    if (found) break;
-  }
-  vts_ttn++;
-  part++;
-  
-  if (!found) {
-    fprintf(MSG_OUT, "libdvdnav: chapter NOT FOUND!\n");
-    return 0;
-  }
-
-  title = get_TT(vm, vm->state.vtsN, vts_ttn);
-
-#ifdef TRACE
-  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[vts_ttn-1].ptt[part-1].pgcn ,
-             vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn );
-  }
-#endif
-  *title_result = title;
-  *part_result = part;
-  return 1;
-}
-
-/* Return the substream id for 'logical' audio stream audioN.
- * 0 <= audioN < 8
- */
-int vm_get_audio_stream(vm_t *vm, int audioN) {
-  int streamN = -1;
-
-  if((vm->state).domain != VTS_DOMAIN)
-    audioN = 0;
-  
-  if(audioN < 8) {
-    /* Is there any control info for this logical stream */ 
-    if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
-      streamN = ((vm->state).pgc->audio_control[audioN] >> 8) & 0x07;  
-    }
-  }
-  
-  if((vm->state).domain != VTS_DOMAIN && streamN == -1)
-    streamN = 0;
-  
-  /* 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.
- * 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 streamN = -1;
-  int source_aspect = vm_get_video_aspect(vm);
-  
-  if((vm->state).domain != VTS_DOMAIN)
-    subpN = 0;
-  
-  if(subpN < 32) { /* a valid logical stream */
-    /* Is this logical stream present */ 
-    if((vm->state).pgc->subp_control[subpN] & (1<<31)) {
-      if(source_aspect == 0) /* 4:3 */	     
-	streamN = ((vm->state).pgc->subp_control[subpN] >> 24) & 0x1f;  
-      if(source_aspect == 3) /* 16:9 */
-        switch (mode) {
-	case 0:
-	  streamN = ((vm->state).pgc->subp_control[subpN] >> 16) & 0x1f;
-	  break;
-	case 1:
-	  streamN = ((vm->state).pgc->subp_control[subpN] >> 8) & 0x1f;
-	  break;
-	case 2:
-	  streamN = (vm->state).pgc->subp_control[subpN] & 0x1f;
-	}
-    }
-  }
-  
-  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_audio_active_stream(vm_t *vm) {
-  int audioN;
-  int streamN;
-  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(audioN = 0; audioN < 8; audioN++) {
-      if((vm->state).pgc->audio_control[audioN] & (1<<15)) {
-        if ((streamN = vm_get_audio_stream(vm, audioN)) >= 0)
-          break;
-      }
-    }
-  }
-
-  return streamN;
-}
-
-int vm_get_subp_active_stream(vm_t *vm, int mode) {
-  int subpN;
-  int streamN;
-  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(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;
-      }
-    }
-  }
-
-  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 *current, int *num_avail) {
-  *num_avail = 1;
-  *current = 1;
-  
-  if((vm->state).domain == VTS_DOMAIN) {
-    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];
-    if(title->title_set_nr != (vm->state).vtsN || 
-       title->vts_ttn != (vm->state).VTS_TTN_REG)
-      return; 
-    *num_avail = title->nr_of_angles;
-    *current = (vm->state).AGL_REG;
-  }
-}
-
-#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;
-    break;
-  case VTSM_DOMAIN:
-    *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; /*  1 */
-    *current = 1;
-    break;
-  case VMGM_DOMAIN:
-  case FP_DOMAIN:
-    *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; /*  1 */
-    *current = 1;
-    break;
-  }
-}
-
-/* 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;
-    break;
-  case VTSM_DOMAIN:
-    *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; /*  1 */
-    *current = 0x41;
-    break;
-  case VMGM_DOMAIN:
-  case FP_DOMAIN:
-    *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; /*  1 */
-    *current = 0x41;
-    break;
-  }
-}
-
-/* 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;
-  else
-    *height = 480;
-  switch(attr.picture_size) {
-  case 0:
-    *width = 720;
-    break;
-  case 1:
-    *width = 704;
-    break;
-  case 2:
-    *width = 352;
-    break;
-  case 3:
-    *width = 352;
-    *height /= 2;
-    break;
-  }
-}
-#endif
-
-int vm_get_video_aspect(vm_t *vm) {
-  int aspect = vm_get_video_attr(vm).display_aspect_ratio;
-  
-  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) {
-  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;
-  default:
-    abort();
-  }
-}
-
-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;
-  default:
-    abort();
-  }
-}
-
-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;
-  default:
-    abort();
-  }
-}
-
-
-/* Playback control */
-
-static link_t play_PGC(vm_t *vm) {
-  link_t link_values;
-  
-#ifdef TRACE
-  fprintf(MSG_OUT, "libdvdnav: play_PGC:");
-  if((vm->state).domain != FP_DOMAIN) {
-    fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
-  } else {
-    fprintf(MSG_OUT, " first_play_pgc\n");
-  }
-#endif
-
-  /* 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 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, 
-		  &(vm->state).registers, &link_values)) {
-      /*  link_values contains the 'jump' return value */
-      return link_values;
-    } else {
-#ifdef TRACE
-      fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
-#endif
-    }
-  }
-  return play_PG(vm);
-}  
-
-static link_t play_PGC_PG(vm_t *vm, int pgN) {    
-  link_t link_values;
-  
-#ifdef TRACE
-  fprintf(MSG_OUT, "libdvdnav: play_PGC_PG:");
-  if((vm->state).domain != FP_DOMAIN) {
-    fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm));
-  } else {
-    fprintf(MSG_OUT, " first_play_pgc\n");
-  }
-#endif
-
-  /*  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 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, 
-		  &(vm->state).registers, &link_values)) {
-      /*  link_values contains the 'jump' return value */
-      return link_values;
-    } else {
-#ifdef TRACE
-      fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n");
-#endif
-    }
-  }
-  return play_PG(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
-  
-  /* 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 && (vm->state).pgc->command_tbl->nr_of_post &&
-     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
-  /* Should end up in the STOP_DOMAIN if next_pgc is 0. */
-  if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) {
-    link_values.command = Exit;
-    return link_values;
-  }
-  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
-  
-  assert((vm->state).pgN > 0);
-  if((vm->state).pgN > (vm->state).pgc->nr_of_programs) {
-#ifdef TRACE
-    fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i) > pgc->nr_of_programs (%i)\n", 
-	    (vm->state).pgN, (vm->state).pgc->nr_of_programs );
-#endif
-    assert((vm->state).pgN == (vm->state).pgc->nr_of_programs + 1); 
-    return play_PGC_post(vm);
-  }
-  
-  (vm->state).cellN = (vm->state).pgc->program_map[(vm->state).pgN - 1];
-  
-  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};
-
-#ifdef TRACE
-  fprintf(MSG_OUT, "libdvdnav: play_Cell: (vm->state).cellN (%i)\n", (vm->state).cellN);
-#endif
-  
-  assert((vm->state).cellN > 0);
-  if((vm->state).cellN > (vm->state).pgc->nr_of_cells) {
-#ifdef TRACE
-    fprintf(MSG_OUT, "libdvdnav: (vm->state).cellN (%i) > pgc->nr_of_cells (%i)\n", 
-	    (vm->state).cellN, (vm->state).pgc->nr_of_cells );
-#endif
-    assert((vm->state).cellN == (vm->state).pgc->nr_of_cells + 1); 
-    return play_PGC_post(vm);
-  }
-  
-  /* Multi angle/Interleaved */
-  switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) {
-  case 0: /*  Normal */
-    assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
-    break;
-  case 1: /*  The first cell in the block */
-    switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
-    case 0: /*  Not part of a block */
-      assert(0);
-      break;
-    case 1: /*  Angle 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);
-#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: /*  ?? */
-    default:
-      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? */
-  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)) {
-    /* Should not happen */
-    assert(0);
-    return play_PGC_post(vm);
-  }
-  (vm->state).cell_restart++;
-  (vm->state).blockN = 0;
-#ifdef TRACE
-  fprintf(MSG_OUT, "libdvdnav: Cell should restart here\n");
-#endif
-  return play_this;
-}
-
-static link_t play_Cell_post(vm_t *vm) {
-  cell_playback_t *cell;
-  
-#ifdef TRACE
-  fprintf(MSG_OUT, "libdvdnav: play_Cell_post: (vm->state).cellN (%i)\n", (vm->state).cellN);
-#endif
-  
-  cell = &(vm->state).pgc->cell_playback[(vm->state).cellN - 1];
-  
-  /* Still time is already taken care of before we get called. */
-  
-  /* Deal with a Cell command, if any */
-  if(cell->cell_cmd_nr != 0) {
-    link_t link_values;
-    
-/*  These asserts are now not needed.
- *  Some DVDs have no cell commands listed in the PGC,
- *  but the Cell itself points to a cell command that does not exist.
- *  For this situation, just ignore the cell command and continue.
- *
- *  assert((vm->state).pgc->command_tbl != NULL);
- *  assert((vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr);
- */
-
-    if ((vm->state).pgc->command_tbl != NULL &&
-        (vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) {
-#ifdef TRACE
-      fprintf(MSG_OUT, "libdvdnav: Cell command present, executing\n");
-#endif
-      if(vmEval_CMD(&(vm->state).pgc->command_tbl->cell_cmds[cell->cell_cmd_nr - 1], 1,
-		    &(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");
-#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) {
-  case 0: /*  Normal */
-    assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0);
-    (vm->state).cellN++;
-    break;
-  case 1: /*  The first cell in the block */
-  case 2: /*  A cell in the block */
-  case 3: /*  The last cell in the block */
-  default:
-    switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) {
-    case 0: /*  Not part of a block */
-      assert(0);
-      break;
-    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) {
-	(vm->state).cellN++;
-      }
-      break;
-    case 2: /*  ?? */
-    case 3: /*  ?? */
-    default:
-      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)) {
-#ifdef TRACE
-    fprintf(MSG_OUT, "libdvdnav: last cell in this PGC\n");
-#endif
-    return play_PGC_post(vm);
-  }
-  return play_Cell(vm);
-}
-
-
-/* link processing */
-
-static int process_command(vm_t *vm, link_t link_values) {
-  
-  while(link_values.command != PlayThis) {
-    
-#ifdef TRACE
-    fprintf(MSG_OUT, "libdvdnav: Before printout starts:\n");
-    vm_print_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:
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      return 0;  /* no actual jump */
-
-    case LinkTopC:
-      /* Restart playing from the beginning of the current Cell. */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      link_values = play_Cell(vm);
-      break;
-    case LinkNextC:
-      /* Link to Next Cell */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      (vm->state).cellN += 1;
-      link_values = play_Cell(vm);
-      break;
-    case LinkPrevC:
-      /* Link to Previous Cell */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      assert((vm->state).cellN > 1);
-      (vm->state).cellN -= 1;
-      link_values = play_Cell(vm);
-      break;
-      
-    case LinkTopPG:
-      /* Link to Top of current Program */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      link_values = play_PG(vm);
-      break;
-    case LinkNextPG:
-      /* Link to Next Program */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      (vm->state).pgN += 1;
-      link_values = play_PG(vm);
-      break;
-    case LinkPrevPG:
-      /* Link to Previous Program */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      assert((vm->state).pgN > 1);
-      (vm->state).pgN -= 1;
-      link_values = play_PG(vm);
-      break;
-
-    case LinkTopPGC:
-      /* Restart playing from beginning of current Program Chain */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      link_values = play_PGC(vm);
-      break;
-    case LinkNextPGC:
-      /* Link to Next Program Chain */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      assert((vm->state).pgc->next_pgc_nr != 0);
-      if(set_PGCN(vm, (vm->state).pgc->next_pgc_nr))
-	link_values = play_PGC(vm);
-      else
-	link_values.command = Exit;
-      break;
-    case LinkPrevPGC:
-      /* Link to Previous Program Chain */
-      /* BUTTON number:data1 */
-      if(link_values.data1 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data1 << 10;
-      assert((vm->state).pgc->prev_pgc_nr != 0);
-      if(set_PGCN(vm, (vm->state).pgc->prev_pgc_nr))
-	link_values = play_PGC(vm);
-      else
-	link_values.command = Exit;
-      break;
-    case LinkGoUpPGC:
-      /* 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_PGCN(vm, (vm->state).pgc->goup_pgc_nr))
-	link_values = play_PGC(vm);
-      else
-	link_values.command = Exit;
-      break;
-    case LinkTailPGC:
-      /* Link to Tail of Program Chain */
-      /* BUTTON number:data1 */
-      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 point */
-	int i;
-	
-	/* Check and see if there is any rsm info!! */
-	if (!(vm->state).rsm_vtsN) {
-	  fprintf(MSG_OUT, "libdvdnav: trying to resume without any resume info set\n");
-	  link_values.command = Exit;
-	  break;
-	}
-	
-	(vm->state).domain = VTS_DOMAIN;
-	if (!ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN))
-	  assert(0);
-	set_PGCN(vm, (vm->state).rsm_pgcN);
-	
-	/* These should never be set in SystemSpace and/or MenuSpace */ 
-	/* (vm->state).TTN_REG = rsm_tt; ?? */
-	/* (vm->state).TT_PGCN_REG = (vm->state).rsm_pgcN; ?? */
-	for(i = 0; i < 5; i++) {
-	  (vm->state).registers.SPRM[4 + i] = (vm->state).rsm_regs[i];
-	}
-	
-	if(link_values.data1 != 0)
-	  (vm->state).HL_BTNN_REG = link_values.data1 << 10;
-	
-	if((vm->state).rsm_cellN == 0) {
-	  assert((vm->state).cellN); /*  Checking if this ever happens */
-	  (vm->state).pgN = 1;
-	  link_values = play_PG(vm);
-	} else { 
-	  /* (vm->state).pgN = ?? this gets the right value in set_PGN() below */
-	  (vm->state).cellN = (vm->state).rsm_cellN;
-	  link_values.command = PlayThis;
-	  link_values.data1 = (vm->state).rsm_blockN & 0xffff;
-	  link_values.data2 = (vm->state).rsm_blockN >> 16;
-	  if(!set_PGN(vm)) {
-	    /* Were at the end of the PGC, should not happen for a RSM */
-	    assert(0);
-	    link_values.command = LinkTailPGC;
-	    link_values.data1 = 0;  /* No button */
-	  }
-	}
-      }
-      break;
-    case LinkPGCN:
-      /* Link to Program Chain Number:data1 */
-      if(!set_PGCN(vm, link_values.data1))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-    case LinkPTTN:
-      /* Link to Part of current Title Number:data1 */
-      /* BUTTON number:data2 */
-      /* PGC Pre-Commands are not executed */
-      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))
-	assert(0);
-      link_values = play_PG(vm);
-      break;
-    case LinkPGN:
-      /* Link to Program Number:data1 */
-      /* BUTTON number:data2 */
-      if(link_values.data2 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data2 << 10;
-      /* Update any other state, PTTN perhaps? */
-      (vm->state).pgN = link_values.data1;
-      link_values = play_PG(vm);
-      break;
-    case LinkCN:
-      /* Link to Cell Number:data1 */
-      /* BUTTON number:data2 */
-      if(link_values.data2 != 0)
-	(vm->state).HL_BTNN_REG = link_values.data2 << 10;
-      /* Update any other state, pgN, PTTN perhaps? */
-      (vm->state).cellN = link_values.data1;
-      link_values = play_Cell(vm);
-      break;
-      
-    case Exit:
-      vm->stopped = 1;
-      return 0;
-      
-    case JumpTT:
-      /* Jump to VTS Title Domain */
-      /* Only allowed from the First Play domain(PGC) */
-      /* or the Video Manager domain (VMG) */
-      /* Stop SPRM9 Timer */
-      /* Set SPRM1 and SPRM2 */
-      assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
-      if(set_TT(vm, link_values.data1))
-        link_values = play_PGC(vm);
-      else
-	link_values.command = Exit;
-      break;
-    case JumpVTS_TT:
-      /* Jump to Title:data1 in same VTS Title Domain */
-      /* Only allowed from the VTS Menu Domain(VTSM) */
-      /* or the Video Title Set Domain(VTS) */
-      /* Stop SPRM9 Timer */
-      /* Set SPRM1 and SPRM2 */
-      assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
-      if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-    case JumpVTS_PTT:
-      /* Jump to Part:data2 of Title:data1 in same VTS Title Domain */
-      /* Only allowed from the VTS Menu Domain(VTSM) */
-      /* or the Video Title Set Domain(VTS) */
-      /* Stop SPRM9 Timer */
-      /* Set SPRM1 and SPRM2 */
-      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))
-	assert(0);
-      link_values = play_PGC_PG(vm, (vm->state).pgN);
-      break;
-      
-    case JumpSS_FP:
-      /* Jump to First Play Domain */
-      /* Only allowed from the VTS Menu Domain(VTSM) */
-      /* or the Video Manager domain (VMG) */
-      /* Stop SPRM9 Timer and any GPRM counters */
-      assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN); /* ?? */
-      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 */
-      /* Stop SPRM9 Timer and any GPRM counters */
-      assert((vm->state).domain != VTS_DOMAIN); /* ?? */
-      (vm->state).domain = VMGM_DOMAIN;
-      if(!set_MENU(vm, link_values.data1))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-    case JumpSS_VTSM:
-      /* Jump to a menu in Video Title domain, */
-      /* or to a Menu is the current VTS */
-      /* Stop SPRM9 Timer and any GPRM counters */
-      /* ifoOpenNewVTSI:data1 */
-      /* VTS_TTN_REG:data2 */
-      /* get_MENU:data3 */ 
-      if(link_values.data1 != 0) {
-	if (link_values.data1 != (vm->state).vtsN) {
-	  /* the normal case */
-	  assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
-	  (vm->state).domain = VTSM_DOMAIN;
-	  if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1))  /* Also sets (vm->state).vtsN */
-	    assert(0);
-	} else {
-	  /* This happens on some discs like "Captain Scarlet & the Mysterons" or
-	   * the German RC2 of "Anatomie" in VTSM. */
-	  assert((vm->state).domain == VTSM_DOMAIN ||
-	    (vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
-	  (vm->state).domain = VTSM_DOMAIN;
-	}
-      } else {
-	/*  This happens on 'The Fifth Element' region 2. */
-	assert((vm->state).domain == VTSM_DOMAIN);
-      }
-      /*  I don't know what title is supposed to be used for. */
-      /*  Alien or Aliens has this != 1, I think. */
-      /* assert(link_values.data2 == 1); */
-      (vm->state).VTS_TTN_REG = link_values.data2;
-      /* TTN_REG (SPRM4), VTS_TTN_REG (SPRM5), TT_PGCN_REG (SPRM6) are linked, */
-      /* so if one changes, the others must change to match it. */
-      (vm->state).TTN_REG     = get_TT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG);
-      if(!set_MENU(vm, link_values.data3))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-    case JumpSS_VMGM_PGC:
-      /* set_PGCN:data1 */
-      /* Stop SPRM9 Timer and any GPRM counters */
-      assert((vm->state).domain != VTS_DOMAIN); /* ?? */
-      (vm->state).domain = VMGM_DOMAIN;
-      if(!set_PGCN(vm, link_values.data1))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-      
-    case CallSS_FP:
-      /* 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:
-      /* 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))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-    case CallSS_VTSM:
-      /* 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))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-    case CallSS_VMGM_PGC:
-      /* 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_PGCN(vm, link_values.data1))
-	assert(0);
-      link_values = play_PGC(vm);
-      break;
-    case PlayThis:
-      /* Should never happen. */
-      assert(0);
-      break;
-    }
-
-#ifdef TRACE
-    fprintf(MSG_OUT, "libdvdnav: After printout starts:\n");
-    vm_print_current_domain_state(vm);
-    fprintf(MSG_OUT, "libdvdnav: After printout ends.\n");
-#endif
-    
-  }
-  (vm->state).blockN = link_values.data1 | (link_values.data2 << 16);
-  return 1;
-}
-
-
-/* Set functions */
-
-static int set_TT(vm_t *vm, int tt) {  
-  return set_PTT(vm, tt, 1);
-}
-
-static int set_PTT(vm_t *vm, int tt, int ptt) {
-  assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
-  return set_VTS_PTT(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
-		     vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, ptt);
-}
-
-static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn) {
-  return set_VTS_PTT(vm, vtsN, vts_ttn, 1);
-}
-
-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)
-    if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN))  /* Also sets (vm->state).vtsN */
-      return 0;
-  
-  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 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    = part;
-  (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 */
-  /* Any other registers? */
-  
-  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;
-  if (!vm->vmgi->first_play_pgc) {
-    return set_PGCN(vm, 1);
-  }
-  (vm->state).pgc = vm->vmgi->first_play_pgc;
-  (vm->state).pgcN = vm->vmgi->vmgi_mat->first_play_pgc;
-  return 1;
-}
-
-
-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));
-}
-
-static int set_PGCN(vm_t *vm, int pgcN) {
-  pgcit_t *pgcit;
-  
-  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).pgcN = pgcN;
-  (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, part;
-      vm_get_current_title_part(vm, &dummy, &part);
-      (vm->state).PTTN_REG = part;
-    } else {
-      /* FIXME: Handle RANDOM or SHUFFLE titles. */
-      fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n");
-    }
-  }
-  return 1;
-}
-
-/* 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) {
-  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) {
-      fprintf(MSG_OUT, "libdvdnav: Available menus: 0x%x\n",
-                     pgcit->pgci_srp[i].entry_id & 0x7f);
-    }
-  }
-#endif
-  return 0; /*  error */
-}
-
-/* FIXME: we have a pgcN member in the vm's state now, so this should be obsolete */
-static int get_PGCN(vm_t *vm) {
-  pgcit_t *pgcit;
-  int pgcN = 1;
-
-  pgcit = get_PGCIT(vm);
-  
-  if (pgcit) {
-    while(pgcN <= pgcit->nr_of_pgci_srp) {
-      if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) {
-	assert((vm->state).pgcN == pgcN);
-	return pgcN;
-      }
-      pgcN++;
-    }
-  }
-  fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n", 
-         (vm->state).domain);
-  return 0; /*  error */
-}
-
-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) {
-    fprintf(MSG_OUT, "libdvdnav: *** pgci_ut handle is NULL ***\n");
-    return NULL; /*  error? */
-  }
-  
-  i = 0;
-  while(i < h->pgci_ut->nr_of_lus
-	&& h->pgci_ut->lu[i].lang_code != lang)
-    i++;
-  if(i == h->pgci_ut->nr_of_lus) {
-    fprintf(MSG_OUT, "libdvdnav: Language '%c%c' not found, using '%c%c' instead\n",
-	    (char)(lang >> 8), (char)(lang & 0xff),
- 	    (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++) {
-      fprintf(MSG_OUT, "%c%c ",
- 	    (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? */
-  }
-  
-  return h->pgci_ut->lu[i].pgcit;
-}
-
-/* Uses state to decide what to return */
-static pgcit_t* get_PGCIT(vm_t *vm) {
-  pgcit_t *pgcit = NULL;
-  
-  switch ((vm->state).domain) {
-  case VTS_DOMAIN:
-    if(!vm->vtsi) return NULL;
-    pgcit = vm->vtsi->vts_pgcit;
-    break;
-  case VTSM_DOMAIN:
-    if(!vm->vtsi) return NULL;
-    pgcit = get_MENU_PGCIT(vm, vm->vtsi, (vm->state).registers.SPRM[0]);
-    break;
-  case VMGM_DOMAIN:
-  case FP_DOMAIN:
-    pgcit = get_MENU_PGCIT(vm, vm->vmgi, (vm->state).registers.SPRM[0]);
-    break;
-  default:
-    abort();
-  }
-  
-  return pgcit;
-}
-
-//return the ifo_handle_t describing required title, used to 
-//identify chapters
-ifo_handle_t *vm_get_title_ifo(vm_t *vm, uint32_t title)
-{
-  ifo_handle_t *ifo = NULL;
-  uint8_t titleset_nr;
-  if((title < 1) || (title > vm->vmgi->tt_srpt->nr_of_srpts))
-    return NULL;
-  titleset_nr = vm->vmgi->tt_srpt->title[title-1].title_set_nr;
-  ifo = ifoOpen(vm->dvd, titleset_nr);
-  return ifo;
-}
-
-void vm_ifo_close(ifo_handle_t *ifo)
-{
-  ifoClose(ifo);
-}
-
-/* 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
-
--- a/vm/vm.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Håkan Hjort
- * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net>
- * 
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifndef VM_H_INCLUDED
-#define VM_H_INCLUDED
-
-/* DOMAIN enum */
-
-typedef enum {
-  FP_DOMAIN   = 1,
-  VTS_DOMAIN  = 2,
-  VMGM_DOMAIN = 4,
-  VTSM_DOMAIN = 8
-} domain_t;  
-
-/**
- * State: SPRM, GPRM, Domain, pgc, pgN, cellN, ?
- */
-typedef struct {
-  registers_t registers;
-  
-  domain_t  domain;
-  int       vtsN;         /* 0 is vmgm? */
-  pgc_t    *pgc;          /* either this or 'int pgcN' is enough? */
-  int       pgcN;         /* but provide pgcN for quick lookup */
-  int       pgN;          /* is this needed? can allways fid pgN from cellN? */
-  int       cellN;
-  int32_t   cell_restart; /* get cell to restart */
-  int       blockN;
-  
-  /* Resume info */
-  int      rsm_vtsN;
-  int      rsm_blockN;    /* of nav_packet */
-  uint16_t rsm_regs[5];   /* system registers 4-8 */
-  int      rsm_pgcN;
-  int      rsm_cellN;
-} dvd_state_t;
-
-typedef struct vm_position_s {
-  int16_t  button;        /* Button highlighted */
-  int32_t  vts;           /* vts number to use */
-  domain_t domain;        /* domain to use */
-  int32_t  spu_channel;   /* spu channel to use */
-  int32_t  angle_channel; /* angle channel to use */
-  int32_t  audio_channel; /* audio channel to use */
-  int32_t  hop_channel;   /* channel hopping. E.g menu button pressed */
-#if 0
-  /* currently unused */
-  int32_t  title;         /* title number */
-  int32_t  chapter;       /* chapter number */
-#endif
-  int32_t  cell;          /* cell number */
-  int32_t  cell_restart;  /* get cell to restart */
-  int32_t  cell_start;    /* sector number of start of current cell in use */
-  int32_t  still;         /* is cell still */
-  int32_t  block;         /* block number within cell in use */
-} vm_position_t;
-
-typedef struct {
-  dvd_reader_t *dvd;
-  ifo_handle_t *vmgi;
-  ifo_handle_t *vtsi;
-  dvd_state_t   state;
-  int32_t       hop_channel;
-  char          dvd_name[50];
-  remap_t      *map;
-  int           stopped;
-} vm_t;
-
-/* magic number for seeking hops */
-#define HOP_SEEK 0x1000
-
-
-/*  Audio stream number */
-#define AST_REG      registers.SPRM[1]
-/*  Subpicture stream number */
-#define SPST_REG     registers.SPRM[2]
-/*  Angle number */
-#define AGL_REG      registers.SPRM[3]
-/*  Title Track Number */
-#define TTN_REG      registers.SPRM[4]
-/*  VTS Title Track Number */
-#define VTS_TTN_REG  registers.SPRM[5]
-/*  PGC Number for this Title Track */
-#define TT_PGCN_REG  registers.SPRM[6]
-/*  Current Part of Title (PTT) number for (One_Sequential_PGC_Title) */
-#define PTTN_REG     registers.SPRM[7]
-/*  Highlighted Button Number (btn nr 1 == value 1024) */
-#define HL_BTNN_REG  registers.SPRM[8]
-/*  Parental Level */
-#define PTL_REG      registers.SPRM[13]
-
-/* Initialisation & destruction */
-vm_t *vm_new_vm(void);
-void  vm_free_vm(vm_t *vm);
-
-/* IFO access */
-ifo_handle_t *vm_get_vmgi(vm_t *vm);
-ifo_handle_t *vm_get_vtsi(vm_t *vm);
-
-/* Reader Access */
-dvd_reader_t *vm_get_dvd_reader(vm_t *vm);
-
-/* Basic Handling */
-int  vm_start(vm_t *vm);
-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);
-
-/* Jumping - all these return 1, if a hop has been performed */
-int vm_jump_pg(vm_t *vm, int pg);
-int vm_jump_cell_block(vm_t *vm, int cell, int block);
-int vm_jump_title_part(vm_t *vm, int title, int part);
-int vm_jump_top_pg(vm_t *vm);
-int vm_jump_next_pg(vm_t *vm);
-int vm_jump_prev_pg(vm_t *vm);
-int vm_jump_up(vm_t *vm);
-int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid);
-int vm_jump_resume(vm_t *vm);
-int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd);
-
-/* getting information */
-int vm_get_current_menu(vm_t *vm, int *menuid);
-int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result);
-int vm_get_audio_stream(vm_t *vm, int audioN);
-int vm_get_subp_stream(vm_t *vm, int subpN, int mode);
-int vm_get_audio_active_stream(vm_t *vm);
-int vm_get_subp_active_stream(vm_t *vm, int mode);
-void vm_get_angle_info(vm_t *vm, int *current, int *num_avail);
-#if 0
-/* currently unused */
-void vm_get_audio_info(vm_t *vm, int *current, int *num_avail);
-void vm_get_subp_info(vm_t *vm, int *current, int *num_avail);
-void vm_get_video_res(vm_t *vm, int *width, int *height);
-#endif
-int  vm_get_video_aspect(vm_t *vm);
-int  vm_get_video_scale_permission(vm_t *vm);
-video_attr_t vm_get_video_attr(vm_t *vm);
-audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN);
-subp_attr_t  vm_get_subp_attr(vm_t *vm, int streamN);
-ifo_handle_t *vm_get_title_ifo(vm_t *vm, uint32_t title);
-void vm_ifo_close(ifo_handle_t *ifo);
-
-/* Uncomment for VM command tracing */
-/* #define TRACE */
-#ifdef TRACE
-/* Debug */
-void vm_position_print(vm_t *vm, vm_position_t *position);
-#endif
-
-
-#endif /* VM_HV_INCLUDED */
--- a/vm/vmcmd.c	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,549 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
- *               2002-2004 the dvdnav project
- * 
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <sys/time.h>
-
-#include "dvd_types.h"
-#include "nav_types.h"
-#include "ifo_types.h"
-#include "decoder.h"
-#include "remap.h"
-#include "vm.h"
-#include "vmcmd.h"
-#include "dvdnav.h"
-#include "dvdnav_internal.h"
-
-/*  freebsd compatibility */
-#ifndef PRIu8
-#define PRIu8 "d"
-#endif
-
-/*  freebsd compatibility */
-#ifndef PRIu16
-#define PRIu16 "d"
-#endif
-
-static const char cmp_op_table[][4] = {
-  "", "&", "==", "!=", ">=", ">", "<=", "<"
-};
-static const char set_op_table[][4] = {
-  "", "=", "<->", "+=", "-=", "*=", "/=", "%=", "rnd", "&=", "|=", "^="
-};
-
-static const char link_table[][16] = {
-  "LinkNoLink",  "LinkTopC",    "LinkNextC",   "LinkPrevC",
-  "",            "LinkTopPG",   "LinkNextPG",  "LinkPrevPG",
-  "",            "LinkTopPGC",  "LinkNextPGC", "LinkPrevPGC",
-  "LinkGoUpPGC", "LinkTailPGC", "",            "",
-  "RSM"
-};
-
-static const char *const system_reg_table[] = {
-  "Menu Description Language Code",
-  "Audio Stream Number",
-  "Sub-picture Stream Number",
-  "Angle Number",
-  "Title Track Number",
-  "VTS Title Track Number",
-  "VTS PGC Number",
-  "PTT Number for One_Sequential_PGC_Title",
-  "Highlighted Button Number",
-  "Navigation Timer",
-  "Title PGC Number for Navigation Timer",
-  "Audio Mixing Mode for Karaoke",
-  "Country Code for Parental Management",
-  "Parental Level",
-  "Player Configurations for Video",
-  "Player Configurations for Audio",
-  "Initial Language Code for Audio",
-  "Initial Language Code Extension for Audio",
-  "Initial Language Code for Sub-picture",
-  "Initial Language Code Extension for Sub-picture",
-  "Player Regional Code",
-  "Reserved 21",
-  "Reserved 22",
-  "Reserved 23"
-};
-
-static const char system_reg_abbr_table[][8] = {
-  "",
-  "ASTN",
-  "SPSTN",
-  "AGLN",
-  "TTN",
-  "VTS_TTN",
-  "TT_PGCN",
-  "PTTN",
-  "HL_BTNN",
-  "NVTMR",
-  "NV_PGCN",
-  "",
-  "CC_PLT",
-  "PLT",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-};
-
-static void print_system_reg(uint16_t reg) {
-  if(reg < sizeof(system_reg_abbr_table) / sizeof(system_reg_abbr_table[0]))
-    fprintf(MSG_OUT, "%s (SRPM:%d)", system_reg_table[reg], reg);
-  else
-    fprintf(MSG_OUT, " WARNING: Unknown system register ( reg=%d ) ", reg);
-}
-
-static void print_g_reg(uint8_t reg) {
-    if(reg < 16)
-      fprintf(MSG_OUT, "g[%" PRIu8 "]", reg);
-    else
-      fprintf(MSG_OUT, " WARNING: Unknown general register ");
-}
-
-static void print_reg(uint8_t reg) {
-  if(reg & 0x80)
-    print_system_reg(reg & 0x7f);
-  else
-    print_g_reg(reg & 0x7f);
-}
-
-static void print_cmp_op(uint8_t op) {
-  if(op < sizeof(cmp_op_table) / sizeof(cmp_op_table[0]))
-    fprintf(MSG_OUT, " %s ", cmp_op_table[op]);
-  else
-    fprintf(MSG_OUT, " WARNING: Unknown compare op ");
-}
-
-static void print_set_op(uint8_t op) {
-  if(op < sizeof(set_op_table) / sizeof(cmp_op_table[0]))
-    fprintf(MSG_OUT, " %s ", set_op_table[op]);
-  else
-    fprintf(MSG_OUT, " WARNING: Unknown set op ");
-}
-
-static void print_reg_or_data(command_t* command, int immediate, int start) {
-  if(immediate) {
-    uint32_t i = vm_getbits(command, start, 16);
-    
-    fprintf(MSG_OUT, "0x%x", i);
-    if(isprint(i & 0xff) && isprint((i>>8) & 0xff))
-      fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff));
-  } else {
-    print_reg(vm_getbits(command, start - 8, 8));
-  }
-}
-
-static void print_reg_or_data_2(command_t* command, int immediate, int start) {
-  if(immediate)
-    fprintf(MSG_OUT, "0x%x", vm_getbits(command, start - 1, 7));
-  else
-    fprintf(MSG_OUT, "g[%" PRIu8 "]", vm_getbits(command, start - 4, 4));
-}
-
-static void print_reg_or_data_3(command_t* command, int immediate, int start) {
-  if(immediate) {
-    uint32_t i = vm_getbits(command, start, 16);
-    
-    fprintf(MSG_OUT, "0x%x", i);
-    if(isprint(i & 0xff) && isprint((i>>8) & 0xff))
-      fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff));
-  } else {
-    print_reg(vm_getbits(command, start, 8));
-  }
-}
-
-
-static void print_if_version_1(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  
-  if(op) {
-    fprintf(MSG_OUT, "if (");
-    print_g_reg(vm_getbits(command,39,8));
-    print_cmp_op(op);
-    print_reg_or_data(command, vm_getbits(command, 55,1), 31);
-    fprintf(MSG_OUT, ") ");
-  }
-}
-
-static void print_if_version_2(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  
-  if(op) {
-    fprintf(MSG_OUT, "if (");
-    print_reg(vm_getbits(command, 15, 8));
-    print_cmp_op(op);
-    print_reg(vm_getbits(command, 7, 8));
-    fprintf(MSG_OUT, ") ");
-  }
-}
-
-static void print_if_version_3(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  
-  if(op) {
-    fprintf(MSG_OUT, "if (");
-    print_g_reg(vm_getbits(command, 43, 4));
-    print_cmp_op(op);
-    print_reg_or_data(command, vm_getbits(command, 55, 1), 15);
-    fprintf(MSG_OUT, ") ");
-  }
-}
-
-static void print_if_version_4(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-
-  if(op) {
-    fprintf(MSG_OUT, "if (");
-    print_g_reg(vm_getbits(command, 51, 4));
-    print_cmp_op(op);
-    print_reg_or_data(command, vm_getbits(command, 55, 1), 31);
-    fprintf(MSG_OUT, ") ");
-  }
-}
-
-static void print_if_version_5(command_t* command) {
-  uint8_t op = vm_getbits(command, 54, 3);
-  int set_immediate = vm_getbits(command, 60, 1);
-  
-  if(op) {
-    if (set_immediate) {
-      fprintf(MSG_OUT, "if (");
-      print_g_reg(vm_getbits(command, 31, 8));
-      print_cmp_op(op);
-      print_reg(vm_getbits(command, 23, 8));
-      fprintf(MSG_OUT, ") ");
-    } else {
-      fprintf(MSG_OUT, "if (");
-      print_g_reg(vm_getbits(command, 39, 8));
-      print_cmp_op(op);
-      print_reg_or_data(command, vm_getbits(command, 55, 1), 31);
-      fprintf(MSG_OUT, ") ");
-    }
-  }
-}
-
-static void print_special_instruction(command_t* command) {
-  uint8_t op = vm_getbits(command, 51, 4);
-  
-  switch(op) {
-    case 0: /*  NOP */
-      fprintf(MSG_OUT, "Nop");
-      break;
-    case 1: /*  Goto line */
-      fprintf(MSG_OUT, "Goto %" PRIu8, vm_getbits(command, 7, 8));
-      break;
-    case 2: /*  Break */
-      fprintf(MSG_OUT, "Break");
-      break;
-    case 3: /*  Parental level */
-      fprintf(MSG_OUT, "SetTmpPML %" PRIu8 ", Goto %" PRIu8, 
-	      vm_getbits(command, 11, 4), vm_getbits(command, 7, 8));
-      break;
-    default:
-      fprintf(MSG_OUT, "WARNING: Unknown special instruction (%i)", 
-	      vm_getbits(command, 51, 4));
-  }
-}
-
-static void print_linksub_instruction(command_t* command) {
-  uint32_t linkop = vm_getbits(command, 7, 8);
-  uint32_t button = vm_getbits(command, 15, 6);
-  
-  if(linkop < sizeof(link_table)/sizeof(link_table[0]))
-    fprintf(MSG_OUT, "%s (button %" PRIu8 ")", link_table[linkop], button);
-  else
-    fprintf(MSG_OUT, "WARNING: Unknown linksub instruction (%i)", linkop);
-}
-
-static void print_link_instruction(command_t* command, int optional) {
-  uint8_t op = vm_getbits(command, 51, 4);
-  
-  if(optional && op)
-    fprintf(MSG_OUT, ", ");
-  
-  switch(op) {
-    case 0:
-      if(!optional)
-      fprintf(MSG_OUT, "WARNING: NOP (link)!");
-      break;
-    case 1:
-      print_linksub_instruction(command);
-      break;
-    case 4:
-      fprintf(MSG_OUT, "LinkPGCN %" PRIu16, vm_getbits(command, 14, 15));
-      break;
-    case 5:
-      fprintf(MSG_OUT, "LinkPTT %" PRIu16 " (button %" PRIu8 ")", 
-	      vm_getbits(command, 9, 10), vm_getbits(command, 15, 6));
-      break;
-    case 6:
-      fprintf(MSG_OUT, "LinkPGN %" PRIu8 " (button %" PRIu8 ")", 
-	      vm_getbits(command, 6, 7), vm_getbits(command, 15, 6));
-      break;
-    case 7:
-      fprintf(MSG_OUT, "LinkCN %" PRIu8 " (button %" PRIu8 ")", 
-	      vm_getbits(command, 7, 8), vm_getbits(command, 15, 6));
-      break;
-    default:
-      fprintf(MSG_OUT, "WARNING: Unknown link instruction");
-  }
-}
-
-static void print_jump_instruction(command_t* command) {
-  switch(vm_getbits(command, 51, 4)) {
-    case 1:
-      fprintf(MSG_OUT, "Exit");
-      break;
-    case 2:
-      fprintf(MSG_OUT, "JumpTT %" PRIu8, vm_getbits(command, 22, 7));
-      break;
-    case 3:
-      fprintf(MSG_OUT, "JumpVTS_TT %" PRIu8, vm_getbits(command, 22, 7));
-      break;
-    case 5:
-      fprintf(MSG_OUT, "JumpVTS_PTT %" PRIu8 ":%" PRIu16, 
-	      vm_getbits(command, 22, 7), vm_getbits(command, 41, 10));
-      break;
-    case 6:
-      switch(vm_getbits(command, 23, 2)) {
-        case 0:
-          fprintf(MSG_OUT, "JumpSS FP");
-          break;
-        case 1:
-          fprintf(MSG_OUT, "JumpSS VMGM (menu %" PRIu8 ")", vm_getbits(command, 19, 4));
-          break;
-        case 2:
-          fprintf(MSG_OUT, "JumpSS VTSM (vts %" PRIu8 ", title %" PRIu8 
-		  ", menu %" PRIu8 ")", vm_getbits(command, 30, 7), vm_getbits(command, 38, 7), vm_getbits(command, 19, 4));
-          break;
-        case 3:
-          fprintf(MSG_OUT, "JumpSS VMGM (pgc %" PRIu8 ")", vm_getbits(command, 46, 15));
-          break;
-        }
-      break;
-    case 8:
-      switch(vm_getbits(command, 23, 2)) {
-        case 0:
-          fprintf(MSG_OUT, "CallSS FP (rsm_cell %" PRIu8 ")",
-              vm_getbits(command, 31, 8));
-          break;
-        case 1:
-          fprintf(MSG_OUT, "CallSS VMGM (menu %" PRIu8 
-		  ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
-          break;
-        case 2:
-          fprintf(MSG_OUT, "CallSS VTSM (menu %" PRIu8 
-		  ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8));
-          break;
-        case 3:
-          fprintf(MSG_OUT, "CallSS VMGM (pgc %" PRIu8 ", rsm_cell %" PRIu8 ")", 
-		  vm_getbits(command, 46, 15), vm_getbits(command, 31, 8));
-          break;
-      }
-      break;
-    default:
-      fprintf(MSG_OUT, "WARNING: Unknown Jump/Call instruction");
-  }
-}
-
-static void print_system_set(command_t* command) {
-  int i;
-/* FIXME: What about SPRM11 ? Karaoke */
-/*        Surely there must be some system set command for that ? */
-  
-  switch(vm_getbits(command, 59, 4)) {
-    case 1: /*  Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */
-      for(i = 1; i <= 3; i++) {
-        if(vm_getbits(command, 47 - (i*8), 1)) {
-          print_system_reg(i);
-          fprintf(MSG_OUT, " = ");
-          print_reg_or_data_2(command, vm_getbits(command, 60, 1), 47 - (i*8) );
-          fprintf(MSG_OUT, " ");
-        }
-      }
-      break;
-    case 2: /*  Set system reg 9 & 10 (Navigation timer, Title PGC number) */
-      print_system_reg(9);
-      fprintf(MSG_OUT, " = ");
-      print_reg_or_data(command, vm_getbits(command, 60, 1), 47);
-      fprintf(MSG_OUT, " ");
-      print_system_reg(10);
-      fprintf(MSG_OUT, " = %" PRIu16, vm_getbits(command, 30, 15)); /*  ?? */
-      break;
-    case 3: /*  Mode: Counter / Register + Set */
-      fprintf(MSG_OUT, "SetMode ");
-      if(vm_getbits(command, 23, 1))
-	fprintf(MSG_OUT, "Counter ");
-      else
-	fprintf(MSG_OUT, "Register ");
-      print_g_reg(vm_getbits(command, 19, 4));
-      print_set_op(0x1); /*  '=' */
-      print_reg_or_data(command, vm_getbits(command, 60, 1), 47);
-      break;
-    case 6: /*  Set system reg 8 (Highlighted button) */
-      print_system_reg(8);
-      if(vm_getbits(command, 60, 1)) /*  immediate */
-        fprintf(MSG_OUT, " = 0x%x (button no %d)", vm_getbits(command, 31, 16), vm_getbits(command, 31, 6));
-      else
-        fprintf(MSG_OUT, " = g[%" PRIu8 "]", vm_getbits(command, 19, 4));
-      break;
-    default:
-      fprintf(MSG_OUT, "WARNING: Unknown system set instruction (%i)", 
-	      vm_getbits(command, 59, 4));
-  }
-}
-
-static void print_set_version_1(command_t* command) {
-  uint8_t set_op = vm_getbits(command, 59, 4);
-  
-  if(set_op) {
-    print_g_reg(vm_getbits(command, 35, 4));
-    print_set_op(set_op);
-    print_reg_or_data(command, vm_getbits(command, 60, 1), 31);
-  } else {
-    fprintf(MSG_OUT, "NOP");
-  }
-}
-
-static void print_set_version_2(command_t* command) {
-  uint8_t set_op = vm_getbits(command, 59, 4);
-  
-  if(set_op) {
-    print_g_reg(vm_getbits(command, 51, 4));
-    print_set_op(set_op);
-    print_reg_or_data(command, vm_getbits(command, 60, 1), 47);
-  } else {
-    fprintf(MSG_OUT, "NOP");
-  }
-}
-
-static void print_set_version_3(command_t* command) {
-  uint8_t set_op = vm_getbits(command, 59, 4);
-  
-  if(set_op) {
-    print_g_reg(vm_getbits(command, 51, 4));
-    print_set_op(set_op);
-    print_reg_or_data_3(command, vm_getbits(command, 60, 1), 47);
-  } else {
-    fprintf(MSG_OUT, "NOP");
-  }
-}
-
-
-void vm_print_mnemonic(vm_cmd_t *vm_command)  {
-  command_t command;
-  command.instruction =( (uint64_t) vm_command->bytes[0] << 56 ) |
-        ( (uint64_t) vm_command->bytes[1] << 48 ) |
-        ( (uint64_t) vm_command->bytes[2] << 40 ) |
-        ( (uint64_t) vm_command->bytes[3] << 32 ) |
-        ( (uint64_t) vm_command->bytes[4] << 24 ) |
-        ( (uint64_t) vm_command->bytes[5] << 16 ) |
-        ( (uint64_t) vm_command->bytes[6] <<  8 ) |
-          (uint64_t) vm_command->bytes[7] ;
-  command.examined = 0; 
-
-  switch(vm_getbits(&command,63,3)) { /* three first bits */
-    case 0: /*  Special instructions */
-      print_if_version_1(&command);
-      print_special_instruction(&command);
-      break;
-    case 1: /*  Jump/Call or Link instructions */
-      if(vm_getbits(&command,60,1)) {
-        print_if_version_2(&command);
-        print_jump_instruction(&command);
-      } else {
-        print_if_version_1(&command);
-        print_link_instruction(&command, 0); /*  must be pressent */
-      }
-      break;
-    case 2: /*  Set System Parameters instructions */
-      print_if_version_2(&command);
-      print_system_set(&command);
-      print_link_instruction(&command, 1); /*  either 'if' or 'link' */
-      break;
-    case 3: /*  Set General Parameters instructions */
-      print_if_version_3(&command);
-      print_set_version_1(&command);
-      print_link_instruction(&command, 1); /*  either 'if' or 'link' */
-      break;
-    case 4: /*  Set, Compare -> LinkSub instructions */
-      print_set_version_2(&command);
-      fprintf(MSG_OUT, ", ");
-      print_if_version_4(&command);
-      print_linksub_instruction(&command);
-      break;
-    case 5: /*  Compare -> (Set and LinkSub) instructions */
-      print_if_version_5(&command);
-      fprintf(MSG_OUT, "{ ");
-      print_set_version_3(&command);
-      fprintf(MSG_OUT, ", ");
-      print_linksub_instruction(&command);
-      fprintf(MSG_OUT, " }");
-      break;
-    case 6: /*  Compare -> Set, always LinkSub instructions */
-      print_if_version_5(&command);
-      fprintf(MSG_OUT, "{ ");
-      print_set_version_3(&command);
-      fprintf(MSG_OUT, " } ");
-      print_linksub_instruction(&command);
-      break;
-    default:
-      fprintf(MSG_OUT, "WARNING: Unknown instruction type (%i)", vm_getbits(&command, 63, 3));
-  }
-  /*  Check if there still are bits set that were not examined */
-  
-  if(command.instruction & ~ command.examined) {
-    fprintf(MSG_OUT, " libdvdnav: vmcmd.c: [WARNING, unknown bits:");
-    fprintf(MSG_OUT, " %08"PRIx64, (command.instruction & ~ command.examined) );
-    fprintf(MSG_OUT, "]");
-  }
-}
-
-void vm_print_cmd(int row, vm_cmd_t *vm_command) {
-  int i;
-
-  fprintf(MSG_OUT, "(%03d) ", row + 1);
-  for(i = 0; i < 8; i++)
-    fprintf(MSG_OUT, "%02x ", vm_command->bytes[i]);
-  fprintf(MSG_OUT, "| ");
-
-  vm_print_mnemonic(vm_command);
-  fprintf(MSG_OUT, "\n");
-}
-
--- a/vm/vmcmd.h	Sun Jun 01 08:39:07 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
- * 
- * This file is part of libdvdnav, a DVD navigation library. It is modified
- * from a file originally part of the Ogle DVD player.
- * 
- * libdvdnav is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * libdvdnav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
- *
- * $Id$
- *
- */
-
-#ifndef VMCMD_H_INCLUDED
-#define VMCMD_H_INCLUDED
-
-void vm_print_mnemonic(vm_cmd_t *command);
-void vm_print_cmd(int row, vm_cmd_t *command);
-
-#endif /* VMCMD_H_INCLUDED */