⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	return do_nothing;      }      break;    case LinkPGCN:      if(get_PGC(link_values.data1))	assert(0);      link_values = play_PGC();      break;    case LinkPTTN:      assert(state.domain == VTS_DOMAIN);      if(get_VTS_PTT(state.vtsN, state.VTS_TTN_REG, link_values.data1) == -1)	assert(0);      // not play_PGC(); Fixes Men In Black delux set / sepcial edition       link_values = play_PG();      break;    case LinkPGN:      /* Update any other state, PTTN perhaps? */      state.pgN = link_values.data1;      link_values = play_PG();      break;    case LinkCN:      /* Update any other state, pgN, PTTN perhaps? */      state.cellN = link_values.data1;      link_values = play_Cell();      break;          case Exit:      exit(1); // What should we do here??          case JumpTT:      assert(state.domain == VMGM_DOMAIN || state.domain == FP_DOMAIN);      if(get_TT(link_values.data1) == -1)	assert(0);      link_values = play_PGC();      break;    case JumpVTS_TT:      assert(state.domain == VTSM_DOMAIN || state.domain == VTS_DOMAIN); //??      if(get_VTS_TT(state.vtsN, link_values.data1) == -1)	assert(0);      link_values = play_PGC();      break;    case JumpVTS_PTT:      assert(state.domain == VTSM_DOMAIN || state.domain == VTS_DOMAIN); //??      if(get_VTS_PTT(state.vtsN, link_values.data1, link_values.data2) == -1)	assert(0);      link_values = play_PGC();      break;          case JumpSS_FP:      assert(state.domain == VMGM_DOMAIN || state.domain == VTSM_DOMAIN); //??      get_FP_PGC();      link_values = play_PGC();      break;    case JumpSS_VMGM_MENU:      assert(state.domain == VMGM_DOMAIN || 	     state.domain == VTSM_DOMAIN || 	     state.domain == FP_DOMAIN); //??      state.domain = VMGM_DOMAIN;      if(get_MENU(link_values.data1) == -1)	assert(0);      link_values = play_PGC();      break;    case JumpSS_VTSM:      if(link_values.data1 == 0) {	// 'The Fifth Element' region 2 has data1 == 0.	assert(state.domain == VTSM_DOMAIN);      } else if(link_values.data1 == state.vtsN) {	// "Captain Scarlet & the Mysterons" has data1 == state.vtsN i VTSM	assert(state.domain == VTSM_DOMAIN || 	       state.domain == VMGM_DOMAIN || 	       state.domain == FP_DOMAIN); //??	state.domain = VTSM_DOMAIN;      } else {	// Normal case.	assert(state.domain == VMGM_DOMAIN || 	       state.domain == FP_DOMAIN); //??	state.domain = VTSM_DOMAIN;	ifoOpenNewVTSI(dvd, link_values.data1);  // Also sets state.vtsN      }      // I don't really know what title is supposed to be used for.      // Alien or Aliens has this != 1, I think.      //assert(link_values.data2 == 1);      assert(link_values.data2 != 0);      state.VTS_TTN_REG = link_values.data2;      if(get_MENU(link_values.data3) == -1)	assert(0);      link_values = play_PGC();      break;    case JumpSS_VMGM_PGC:      assert(state.domain == VMGM_DOMAIN ||	     state.domain == VTSM_DOMAIN ||	     state.domain == FP_DOMAIN); //??      state.domain = VMGM_DOMAIN;      if(get_PGC(link_values.data1) == -1)	assert(0);      link_values = play_PGC();      break;          case CallSS_FP:      assert(state.domain == VTS_DOMAIN); //??         // Must be called before domain is changed      saveRSMinfo(link_values.data1, /* We dont have block info */ 0);      get_FP_PGC();      link_values = play_PGC();      break;    case CallSS_VMGM_MENU:      assert(state.domain == VTS_DOMAIN); //??         // Must be called before domain is changed      saveRSMinfo(link_values.data2, /* We dont have block info */ 0);            state.domain = VMGM_DOMAIN;      if(get_MENU(link_values.data1) == -1)	assert(0);      link_values = play_PGC();      break;    case CallSS_VTSM:      assert(state.domain == VTS_DOMAIN); //??         // Must be called before domain is changed      saveRSMinfo(link_values.data2, /* We dont have block info */ 0);      state.domain = VTSM_DOMAIN;      if(get_MENU(link_values.data1) == -1)	assert(0);      link_values = play_PGC();      break;    case CallSS_VMGM_PGC:      assert(state.domain == VTS_DOMAIN); //??         // Must be called before domain is changed      saveRSMinfo(link_values.data2, /* We dont have block info */ 0);      state.domain = VMGM_DOMAIN;      if(get_PGC(link_values.data1) == -1)	assert(0);      link_values = play_PGC();      break;    case PlayThis:      /* Should never happen. */      break;    }      }  return link_values;}static int get_TT(int tt){    assert(tt <= vmgi->tt_srpt->nr_of_srpts);    state.TTN_REG = tt;    return get_VTS_TT(vmgi->tt_srpt->title[tt - 1].title_set_nr,		    vmgi->tt_srpt->title[tt - 1].vts_ttn);}static int get_TT_PTT(int tt, int ptt){    assert(tt <= vmgi->tt_srpt->nr_of_srpts);    state.TTN_REG = tt;    // Add this check for use call of this code.  //assert(part <= vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts);    return get_VTS_PTT(vmgi->tt_srpt->title[tt - 1].title_set_nr,		     vmgi->tt_srpt->title[tt - 1].vts_ttn, 		     ptt);}static int get_VTS_TT(int vtsN, int vts_ttn){  int pgcN;    state.domain = VTS_DOMAIN;  if(vtsN != state.vtsN)    ifoOpenNewVTSI(dvd, vtsN); // Also sets state.vtsN    pgcN = get_ID(vts_ttn); // This might return -1  assert(pgcN != -1);  //assert(pgcN == vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[0].pgcn); ??    //state.TTN_REG = ?? Must search tt_srpt for a matching entry...    state.VTS_TTN_REG = vts_ttn;  /* Any other registers? */    return get_PGC(pgcN);}static int get_VTS_PTT(int vtsN, int /* is this really */ vts_ttn, int part){  int pgcN, pgN, res;    state.domain = VTS_DOMAIN;  if(vtsN != state.vtsN)    ifoOpenNewVTSI(dvd, vtsN); // Also sets state.vtsN    assert(vts_ttn <= vtsi->vts_ptt_srpt->nr_of_srpts);  assert(part <= vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts);    pgcN = vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn;  pgN = vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn;    //assert(pgcN == get_ID(vts_ttn); ??    //state.TTN_REG = ?? Must search tt_srpt for a matchhing entry...  state.VTS_TTN_REG = vts_ttn;  /* Any other registers? */    res = get_PGC(pgcN); // This clobbers state.pgN (sets it to 1).  state.pgN = pgN;  return res;}static int get_FP_PGC(void){    state.domain = FP_DOMAIN;    /* 'DVD Authoring & Production' claim that first_play_pgc is optional. */  if(vmgi->first_play_pgc) {    state.pgc = vmgi->first_play_pgc;    state.pgN = 1;  } else {    if(get_TT(1) == -1)      assert(0);  }  return 0;}static int get_MENU(int menu){  assert(state.domain == VMGM_DOMAIN || state.domain == VTSM_DOMAIN);  return get_PGC(get_ID(menu));}/*** * Search PGCIT for a PGC that has entry_id == id and return the PGCN of that. */static int get_ID(int id){  int pgcN, i;  pgcit_t *pgcit;    /* Relies on state to get the correct pgcit. */  pgcit = get_PGCIT();  assert(pgcit != NULL);    /* Get menu/title */  for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {    int entry_id = pgcit->pgci_srp[i].entry_id & 0x7F;    int entryPGC = pgcit->pgci_srp[i].entry_id & 0x80;    // Only 'enter' the one that has the entry flag set and is a match.    if(entryPGC && (entry_id == id)) {      pgcN = i + 1;      return pgcN;    }  }  DNOTE("** No such id/menu (%d) entry PGC\n", id);  return -1; // error}/*** * Update the state so that pgcN is the current PGC.  Sets PGN to 1 and * if we are in VTS_DOMAIN (really TT_DOM) updates the TT_PGC_REG. */static int get_PGC(int pgcN){  pgcit_t *pgcit;    pgcit = get_PGCIT();    assert(pgcit != NULL); // ?? Make this return -1 instead  if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp)    return -1; // error    //state.pgcN = pgcN;  state.pgc = pgcit->pgci_srp[pgcN - 1].pgc;  state.pgN = 1;    if(state.domain == VTS_DOMAIN)    state.TT_PGCN_REG = pgcN;    return 0;}static int get_PGCN(){  pgcit_t *pgcit;  int pgcN = 1;    pgcit = get_PGCIT();    assert(pgcit != NULL);    while(pgcN <= pgcit->nr_of_pgci_srp) {    if(pgcit->pgci_srp[pgcN - 1].pgc == state.pgc)      return pgcN;    pgcN++;  }    return -1; // error}//scan the cell table?static int get_cellN_for_vobu(uint32_t vobu_addr){  unsigned int i, j, entries;  c_adt_t *c_adt = vtsi->vts_c_adt;    //nr_of_vobs = c_adt->nr_of_vobs;  entries = (c_adt->last_byte + 1 - C_ADT_SIZE)/sizeof(c_adt_t);    fprintf(stderr, "VOBU addr: 0x%x\n", vobu_addr);  for(i = 0; i < entries; i++) {    if(c_adt->cell_adr_table[i].start_sector <= vobu_addr &&        vobu_addr <= c_adt->cell_adr_table[i].last_sector) {      uint16_t vob_id = c_adt->cell_adr_table[i].vob_id;      uint8_t cell_id = c_adt->cell_adr_table[i].cell_id;      fprintf(stderr, "start_sector: 0x%x\n",	      c_adt->cell_adr_table[i].start_sector);      fprintf(stderr, "last_sector: 0x%x\n",	      c_adt->cell_adr_table[i].last_sector);      fprintf(stderr, "VOBID: %d CELLID: %d\n", vob_id, cell_id);      for(j = 0; j < state.pgc->nr_of_cells; j++) {	if(state.pgc->cell_position[j].vob_id_nr == vob_id &&	   state.pgc->cell_position[j].cell_nr == cell_id) {	  fprintf(stderr, "VOBID: %d CELLID: %d, CellN: %d\n",		  vob_id, cell_id, j + 1);	  return j + 1; // cellN is 1 based	}      }      // Something crazy has happened!!      // The VOB / CELL id wasn't part of this PGC!      assert(0 & 13);    }  }  // Something crazy has happened!!  // Unable to find the VOB / CELL id for the VOBU!  assert(0 & 14);  return 1;}static int get_video_aspect(void){  int aspect = 0;    if(state.domain == VTS_DOMAIN) {    aspect = vtsi->vtsi_mat->vts_video_attr.display_aspect_ratio;    } else if(state.domain == VTSM_DOMAIN) {    aspect = vtsi->vtsi_mat->vtsm_video_attr.display_aspect_ratio;  } else if(state.domain == VMGM_DOMAIN) {    aspect = vmgi->vmgi_mat->vmgm_video_attr.display_aspect_ratio;  }  assert(aspect == 0 || aspect == 3);  state.registers.SPRM[14] &= ~(0x3 << 10);  state.registers.SPRM[14] |= aspect << 10;    return aspect;}static void ifoOpenNewVTSI(dvd_reader_t *dvd, int vtsN) {  if(state.vtsN == vtsN) {    return; // We alread have it  }    if(vtsi != NULL)    ifoClose(vtsi);    vtsi = ifoOpenVTSI(dvd, vtsN);  if(vtsi == NULL) {    FATAL("%s", "ifoOpenVTSI failed\n");    exit(1);  }  if(!ifoRead_VTS_PTT_SRPT(vtsi)) {    FATAL("%s", "ifoRead_VTS_PTT_SRPT failed\n");    exit(1);  }  if(!ifoRead_PGCIT(vtsi)) {    FATAL("%s", "ifoRead_PGCIT failed\n");    exit(1);  }  if(!ifoRead_PGCI_UT(vtsi)) {    FATAL("%s", "ifoRead_PGCI_UT failed\n");    exit(1);  }  if(!ifoRead_VTS_TMAPT(vtsi)) {    FATAL("%s", "ifoRead_VTS_TMAPT failed\n");    exit(1);  }  if(!ifoRead_TITLE_C_ADT(vtsi)) {    FATAL("%s", "ifoRead_TITLE_C_ADT failed\n");    exit(1);  }      state.vtsN = vtsN;}static pgcit_t* get_MENU_PGCIT(ifo_handle_t *h, uint16_t lang){  int i;    if(h == NULL || h->pgci_ut == NULL) {    WARNING("%s", "*** 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) {    NOTE("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));    i = 0; // error?  }    return h->pgci_ut->lu[i].pgcit;}/* Uses state to decide what to return */static pgcit_t* get_PGCIT(void) {  pgcit_t *pgcit;    if(state.domain == VTS_DOMAIN) {    pgcit = vtsi->vts_pgcit;  } else if(state.domain == VTSM_DOMAIN) {    pgcit = get_MENU_PGCIT(vtsi, state.registers.SPRM[0]);  } else if(state.domain == VMGM_DOMAIN) {    pgcit = get_MENU_PGCIT(vmgi, state.registers.SPRM[0]);  } else {    pgcit = NULL;    /* Should never hapen */  }    return pgcit;}int vm_get_udf_volids(char *volid, unsigned int volidlen,		      unsigned char *volsetid, unsigned int volsetidlen){  return DVDUDFVolumeInfo(dvd, volid, volidlen, volsetid, volsetidlen);}int vm_get_iso_volids(char *volid, unsigned int volidlen,		      unsigned char *volsetid, unsigned int volsetidlen){  return DVDISOVolumeInfo(dvd, volid, volidlen, volsetid, volsetidlen);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -