/***************************************************************************** * tools.c: functions called from other files. ***************************************************************************** * Copyright (C) 2002 VideoLAN * $Id: tools.c,v 1.6 2003/01/29 22:09:46 sam Exp $ * * Authors: Stéphane Borel * * This program 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. * * This program 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, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ #include "config.h" #include #include #include #ifdef HAVE_UNISTD_H # include #endif #include #include "common.h" #include #include #include "dvdplay/dvdplay.h" #include "dvdplay/info.h" #include "command.h" #include "vmg.h" /* * get functions: they return some data */ /***************************************************************************** * GetMenuPGCIT: *****************************************************************************/ static pgcit_t* GetMenuPGCIT( const dvdplay_ptr dvdplay, ifo_handle_t * p_ifo, uint16_t i_lang ) { int i; if( p_ifo == NULL || p_ifo->pgci_ut == NULL ) { _dvdplay_err( dvdplay, "pgci_ut handle is NULL" ); return NULL; // error? } i = 0; while( i < p_ifo->pgci_ut->nr_of_lus && p_ifo->pgci_ut->lu[i].lang_code != i_lang ) { i++; } if( i == p_ifo->pgci_ut->nr_of_lus ) { _dvdplay_warn( dvdplay, "language '%c%c' not found, " "using '%c%c' instead", (char)(i_lang >> 8), (char)(i_lang & 0xff), (char)(p_ifo->pgci_ut->lu[0].lang_code >> 8), (char)(p_ifo->pgci_ut->lu[0].lang_code & 0xff) ); i = 0; // error? } return p_ifo->pgci_ut->lu[i].pgcit; } /***************************************************************************** * _GetPGCIT: ***************************************************************************** * Uses state to decide what to return *****************************************************************************/ pgcit_t* _GetPGCIT( dvdplay_ptr dvdplay ) { pgcit_t * p_pgcit; switch( dvdplay->state.domain ) { case VTS_DOMAIN: p_pgcit = dvdplay->p_vtsi->vts_pgcit; break; case VTSM_DOMAIN: p_pgcit = GetMenuPGCIT( dvdplay, dvdplay->p_vtsi, dvdplay->registers.SPRM[0] ); break; case VMGM_DOMAIN: p_pgcit = GetMenuPGCIT( dvdplay, dvdplay->p_vmgi, dvdplay->registers.SPRM[0] ); break; default: _dvdplay_err( dvdplay, "invalid domain" ); p_pgcit = NULL; /* Should never hapen */ break; } return p_pgcit; } /***************************************************************************** * _GetPGCNbyID: *****************************************************************************/ int _GetPGCNbyID( dvdplay_ptr dvdplay, int i_id ) { pgcit_t * p_pgcit; int i_pgcN, i; /* Relies on state to get the correct pgcit. */ p_pgcit = _GetPGCIT( dvdplay ); if( p_pgcit == NULL ) { _dvdplay_err( dvdplay, "cannot get PGCIT" ); return -1; } /* Get menu/title */ for( i = 0 ; i < p_pgcit->nr_of_pgci_srp ; i++ ) { if( ( p_pgcit->pgci_srp[i].entry_id & 0x7f ) == i_id ) { assert( ( p_pgcit->pgci_srp[i].entry_id & 0x80 ) == 0x80 ); i_pgcN = i + 1; return i_pgcN; } } _dvdplay_err( dvdplay, "no such id/menu (%d) entry PGC", i_id ); return -1; // error } /***************************************************************************** * _GetCurrentPGCN: *****************************************************************************/ int _GetCurrentPGCN( dvdplay_ptr dvdplay ) { pgcit_t * p_pgcit; int i_pgcN = 1; p_pgcit = _GetPGCIT( dvdplay ); if( p_pgcit == NULL ) { _dvdplay_err( dvdplay, "cannot get PGCIT" ); return -1; } while( i_pgcN <= p_pgcit->nr_of_pgci_srp ) { if( p_pgcit->pgci_srp[i_pgcN - 1].pgc == dvdplay->state.p_pgc ) { return i_pgcN; } i_pgcN++; } return -1; // error } /***************************************************************************** * _GetVideoAspect: *****************************************************************************/ int _GetVideoAspect( dvdplay_ptr dvdplay ) { video_attr_t * p_video_attr; int i_aspect = 0; p_video_attr = dvdplay_video_attr( dvdplay ); i_aspect = p_video_attr->display_aspect_ratio; dvdplay->registers.SPRM[14] &= ~(0x3 << 10); dvdplay->registers.SPRM[14] |= i_aspect << 10; return i_aspect; } /* * Maintain state coherence. */ /***************************************************************************** * _UpdatePGN: Figure out the correct pgN from the cell and update state. *****************************************************************************/ int _UpdatePGN( dvdplay_ptr dvdplay ) { int i_new_pgN = 0; while( i_new_pgN < dvdplay->state.p_pgc->nr_of_programs && dvdplay->state.i_cellN >= dvdplay->state.p_pgc->program_map[i_new_pgN] ) { i_new_pgN++; } if( ( i_new_pgN == dvdplay->state.p_pgc->nr_of_programs ) &&( dvdplay->state.i_cellN > dvdplay->state.p_pgc->nr_of_cells ) ) { /* We are at the last program, past the last cell */ return 1; } dvdplay->state.i_pgN = i_new_pgN; if( dvdplay->state.domain == VTS_DOMAIN ) { playback_type_t * pb_ty; if( dvdplay->TTN_REG > dvdplay->p_vmgi->tt_srpt->nr_of_srpts ) { return 0; // ?? } pb_ty = &dvdplay->p_vmgi->tt_srpt->title[dvdplay->TTN_REG - 1].pb_ty; if( pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0 ) { #if 0 /* TTN_REG can't be trusted to have a correct value here... */ vts_ptt_srpt_t *ptt_srpt = vtsi->vts_ptt_srpt; assert(state.VTS_TTN_REG <= ptt_srpt->nr_of_srpts); assert(get_PGCN() == ptt_srpt->title[state.VTS_TTN_REG - 1].ptt[0].pgcn); assert(1 == ptt_srpt->title[state.VTS_TTN_REG - 1].ptt[0].pgn); #endif dvdplay->PTTN_REG = dvdplay->state.i_pgN; } } dvdplay->pf_callback( dvdplay->p_args, NEW_PG ); return 0; }