From 181459a87051f7c781aeeb637cff6b4a83305f52 Mon Sep 17 00:00:00 2001 From: "fix94.1" Date: Sun, 22 Jan 2012 22:03:30 +0000 Subject: [PATCH] -added VERY rough solution for retail gamecube games with audio streaming, dvd drive will init twice --- source/dml/dml.c | 40 -- source/dml/dvd_broadway.c | 864 ++++++++++++++++++++++++++++++++++++++ source/dml/dvd_broadway.h | 67 +++ source/menu/menu_game.cpp | 13 + 4 files changed, 944 insertions(+), 40 deletions(-) create mode 100644 source/dml/dvd_broadway.c create mode 100644 source/dml/dvd_broadway.h diff --git a/source/dml/dml.c b/source/dml/dml.c index 0b6fe645..8ce1c1cf 100644 --- a/source/dml/dml.c +++ b/source/dml/dml.c @@ -31,46 +31,6 @@ syssram* __SYS_LockSram(); u32 __SYS_UnlockSram(u32 write); u32 __SYS_SyncSram(void); -s32 setstreaming() - { - char __di_fs[] ATTRIBUTE_ALIGN(32) = "/dev/di"; - u32 bufferin[0x20] __attribute__((aligned(32))); - u32 bufferout[0x20] __attribute__((aligned(32))); - s32 __dvd_fd = -1; - - u8 ioctl; - ioctl = IOCTL_DI_DVDLowAudioBufferConfig; - - __dvd_fd = IOS_Open(__di_fs,0); - if(__dvd_fd < 0) return __dvd_fd; - - memset(bufferin, 0, 0x20); - memset(bufferout, 0, 0x20); - - bufferin[0] = (ioctl << 24); - - if ( (*(u32*)0x80000008)>>24 ) - { - bufferin[1] = 1; - if( ((*(u32*)0x80000008)>>16) & 0xFF ) - bufferin[2] = 10; - else - bufferin[2] = 0; - } - else - { - bufferin[1] = 0; - bufferin[2] = 0; - } - DCFlushRange(bufferin, 0x20); - - int Ret = IOS_Ioctl(__dvd_fd, ioctl, bufferin, 0x20, bufferout, 0x20); - - IOS_Close(__dvd_fd); - - return ((Ret == 1) ? 0 : -Ret); - } - void SRAM_PAL() { syssram *sram; diff --git a/source/dml/dvd_broadway.c b/source/dml/dvd_broadway.c new file mode 100644 index 00000000..d60f9562 --- /dev/null +++ b/source/dml/dvd_broadway.c @@ -0,0 +1,864 @@ +/* + * Copyright (C) 2008 Nuke (wiinuke@gmail.com) + * + * this file is part of GeckoOS for USB Gecko + * http://www.usbgecko.com + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "dvd_broadway.h" + +#define DI_CMDCTX_CNT 4 + +#define DVD_DISKIDSIZE 0x20 +#define DVD_DRVINFSIZE 0x20 + +#define IOCTL_DI_INQUIRY 0x12 +#define IOCTL_DI_READID 0x70 +#define IOCTL_DI_READ 0x71 +#define IOCTL_DI_WAITCVRCLOSE 0x79 +#define IOCTL_DI_COVER 0x7A +#define IOCTL_DI_RESETNOTIFY 0x7E +#define IOCTL_DI_ClearCoverInterrupt 0x86 +#define IOCTL_DI_GetCoverStatus 0x88 +#define IOCTL_DI_RESET 0x8A +#define IOCTL_DI_OPENPART 0x8B +#define IOCTL_DI_CLOSEPART 0x8C +#define IOCTL_DI_UNENCREAD 0x8D +#define IOCTL_DI_ENABLE_DVD 0x8E +#define IOCTL_DI_REPORTKEY 0xA4 +#define IOCTL_DI_SEEK 0xAB +#define IOCTL_DI_READ_DVDVIDEO 0xD0 +#define IOCTL_DI_STOPLASER 0xD2 +#define IOCTL_DI_OFFSET 0xD9 +#define IOCTL_DI_REQERROR 0xE0 +#define IOCTL_DI_DVDLowAudioStatus 0xE2 +#define IOCTL_DI_STOPMOTOR 0xE3 +#define IOCTL_DI_DVDLowAudioBufferConfig 0xE4 +#define IOCTL_DI_SETOFFBASE 0xF0 +#define IOCTL_DI_GETOFFBASE 0xF1 +#define IOCTL_DI_SETCRYPTMODE 0xF2 +#define IOCTL_DI_GETCRYPTMODE 0xF3 +#define IOCTL_DI_SETDVDROMMODE 0xF4 +#define IOCTL_DI_GETDVDROMMODE 0xF5 +#define DI_SETWBFSMODE_IOS249 0xf4 +#define IOCTL_DI_DISCTYPE 0xF7 +//#define DI_SETWBFSMODE_IOS222 0xfe + +#define IOCTL_DI_SNEEK_READ_GAMEINFO 0x30 +#define IOCTL_DI_SNEEK_SELECT_GAME 0x23 +#define IOCTL_DI_SNEEK_GET_GAMECOUNT 0x24 + + + + + +#define _SHIFTL(v, s, w) \ + ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) +#define _SHIFTR(v, s, w) \ + ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) + + +static u32 bufferin[0x20] __attribute__((aligned(32))); +static u32 bufferout[0x20] __attribute__((aligned(32))); + +struct dicommand +{ + u32 diReg[8]; +}; + +struct dicontext +{ + lwp_node node; + dvdcallbacklow cb; + struct dicommand *cmd; +}; + +static s32 __dvd_fd = -1; +static u32 __dvd_spinupval = 1; +static lwp_queue __di_contextq; +static u32 __dvd_readlength = 0; +static u32 __dvd_cbinprogress = 0; +static u32 __dvd_reqinprogress = 0; +static u32 __dvd_lowinitcalled = 0; +static struct dicommand *__di_commands = NULL; +static struct dicontext __di_contexts[DI_CMDCTX_CNT]; +static u32 __di_regbuffer[0x08] ATTRIBUTE_ALIGN(32); +static u32 __di_regvalcache[0x08] ATTRIBUTE_ALIGN(32); +static u32 __di_lastticketerror[0x08] ATTRIBUTE_ALIGN(32); +static ioctlv __di_iovector[0x08] ATTRIBUTE_ALIGN(32); +static char __di_fs[] ATTRIBUTE_ALIGN(32) = "/dev/di"; + +extern u32 __IPC_ClntInit(); + +static __inline__ lwp_node* __lwp_queue_head(lwp_queue *queue) +{ + return (lwp_node*)queue; +} + +static __inline__ lwp_node* __lwp_queue_tail(lwp_queue *queue) +{ + return (lwp_node*)&queue->perm_null; +} + + +static __inline__ void __lwp_queue_init_empty(lwp_queue *queue) +{ + queue->first = __lwp_queue_tail(queue); + queue->perm_null = NULL; + queue->last = __lwp_queue_head(queue); +} + +static struct dicontext* __dvd_getcontext(dvdcallbacklow cb) +{ + struct dicontext *ctx; + + ctx = (struct dicontext*)__lwp_queue_get(&__di_contextq); + if(ctx!=NULL) ctx->cb = cb; + + return ctx; +} + +static s32 __dvd_iostransactionCB(s32 result,void *usrdata) +{ + struct dicontext *ctx = (struct dicontext*)usrdata; + + __dvd_reqinprogress = 0; + + if(ctx->cb!=NULL) { + __dvd_cbinprogress = 1; + if(result!=0) __dvd_readlength = 0; + ctx->cb(result); + __dvd_cbinprogress = 0; + } + __lwp_queue_append(&__di_contextq,&ctx->node); + + return 0; +} + +static s32 __dvd_ioscoverregisterCB(s32 result,void *usrdata) +{ + struct dicontext *ctx = (struct dicontext*)usrdata; + + __dvd_reqinprogress = 0; + __di_regvalcache[1] = __di_regbuffer[0]; + + if(ctx->cb!=NULL) { + __dvd_cbinprogress = 1; + ctx->cb(result); + __dvd_cbinprogress = 0; + } + __lwp_queue_append(&__di_contextq,&ctx->node); + + return 0; +} + +static s32 __dvd_ioscovercloseCB(s32 result,void *usrdata) +{ + struct dicontext *ctx = (struct dicontext*)usrdata; + + __dvd_reqinprogress = 0; + + if(ctx->cb!=NULL) { + __dvd_cbinprogress = 1; + ctx->cb(result); + __dvd_cbinprogress = 0; + } + __lwp_queue_append(&__di_contextq,&ctx->node); + + return 0; +} + +s32 bwDVD_LowInit() +{ + s32 i,ret = 0; + u32 ipclo,ipchi; + lwp_queue inactives; + struct dicontext *ctx; + + if(__dvd_lowinitcalled==0) { + ret = __IPC_ClntInit(); + if(ret<0) return ret; + + ipclo = (((u32)IPC_GetBufferLo()+0x1f)&~0x1f); + ipchi = (u32)IPC_GetBufferHi(); + if(ipchi>=(ipclo+(sizeof(struct dicommand)*DI_CMDCTX_CNT))) { + __di_commands = (struct dicommand*)ipclo; + IPC_SetBufferLo((void*)(ipclo+(sizeof(struct dicommand)*DI_CMDCTX_CNT))); + + memset(__di_commands,0,(sizeof(struct dicommand)*DI_CMDCTX_CNT)); + + i = 0; + __lwp_queue_init_empty(&__di_contextq); + __lwp_queue_initialize(&inactives,__di_contexts,DI_CMDCTX_CNT,sizeof(struct dicontext)); + while((ctx=(struct dicontext*)__lwp_queue_get(&inactives))!=NULL) { + ctx->cmd = &__di_commands[i]; + ctx->cb = NULL; + __lwp_queue_append(&__di_contextq,&ctx->node); + + i++; + } + } + + ret = IOS_Open(__di_fs,0); + if(ret<0) return ret; + + __dvd_fd = ret; + //__dvd_lowinitcalled = 1; + + // printf("DVD_LowInit(%d)\n",ret); + } + return 0; +} + +s32 bwDVD_LowClose() +{ + IOS_Close(__dvd_fd); + return 0; +} + + +s32 bwDVD_LowInquiry(dvddrvinfo *info,dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_INQUIRY<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_INQUIRY,cmd->diReg,sizeof(struct dicommand),info,DVD_DRVINFSIZE,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowReadID(dvddiskid *diskID,dvdcallbacklow cb) +{ + s32 ret = 0; + struct dicontext *ctx; + struct dicommand *cmd; + +// printf("DVD_LowReadID()\n"); + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_READID<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_READID,cmd->diReg,sizeof(struct dicommand),diskID,DVD_DISKIDSIZE,__dvd_iostransactionCB,ctx); + +// printf("DVD_LowReadID(%d)\n",ret); + return ret; +} + + +s32 bwDVD_LowRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + if(buf==NULL || ((u32)buf%32)!=0) return -1; + + __dvd_reqinprogress = 1; + __dvd_readlength = len; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_READ<<24); + cmd->diReg[1] = len; + cmd->diReg[2] = offset; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_READ,cmd->diReg,sizeof(struct dicommand),buf,len,__dvd_iostransactionCB,ctx); + + return ret; +} + +// never got this function working, probably removed from wii +s32 bwDVD_LowReadVideo(void *buf,u32 len,u32 offset,dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + __dvd_readlength = len; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_READ_DVDVIDEO<<24); + cmd->diReg[1] = len; + cmd->diReg[2] = offset; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_READ_DVDVIDEO,cmd->diReg,sizeof(struct dicommand),buf,len,__dvd_iostransactionCB,ctx); + + return ret; +} + + + +s32 bwDVD_LowStopLaser(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_STOPLASER<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_STOPLASER,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; +} + +// never got this function working, probably removed from wii +s32 bwDVD_EnableVideo(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_ENABLE_DVD<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_ENABLE_DVD,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowSeek(u32 offset,dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_SEEK<<24); + cmd->diReg[1] = offset; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_SEEK,cmd->diReg,sizeof(struct dicommand),NULL,0,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowOffset(u64 offset,dvdcallbacklow cb) +{ + s32 ret; + u32 *off = (u32*)(void*)(&offset); + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_OFFSET<<24); + cmd->diReg[1] = 0; + if (off[0]) cmd->diReg[1] = 1; + cmd->diReg[2] = off[1]; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_OFFSET,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowPrepareCoverRegister(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_COVER<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_COVER,cmd->diReg,sizeof(struct dicommand),__di_regbuffer,0x20,__dvd_ioscoverregisterCB,ctx); + + return ret; +} + +s32 bwDVD_LowOpenPartition(u32 offset,void *eticket,u32 certin_len,void *certificate_in,void *certificate_out,dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + if(eticket!=NULL && ((u32)eticket%32)!=0) return -1; + if(certificate_in!=NULL && ((u32)certificate_in%32)!=0) return -1; + if(certificate_out!=NULL && ((u32)certificate_out%32)!=0) return -1; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_OPENPART<<24); + cmd->diReg[1] = offset; + + __di_iovector[0].data = cmd; + __di_iovector[0].len = sizeof(struct dicommand); + + __di_iovector[1].data = eticket; + if(eticket==NULL) __di_iovector[1].len = 0; + else __di_iovector[1].len = 676; + + __di_iovector[2].data = certificate_in; + if(certificate_in==NULL) __di_iovector[2].len = 0; + else __di_iovector[2].len = certin_len; + + __di_iovector[3].data = certificate_out; + __di_iovector[3].len = 18916; + __di_iovector[4].data = __di_lastticketerror; + __di_iovector[4].len = 0x20; + ret = IOS_IoctlvAsync(__dvd_fd,IOCTL_DI_OPENPART,3,2,__di_iovector,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowClosePartition(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_CLOSEPART<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_CLOSEPART,cmd->diReg,sizeof(struct dicommand),NULL,0,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowUnencryptedRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + __dvd_readlength = len; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_UNENCREAD<<24); + cmd->diReg[1] = len; + cmd->diReg[2] = offset; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_UNENCREAD,cmd->diReg,sizeof(struct dicommand),buf,len,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowWaitCoverClose(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_WAITCVRCLOSE<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_WAITCVRCLOSE,cmd->diReg,sizeof(struct dicommand),NULL,0,__dvd_ioscovercloseCB,ctx); + + return ret; +} + +s32 bwDVD_LowResetNotify() +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + if(__dvd_cbinprogress==1) return -1; + + ctx = __dvd_getcontext(NULL); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_RESETNOTIFY<<24); + ret = IOS_Ioctl(__dvd_fd,IOCTL_DI_RESETNOTIFY,cmd->diReg,sizeof(struct dicommand),NULL,0); + + return ret; +} + +s32 bwDVD_LowReset(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + +// printf("DVD_LowReset()\n"); + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_RESET<<24); + cmd->diReg[1] = __dvd_spinupval; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_RESET,cmd->diReg,sizeof(struct dicommand),NULL,0,__dvd_iostransactionCB,ctx); + +// printf("DVD_LowReset(%d)\n",ret); + return ret; +} + +s32 bwDVD_LowStopMotor(u8 stop1,u8 stop2) +{ + memset(bufferin, 0, 0x20 ); + memset(bufferout, 0, 0x20 ); + + bufferin[0] = IOCTL_DI_STOPMOTOR<<24; + bufferin[1] = stop1<<24; + bufferin[2] = stop2<<24; + + DCFlushRange(bufferin, 0x20); + + int ret = IOS_Ioctl( __dvd_fd, IOCTL_DI_STOPMOTOR, bufferin, 0x20, bufferout, 0x20); + + return ret; +} + +/* +s32 bwDVD_LowStopMotor(u8 stop1,u8 stop2,dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_STOPMOTOR<<24); + cmd->diReg[1] = (stop1<<24); + cmd->diReg[2] = (stop2<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_STOPMOTOR,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; + +}*/ + + +s32 bwDVD_LowRequestError( void ) +{ + memset(bufferin, 0, 0x20 ); + memset(bufferout, 0, 0x20 ); + + bufferin[0] = (IOCTL_DI_REQERROR << 24); + + DCFlushRange(bufferin, 0x20); + + int ret = IOS_Ioctl( __dvd_fd, IOCTL_DI_REQERROR, bufferin, 0x20, bufferout, 0x20); + + DCFlushRange(bufferout, 0x20); + + if( ret < 0 ) + return ret; + return bufferout[0]; +} + +s32 bwDVD_LowAudioStatus( void ) +{ + memset(bufferin, 0, 0x20 ); + memset(bufferout, 0, 0x20 ); + + bufferin[0] = (IOCTL_DI_DVDLowAudioStatus << 24); + + DCFlushRange(bufferin, 0x20); + + int ret = IOS_Ioctl( __dvd_fd, IOCTL_DI_DVDLowAudioStatus, bufferin, 0x20, bufferout, 0x20); + + DCFlushRange(bufferout, 0x20); + + if( ret < 0) + return ret; + return bufferout[0]; +} +/* + +s32 bwDVD_LowRequestError(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_REQERROR<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_REQERROR,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; +} +*/ + +s32 bwDVD_LowClearCoverInterrupt(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_ClearCoverInterrupt<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_ClearCoverInterrupt,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_LowReportKey(dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_REPORTKEY<<24); + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_REPORTKEY,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; +} + + + +s32 bwDVD_SetDecryption(s32 mode, dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_SETCRYPTMODE<<24); + cmd->diReg[1] = mode; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_SETCRYPTMODE,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; + +} + +s32 bwDVD_SetOffset(u32 offset, dvdcallbacklow cb) +{ + s32 ret; + struct dicontext *ctx; + struct dicommand *cmd; + + __dvd_reqinprogress = 1; + + ctx = __dvd_getcontext(cb); + if(ctx==NULL) return IPC_ENOMEM; + + cmd = ctx->cmd; + cmd->diReg[0] = (IOCTL_DI_SETOFFBASE<<24); + cmd->diReg[1] = offset; + ret = IOS_IoctlAsync(__dvd_fd,IOCTL_DI_SETOFFBASE,cmd->diReg,sizeof(struct dicommand),__di_regvalcache,0x20,__dvd_iostransactionCB,ctx); + + return ret; +} + +s32 bwDVD_GetCoverStatus(u32 *status) +{ + memset(bufferin, 0, 0x20); + memset(bufferout, 0, 0x20); + + bufferin[0] = (IOCTL_DI_GetCoverStatus << 24); + DCFlushRange(bufferin, 0x20); + + int Ret = IOS_Ioctl(__dvd_fd, IOCTL_DI_GetCoverStatus, bufferin, 0x20, bufferout, 0x20); + + DCFlushRange(bufferout, 0x20); + *status = bufferout[0]; + + //return ((Ret == 1) ? 0 : -Ret); + return Ret; +} +/* +s32 bwDVD_SetDiscType(bool dvd5) +{ + memset(bufferin, 0, 0x20); + memset(bufferout, 0, 0x20); + + bufferin[0] = IOCTL_DI_DISCTYPE << 24; + + if (dvd5) + { + bufferin[1] = 0; + } else + { + bufferin[1] = 1; + } + + int Ret = IOS_Ioctl(__dvd_fd, IOCTL_DI_DISCTYPE, bufferin, 0x20, bufferout, 0x20); + + return ((Ret == 1) ? 0 : -Ret); +} +*/ +s32 SetWBFSMode(u8 device, void*discid) +{ + u8 ioctl; + ioctl = DI_SETWBFSMODE_IOS249; + + memset(bufferin, 0, 0x20); + memset(bufferout, 0, 0x20); + + bufferin[0] = (ioctl << 24); + bufferin[1] = device; + if (discid) + { + memcpy(&bufferin[2],discid,6); + } + DCFlushRange(bufferin, 0x20); + + int Ret = IOS_Ioctl(__dvd_fd, ioctl, bufferin, 0x20, bufferout, 0x20); + + return ((Ret == 1) ? 0 : -Ret); +} + +s32 setstreaming() +{ + u8 ioctl; + ioctl = IOCTL_DI_DVDLowAudioBufferConfig; + + memset(bufferin, 0, 0x20); + memset(bufferout, 0, 0x20); + + bufferin[0] = (ioctl << 24); + + if ( (*(u32*)0x80000008)>>24 ) + { + bufferin[1] = 1; + if( ((*(u32*)0x80000008)>>16) & 0xFF ) + { + bufferin[2] = 10; + } else + { + bufferin[2] = 0; + } + } + else + { + bufferin[1] = 0; + bufferin[2] = 0; + } + DCFlushRange(bufferin, 0x20); + + int Ret = IOS_Ioctl(__dvd_fd, ioctl, bufferin, 0x20, bufferout, 0x20); + + return ((Ret == 1) ? 0 : -Ret); +} + + +s32 Sneek_DVDReadGameInfo( u32 Offset, u32 Length, void *Data ) +{ + memset(bufferin, 0, 0x20); + + bufferin[0] = Offset; + bufferin[1] = Length; + bufferin[2] = MEM_VIRTUAL_TO_PHYSICAL((u32)Data); + + DCFlushRange(bufferin, 0x20); + DCInvalidateRange(Data, Length); + + s32 ret = IOS_Ioctl( __dvd_fd, IOCTL_DI_SNEEK_READ_GAMEINFO, bufferin, sizeof(u32) * 3, NULL, 0 ); + + DCFlushRange(Data, Length); + + return ret; +} + + +s32 Sneek_DVDSelectGame( u32 SlotID ) +{ + memset(bufferin, 0, 0x20); + + bufferin[0] = SlotID; + DCFlushRange(bufferin, 0x20); + + s32 ret = IOS_Ioctl(__dvd_fd, IOCTL_DI_SNEEK_SELECT_GAME, bufferin, sizeof(u32) * 1, NULL, 0 ); + + return ret; +} + +s32 Sneek_DVDGetGameCount( u32 *Count ) +{ + s32 ret = IOS_Ioctl( __dvd_fd, IOCTL_DI_SNEEK_GET_GAMECOUNT, NULL, 0, (u32 *)(MEM_VIRTUAL_TO_PHYSICAL(Count)), sizeof(u32) ); + return ret; +} + + + + diff --git a/source/dml/dvd_broadway.h b/source/dml/dvd_broadway.h new file mode 100644 index 00000000..5a50ef35 --- /dev/null +++ b/source/dml/dvd_broadway.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008 Nuke (wiinuke@gmail.com) + * + * this file is part of GeckoOS for USB Gecko + * http://www.usbgecko.com + * + * 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 + */ + +#ifndef __DVD_BROADWAY_H__ +#define __DVD_BROADWAY_H__ + +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +typedef void (*dvdcallbacklow)(s32 result); + +s32 bwDVD_LowInit(); +s32 bwDVD_LowClose(); +s32 bwDVD_LowInquiry(dvddrvinfo *info,dvdcallbacklow cb); +s32 bwDVD_LowReadID(dvddiskid *diskID,dvdcallbacklow cb); +s32 bwDVD_LowClosePartition(dvdcallbacklow cb); +s32 bwDVD_LowOpenPartition(u32 offset,void *eticket,u32 certin_len,void *certificate_in,void *certificate_out,dvdcallbacklow cb); +s32 bwDVD_LowUnencryptedRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb); +s32 bwDVD_LowReset(dvdcallbacklow cb); +s32 bwDVD_LowWaitCoverClose(dvdcallbacklow cb); +s32 bwDVD_LowRead(void *buf,u32 len,u32 offset,dvdcallbacklow cb); +s32 bwDVD_EnableVideo(dvdcallbacklow cb); +s32 bwDVD_LowReadVideo(void *buf,u32 len,u32 offset,dvdcallbacklow cb); +s32 bwDVD_SetDecryption(s32 mode, dvdcallbacklow cb); +s32 bwDVD_SetOffset(u32 offset, dvdcallbacklow cb); +s32 bwDVD_LowStopMotor(u8 stop1,u8 stop2); +s32 bwDVD_GetCoverStatus(u32 *status); +s32 bwDVD_LowRequestError( void ); +s32 bwDVD_LowAudioStatus( void ); +s32 bwDVD_LowClearCoverInterrupt(dvdcallbacklow cb); +s32 bwDVD_LowReportKey(dvdcallbacklow cb); +//s32 bwDVD_SetDiscType(bool dvd5); +s32 SetWBFSMode(u8 device, void*discid); +s32 setstreaming(); + +s32 Sneek_DVDReadGameInfo( u32 Offset, u32 Length, void *Data ); +s32 Sneek_DVDSelectGame( u32 SlotID ); +s32 Sneek_DVDGetGameCount( u32 *Count ); + +#ifdef __cplusplus + } +#endif /* __cplusplus */ + +#endif diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index 7bdcb0e6..5b2b27c2 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -30,6 +30,7 @@ #include "defines.h" #include "dml/dml.h" +#include "dml/dvd_broadway.h" using namespace std; @@ -46,6 +47,15 @@ extern const u8 favoritesoffs_png[]; extern const u8 delete_png[]; extern const u8 deletes_png[]; + +static dvddiskid *g_diskID = (dvddiskid*)0x80000000; +static vu32 dvddone = 0; + +static void __dvd_readidcb(s32 result) +{ + dvddone = result; +} + extern u32 sector_size; extern int mainIOS; static u64 sm_title_id[8] ATTRIBUTE_ALIGN(32); @@ -1072,6 +1082,9 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd) if (gc) { + bwDVD_LowInit(); + bwDVD_LowReset(__dvd_readidcb); + bwDVD_LowReadID(g_diskID,__dvd_readidcb); _launchGC(id.c_str(),false); } else