diff -Naur MPlayer-0.90.orig/input/input.c MPlayer-0.90/input/input.c
--- MPlayer-0.90.orig/input/input.c	2003-06-17 22:49:54.000000000 +0200
+++ MPlayer-0.90/input/input.c	2003-06-22 16:48:40.000000000 +0200
@@ -81,6 +81,15 @@
   { MP_CMD_TV_SET_CHANNEL, "tv_set_channel", 1, { { MP_CMD_ARG_STRING, {0}}, {-1,{0}}  }},
   { MP_CMD_TV_LAST_CHANNEL, "tv_last_channel", 0, { {-1,{0}} } },
 #endif
+#ifdef HAVE_VCD
+  { MP_CMD_VCD_PLAY, "play_vcd", 0, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
+#endif
+#ifdef USE_DVDREAD
+  { MP_CMD_DVD_PLAY, "play_dvd", 0, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
+#endif
+#ifdef HAVE_CDDA
+  { MP_CMD_CDDA_PLAY, "play_cdda", 0, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
+#endif
   { MP_CMD_VO_FULLSCREEN, "vo_fullscreen", 0, { {-1,{0}} } },
   { MP_CMD_SCREENSHOT, "screenshot", 0, { {-1,{0}} } },
   { MP_CMD_PANSCAN, "panscan",1,  { {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
diff -Naur MPlayer-0.90.orig/input/input.h MPlayer-0.90/input/input.h
--- MPlayer-0.90.orig/input/input.h	2003-06-17 22:49:54.000000000 +0200
+++ MPlayer-0.90/input/input.h	2003-06-22 16:48:40.000000000 +0200
@@ -42,6 +42,9 @@
 #endif
 #define MP_CMD_SUB_ALIGNMENT 39
 #define MP_CMD_TV_LAST_CHANNEL 40
+#define MP_CMD_VCD_PLAY 41
+#define MP_CMD_DVD_PLAY 42
+#define MP_CMD_CDDA_PLAY 43
 
 #define MP_CMD_GUI_EVENTS       5000
 #define MP_CMD_GUI_LOADFILE     5001
diff -Naur MPlayer-0.90.orig/libmpdemux/cdda.c MPlayer-0.90/libmpdemux/cdda.c
--- MPlayer-0.90.orig/libmpdemux/cdda.c	2003-06-17 22:49:54.000000000 +0200
+++ MPlayer-0.90/libmpdemux/cdda.c	2003-06-22 16:48:40.000000000 +0200
@@ -170,6 +170,37 @@
 static void cdparanoia_callback(long inpos, int function) {
 }
 
+int get_cdda_tracks_num(char* dev) {
+  cdrom_drive* cdd = NULL;
+  int nb_tracks;
+
+  if(generic_dev)
+    cdd = cdda_identify_scsi(generic_dev,dev,0,NULL);
+  else
+#if defined(__NetBSD__)
+    cdd = cdda_identify_scsi(dev,dev,0,NULL);
+#else
+    cdd = cdda_identify(dev,0,NULL);
+#endif
+
+  if(!cdd) {
+    mp_msg(MSGT_OPEN,MSGL_ERR,"Can't open cdda device\n");
+    return -1;
+  }
+
+  if(cdda_open(cdd)) {
+    mp_msg(MSGT_OPEN,MSGL_ERR,"Can't open disc\n");
+    cdda_close(cdd);
+    return NULL;
+  }
+
+  cdda_verbose_set(cdd, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT);
+
+  nb_tracks = cdda_tracks(cdd);
+  cdda_close(cdd);
+  return nb_tracks;
+}
+
 int read_cdda(stream_t* s) {
   cdda_priv* p = (cdda_priv*)s->priv;
   cd_track_t *cd_track;
diff -Naur MPlayer-0.90.orig/libmpdemux/open.c MPlayer-0.90/libmpdemux/open.c
--- MPlayer-0.90.orig/libmpdemux/open.c	2003-06-17 22:49:54.000000000 +0200
+++ MPlayer-0.90/libmpdemux/open.c	2003-06-22 16:48:40.000000000 +0200
@@ -294,7 +294,6 @@
 	    return NULL;
 	}
     }
-    --dvd_chapter; // remap 1.. -> 0..
     /* XXX No need to remap dvd_last_chapter */
     /**
      * Make sure the angle number is valid for this title.
@@ -448,8 +447,8 @@
      * chapter number.
      */
     ttn = tt_srpt->title[ dvd_title ].vts_ttn; // local
-    pgc_id = vts_file->vts_ptt_srpt->title[ttn-1].ptt[dvd_chapter].pgcn; // local
-    pgn    = vts_file->vts_ptt_srpt->title[ttn-1].ptt[dvd_chapter].pgn;  // local
+    pgc_id = vts_file->vts_ptt_srpt->title[ttn-1].ptt[dvd_chapter-1].pgcn; // local
+    pgn    = vts_file->vts_ptt_srpt->title[ttn-1].ptt[dvd_chapter-1].pgn;  // local
     d->cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;
     d->cur_cell = d->cur_pgc->program_map[pgn-1] - 1; // start playback here
     d->packs_left=-1;      // for Navi stuff
diff -Naur MPlayer-0.90.orig/mplayer.c MPlayer-0.90/mplayer.c
--- MPlayer-0.90.orig/mplayer.c	2003-06-17 22:49:54.000000000 +0200
+++ MPlayer-0.90/mplayer.c	2003-06-22 16:48:40.000000000 +0200
@@ -2336,6 +2336,110 @@
     case MP_CMD_QUIT : {
       exit_player_with_rc(MSGTR_Exit_quit, 0);
     }
+    case MP_CMD_HALT : {
+      exit_player_with_rc(MSGTR_Exit_quit, 166);
+    }
+#ifdef HAVE_VCD
+    case MP_CMD_VCD_PLAY : {
+      char buf[10];
+      play_tree_t *vcd, *tracks;
+      stream_t *s;
+      int i;
+
+      if ((s = open_stream (NULL, 1, NULL)) == NULL)
+        break;
+
+      tracks = play_tree_new();
+      play_tree_add_file(tracks, "vcd://1");
+
+      for (i=2; i<100; i++)
+        {
+          if (vcd_seek_to_track (s->fd, i) < 0)
+            break;
+          vcd = play_tree_new();
+          sprintf(buf, "vcd://%d", i);
+          play_tree_add_file(vcd, buf);
+          play_tree_append_entry(tracks, vcd);
+        }
+      free_stream (s);
+
+      if (cmd->nargs==1 && !strcmp(cmd->args[0].v.s, "hide_menu"))
+        mp_input_queue_cmd(mp_input_parse_cmd("menu hide"));
+
+      while(play_tree_iter_up_step(playtree_iter, 0, 1) != PLAY_TREE_ITER_END);
+      play_tree_free_list(playtree->child, 1);
+      play_tree_set_child(playtree, tracks);
+      play_tree_iter_step(playtree_iter, 0, 0);
+      eof = PT_NEXT_SRC;
+    } break;
+#endif
+#ifdef USE_DVDREAD
+    case MP_CMD_DVD_PLAY : {
+      char buf[10];
+      play_tree_t *dvd, *tracks;
+      stream_t *s;
+      int nb_tracks, i; 
+
+      dvd_title = 1;
+      if ((s = open_stream(NULL, 0, NULL)) == NULL)
+        break;
+
+      tracks = play_tree_new();
+      play_tree_add_file(tracks, "dvd://1");
+
+      nb_tracks = ((dvd_priv_t *) s->priv)->vmg_file->tt_srpt->nr_of_srpts;
+      for (i=2; i<nb_tracks; i++)
+        {
+          dvd = play_tree_new();
+          sprintf(buf, "dvd://%d", i);
+          play_tree_add_file(dvd, buf);
+          play_tree_append_entry(tracks, dvd);
+        }
+      free_stream (s);
+
+      if (cmd->nargs==1 && !strcmp(cmd->args[0].v.s, "hide_menu"))
+        mp_input_queue_cmd(mp_input_parse_cmd("menu hide"));
+
+      while(play_tree_iter_up_step(playtree_iter, 0, 1) != PLAY_TREE_ITER_END);
+      play_tree_free_list(playtree->child, 1);
+      play_tree_set_child(playtree, tracks);
+      play_tree_iter_step(playtree_iter, 0, 0);
+      eof = PT_NEXT_SRC;
+    } break;
+#endif
+#ifdef HAVE_CDDA
+    case MP_CMD_CDDA_PLAY : {
+      int get_cdda_tracks_num(char* dev);
+      char buf[11];
+      play_tree_t *cdda, *tracks;
+      int nb_tracks, i; 
+
+      nb_tracks = get_cdda_tracks_num (cdrom_device ? cdrom_device : DEFAULT_CDROM_DEVICE);
+      if (nb_tracks <= 0)
+        break;
+
+      tracks = play_tree_new();
+      play_tree_add_file(tracks, "cdda://1");
+
+      for (i=2; i<=nb_tracks; i++)
+        {
+          cdda = play_tree_new();
+          sprintf(buf, "cdda://%d", i);
+          play_tree_add_file(cdda, buf);
+          play_tree_append_entry(tracks, cdda);
+        }
+
+      if (cmd->nargs==1 && !strcmp(cmd->args[0].v.s, "hide_menu"))
+        mp_input_queue_cmd(mp_input_parse_cmd("menu hide"));
+
+      while(play_tree_iter_up_step(playtree_iter, 0, 1) != PLAY_TREE_ITER_END);
+      play_tree_free_list(playtree->child, 1);
+      play_tree_set_child(playtree, tracks);
+      play_tree_iter_step(playtree_iter, 0, 0);
+      eof = PT_NEXT_SRC;
+    } break;
+#endif
+
     case MP_CMD_GRAB_FRAMES : {
       grab_frames=2;
     } break;
