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

📄 decoder.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Ogle - A video player * Copyright (C) 2000, 2001 Martin Norb鋍k, H錵an Hjort * * 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-1307  USA */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <inttypes.h>#include <dvdread/ifo_types.h> // vm_cmd_t#include "vmcmd.h"#include "decoder.h"#ifndef booltypedef int bool;#endiftypedef struct{  uint8_t bits[8];  uint8_t examined[8];} cmd_t;// Fix theses two.. pass as parameters instead.static cmd_t cmd;static registers_t *state;/* Get count bits of command from byte and bit position. */static uint32_t bits(int byte, int bit, int count){  uint32_t val = 0;  int bit_mask;    while(count--) {    if(bit > 7) {      bit = 0;      byte++;    }    bit_mask = 0x01 << (7 - bit);    val <<= 1;    if(cmd.bits[byte] & bit_mask)      val |= 1;    cmd.examined[byte] |= bit_mask;    bit++;  }  return val;}/* 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(uint8_t reg){  if(reg & 0x80) {    // assert(reg & 0x7f < 24);    return state->SPRM[reg & 0x1f]; // FIXME max 24 not 32  } else {    // assert(reg < 16);    return state->GPRM[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(int imm, int byte){  if(imm) { // immediate    return bits(byte, 0, 16);  } else {    return eval_reg(bits(byte + 1, 0, 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 */uint16_t eval_reg_or_data_2(int imm, int byte){  if(imm) /* immediate */    return bits(byte, 1, 7);  else    return state->GPRM[bits(byte, 4, 4)];}/* Compare data using operation, return result from comparison.    Helper function for the different if functions. */static bool 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(stderr,"eval_compare: Invalid comparison code\n");  return 0;}/* Evaluate if version 1. * PPP0**** 0CCC**** ******** AAAAAAAA ******** BBBBBBBB ******** ********  * PPP0**** 1CCC**** ******** AAAAAAAA DDDDDDDD DDDDDDDD ******** ******** * where PPP is 000, 001 or 101, 110 * "if (r[A] `C` r[B]) then .." resp "if (r[A] `C` D) then .." */static bool eval_if_version_1(void){  uint8_t op = bits(1, 1, 3);  if(op) {    return eval_compare(op, eval_reg(bits(3, 0, 8)),                             eval_reg_or_data(bits(1, 0, 1), 4));  }  return 1;}/* Evaluate if version 2. * PPPQ**** 0CCC**** ******** ******** ******** ******** AAAAAAAA BBBBBBBB * where PPP is 001 & Q=1 or PPP is 010 & Q=* * "if(r[A] `C` r[B]) then .." */static bool eval_if_version_2(void){  uint8_t op = bits(1, 1, 3);  if(op) {    return eval_compare(op, eval_reg(bits(6, 0, 8)), eval_reg(bits(7, 0, 8)));  }  return 1;}/* Evaluate if version 3. * PPP***** 0CCC**** AAAAAAAA ******** ******** ******** ******** BBBBBBBB * PPP***** 1CCC**** AAAAAAAA ******** ******** ******** DDDDDDDD DDDDDDDD * where PPP is 011 * "if (r[A] `C` r[B]) then .." resp. "if (r[A] `C` D) then .." */static bool eval_if_version_3(void){  uint8_t op = bits(1, 1, 3);  if(op) {    return eval_compare(op, eval_reg(bits(2, 0, 8)),                             eval_reg_or_data(bits(1, 0, 1), 6));  }  return 1;}/* Evaluate if version 4. * PPP***** 0CCCAAAA ******** ******** ******** BBBBBBBB ******** ******** * PPP***** 1CCCAAAA ******** ******** DDDDDDDD DDDDDDDD ******** ******** * where PPP is 100 * "if (g[A] `C` r[B]) then .." resp "if (g[A] `C` D) then .." */static bool eval_if_version_4(void){  uint8_t op = bits(1, 1, 3);  if(op) {    return eval_compare(op, eval_reg(bits(1, 4, 4)),                             eval_reg_or_data(bits(1, 0, 1), 4));  }  return 1;}/* Evaluate if version 5. * PPP1**** 0CCC**** ******** ******** AAAAAAAA BBBBBBBB ******** ******** * where PPP is 101, 110 * "if (g[A] `C` r[B]) .." */static bool eval_if_version_5(void){  uint8_t op = bits(1, 1, 3);  if(op) {    return eval_compare(op, eval_reg(bits(4, 0, 8)), eval_reg(bits(5, 0, 8)));  }  return 1;}/* Evaluate special instruction.... returns the new row/line number,   0 if no new row and 256 if Break. */static int eval_special_instruction(bool cond){  int line, level;    switch(bits(1, 4, 4)) {    case 0: // NOP      line = 0;      return cond ? line : 0;    case 1: // Goto line      line = bits(7, 0, 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 = bits(7, 0, 8);       level = bits(6, 4, 4);      if(cond) {	// This always succeeds now, if we want real parental protection	// we need to ask the user and have passwords and stuff.	state->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 bool eval_link_subins(bool cond, link_t *return_values){  uint16_t button = bits(6, 0, 6);  uint8_t  linkop = bits(7, 3, 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;  if(cond && return_values->data1)    state->SPRM[8] = return_values->data1 << 10;  if(linkop == LinkNoLink) /* Obviously LinkNoLink isn't a link ;) */    return 0;  else    return cond;}/* Evaluate link instruction.   Return 1 if link, or 0 if no link   Actual link instruction is in return_values parameter */static bool eval_link_instruction(bool cond, link_t *return_values){  uint8_t op = bits(1, 4, 4);    switch(op) {    case 1:	return eval_link_subins(cond, return_values);    case 4:	return_values->command = LinkPGCN;	return_values->data1   = bits(6, 1, 15);	return cond;    case 5:	return_values->command = LinkPTTN;	return_values->data1 = bits(6, 6, 10);	return_values->data2 = bits(6, 0, 6);	if(cond && return_values->data2)	  state->SPRM[8] = return_values->data2 << 10;	return cond;    case 6:	return_values->command = LinkPGN;	return_values->data1 = bits(7, 1, 7);	return_values->data2 = bits(6, 0, 6);	if(cond && return_values->data2)	  state->SPRM[8] = return_values->data2 << 10;	return cond;    case 7:	return_values->command = LinkCN;	return_values->data1 = bits(7, 0, 8);	return_values->data2 = bits(6, 0, 6);	if(cond && return_values->data2)	  state->SPRM[8] = return_values->data2 << 10;	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 bool eval_jump_instruction(bool cond, link_t *return_values){    switch(bits(1, 4, 4)) {    case 1:      return_values->command = Exit;      return cond;    case 2:      return_values->command = JumpTT;      return_values->data1 = bits(5, 1, 7);      return cond;    case 3:      return_values->command = JumpVTS_TT;      return_values->data1 = bits(5, 1, 7);      return cond;    case 5:      return_values->command = JumpVTS_PTT;      return_values->data1 = bits(5, 1, 7);      return_values->data2 = bits(2, 6, 10);      return cond;    case 6:      switch(bits(5,0,2)) {        case 0:          return_values->command = JumpSS_FP;          return cond;        case 1:          return_values->command = JumpSS_VMGM_MENU;          return_values->data1 =  bits(5, 4, 4);          return cond;        case 2:          return_values->command = JumpSS_VTSM;          return_values->data1 =  bits(4, 0, 8);          return_values->data2 =  bits(3, 0, 8);          return_values->data3 =  bits(5, 4, 4);          return cond;        case 3:          return_values->command = JumpSS_VMGM_PGC;          return_values->data1 =  bits(2, 1, 15);          return cond;        }      break;    case 8:      switch(bits(5,0,2)) {        case 0:          return_values->command = CallSS_FP;          return_values->data1 = bits(4, 0, 8);          return cond;        case 1:          return_values->command = CallSS_VMGM_MENU;          return_values->data1 = bits(5, 4, 4);          return_values->data2 = bits(4, 0 ,8);          return cond;        case 2:          return_values->command = CallSS_VTSM;          return_values->data1 = bits(5, 4, 4);          return_values->data2 = bits(4, 0, 8);          return cond;        case 3:          return_values->command = CallSS_VMGM_PGC;          return_values->data1 = bits(2, 1, 15);          return_values->data2 = bits(4, 0, 8);          return cond;      }      break;  }  return 0;}/* Evaluate a set sytem register instruction    May contain a link so return the same as eval_link */static bool eval_system_set(int cond, link_t *return_values){  int i;  uint16_t data, data2;    switch(bits(0, 4, 4)) {    case 1: // Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle)      for(i = 1; i <= 3; i++) {        if(bits(2 + i, 0, 1)) {          data = eval_reg_or_data_2(bits(0, 3, 1), 2 + i);          if(cond) {            state->SPRM[i] = data;          }        }      }      break;    case 2: // Set system reg 9 & 10 (Navigation timer, Title PGC number)      data = eval_reg_or_data(bits(0, 3, 1), 2);      data2 = bits(5, 0, 8); // ?? size      if(cond) {	state->SPRM[9] = data; // time	state->SPRM[10] = data2; // pgcN      }      break;    case 3: // Mode: Counter / Register + Set      data = eval_reg_or_data(bits(0, 3, 1), 2);      data2 = bits(5, 4, 4);      if(bits(5, 0, 1)) {	fprintf(stderr, "Detected SetGPRMMD Counter!! This is unsupported.\n");	//exit(-1);      } else {	;      }      if(cond) {	state->GPRM[data2] = data;      }      break;    case 6: // Set system reg 8 (Highlighted button)      data = eval_reg_or_data(bits(0, 3, 1), 4); // Not system reg!!      if(cond) {	/* We check that it's in range 1..36 */	data &= 0xfc00; // Mask out the correct bits	if(data < 0x0400 || data > 0x9000) {	  //abort(0); // FixMe	  data = state->SPRM[8]; // Keep the last value instead	}	state->SPRM[8] = data;      }      break;  }  if(bits(1, 4, 4)) {    return eval_link_instruction(cond, return_values);

⌨️ 快捷键说明

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