diff --git a/source/fceugx.cpp b/source/fceugx.cpp index 2a7579d..0b03136 100644 --- a/source/fceugx.cpp +++ b/source/fceugx.cpp @@ -229,6 +229,31 @@ static bool FindIOS(u32 ios) free(titles); return false; } + +#define ROUNDDOWN32(v) (((u32)(v)-0x1f)&~0x1f) + +static bool USBLANDetected() +{ + u8 dummy; + u8 i; + u16 vid, pid; + + USB_Initialize(); + u8 *buffer = (u8*)ROUNDDOWN32(((u32)SYS_GetArena2Hi() - (32*1024))); + memset(buffer, 0, 8 << 3); + + if(USB_GetDeviceList("/dev/usb/oh0", buffer, 8, 0, &dummy) < 0) + return false; + + for(i = 0; i < 8; i++) + { + memcpy(&vid, (buffer + (i << 3) + 4), 2); + memcpy(&pid, (buffer + (i << 3) + 6), 2); + if( (vid == 0x0b95) && (pid == 0x7720)) + return true; + } + return false; +} #endif /**************************************************************************** * USB Gecko Debugging @@ -299,20 +324,44 @@ int main(int argc, char *argv[]) #endif #ifdef HW_RVL + bool usblan = USBLANDetected(); + // try to load IOS 202 if(FindIOS(202)) IOS_ReloadIOS(202); else if(IOS_GetVersion() < 61 && FindIOS(61)) IOS_ReloadIOS(61); - + if(IOS_GetVersion() == 202) { - DI_LoadDVDX(false); - DI_Init(); - - // load usb2 driver + // enable DVD and USB2 if(mload_init() >= 0 && load_ehci_module()) + { + int mode = 3; + + if(usblan) + { + int usblanport = GetUSB2LanPort(); + + if(usblanport >= 0) + { + if(usblanport == 1) + mode = 1; + else + mode = 2; + + USB2Storage_Close(); + mload_close(); + IOS_ReloadIOS(202); + mload_init(); + load_ehci_module(); + } + } + SetUSB2Mode(mode); USB2Enable(true); + DI_LoadDVDX(false); + DI_Init(); + } } #endif diff --git a/source/utils/FreeTypeGX.cpp b/source/utils/FreeTypeGX.cpp index d982292..8c2f936 100644 --- a/source/utils/FreeTypeGX.cpp +++ b/source/utils/FreeTypeGX.cpp @@ -22,8 +22,6 @@ #include "FreeTypeGX.h" -#define EXPLODE_UINT8_TO_UINT32(x) (x << 24) | (x << 16) | (x << 8) | x - static FT_Library ftLibrary; /**< FreeType FT_Library instance. */ static FT_Face ftFace; /**< FreeType reusable FT_Face typographic object. */ static FT_GlyphSlot ftSlot; /**< FreeType reusable FT_GlyphSlot glyph container object. */ @@ -91,47 +89,6 @@ wchar_t* charToWideChar(const char* strChar) return strWChar; } -static uint32_t* convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t bufferWidth, uint16_t bufferHeight) { - uint32_t bufferSize = (bufferWidth * bufferHeight) << 2; - uint32_t* dataBufferRGBA8 = (uint32_t *)memalign(32, bufferSize); - memset(dataBufferRGBA8, 0x00, bufferSize); - - uint8_t *src = (uint8_t *)rgbaBuffer; - uint8_t *dst = (uint8_t *)dataBufferRGBA8; - - for(uint32_t block = 0; block < bufferHeight; block += 4) { - for(uint32_t i = 0; i < bufferWidth; i += 4) { - for (uint32_t c = 0; c < 4; c++) { - uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ; - - *dst++ = src[blockWid+ 3]; // ar = 0 - *dst++ = src[blockWid+ 0]; - *dst++ = src[blockWid+ 7]; // ar = 1 - *dst++ = src[blockWid+ 4]; - *dst++ = src[blockWid+ 11]; // ar = 2 - *dst++ = src[blockWid+ 8]; - *dst++ = src[blockWid+ 15]; // ar = 3 - *dst++ = src[blockWid+ 12]; - } - for (uint32_t c = 0; c < 4; c++) { - uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ; - - *dst++ = src[blockWid+ 1]; // gb = 0 - *dst++ = src[blockWid+ 2]; - *dst++ = src[blockWid+ 5]; // gb = 1 - *dst++ = src[blockWid+ 6]; - *dst++ = src[blockWid+ 9]; // gb = 2 - *dst++ = src[blockWid+ 10]; - *dst++ = src[blockWid+ 13]; // gb = 3 - *dst++ = src[blockWid+ 14]; - } - } - } - DCFlushRange(dataBufferRGBA8, bufferSize); - - return dataBufferRGBA8; -} - /** * Default constructor for the FreeTypeGX class. * @@ -333,26 +290,36 @@ uint16_t FreeTypeGX::cacheGlyphDataComplete() * * @param bmp A pointer to the most recently rendered glyph's bitmap. * @param charData A pointer to an allocated ftgxCharData structure whose data represent that of the last rendered glyph. + * + * Optimized for RGBA8 use by Dimok. */ void FreeTypeGX::loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData) { - uint32_t *glyphData = (uint32_t *)memalign(32, charData->textureWidth * charData->textureHeight * 4); - memset(glyphData, 0x00, charData->textureWidth * charData->textureHeight * 4); + int length = charData->textureWidth * charData->textureHeight * 4; + + uint8_t * glyphData = (uint8_t *) memalign(32, length); + if(!glyphData) + return; + + memset(glyphData, 0x00, length); uint8_t *src = (uint8_t *)bmp->buffer; - uint32_t *dest = glyphData, *ptr = dest; + uint32_t offset; - for (int imagePosY = 0; imagePosY < bmp->rows; imagePosY++) + for (int imagePosY = 0; imagePosY < bmp->rows; ++imagePosY) { - for (int imagePosX = 0; imagePosX < bmp->width; imagePosX++) + for (int imagePosX = 0; imagePosX < bmp->width; ++imagePosX) { - *ptr++ = EXPLODE_UINT8_TO_UINT32(*src); - src++; + offset = ((((imagePosY >> 2) * (charData->textureWidth >> 2) + (imagePosX >> 2)) << 5) + ((imagePosY & 3) << 2) + (imagePosX & 3)) << 1; + glyphData[offset] = *src; + glyphData[offset+1] = *src; + glyphData[offset+32] = *src; + glyphData[offset+33] = *src; + ++src; } - ptr = dest += charData->textureWidth; } - charData->glyphDataTexture = convertBufferToRGBA8(glyphData, charData->textureWidth, charData->textureHeight); - free(glyphData); + DCFlushRange(glyphData, length); + charData->glyphDataTexture = (uint32_t *) glyphData; } /** diff --git a/source/utils/ehcmodule.elf.o b/source/utils/ehcmodule.elf.o index f88d988..1a67ac2 100644 Binary files a/source/utils/ehcmodule.elf.o and b/source/utils/ehcmodule.elf.o differ diff --git a/source/utils/mload.c b/source/utils/mload.c index 2c6f534..24bb65b 100644 --- a/source/utils/mload.c +++ b/source/utils/mload.c @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - + #ifdef HW_RVL #include @@ -22,25 +22,15 @@ #include #include #include -#include #include "unistd.h" #include "ehcmodule_elf.h" -#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400 -#define MLOAD_LOAD_MODULE 0x4D4C4480 -#define MLOAD_RUN_MODULE 0x4D4C4481 +#define MLOAD_GET_IOS_BASE 0x4D4C4401 +#define MLOAD_GET_MLOAD_VERSION 0x4D4C4402 #define MLOAD_RUN_THREAD 0x4D4C4482 - -#define MLOAD_STOP_THREAD 0x4D4C4484 -#define MLOAD_CONTINUE_THREAD 0x4D4C4485 - #define MLOAD_GET_LOAD_BASE 0x4D4C4490 #define MLOAD_MEMSET 0x4D4C4491 -#define MLOAD_GET_EHCI_DATA 0x4D4C44A0 - -#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0 - #define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3])) typedef struct @@ -84,17 +74,53 @@ typedef struct } data_elf; static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload"; + static s32 mload_fd = -1; +static s32 hid = -1; + +int mloadVersion = -1; +int iosBase = -1; + +// to close the device (remember call it when rebooting the IOS!) +int mload_close() +{ + int ret; + + if (hid >= 0) + { + iosDestroyHeap(hid); + hid = -1; + } + + if (mload_fd < 0) + return -1; + + ret = IOS_Close(mload_fd); + mload_fd = -1; + return ret; +} // to init/test if the device is running int mload_init() { int n; + if (hid < 0) + hid = iosCreateHeap(0x800); + + if (hid < 0) + { + if (mload_fd >= 0) + IOS_Close(mload_fd); + + mload_fd = -1; + return hid; + } + if (mload_fd >= 0) return 0; - for (n = 0; n < 10; n++) // try 2.5 seconds + for (n = 0; n < 20; n++) // try 5 seconds { mload_fd = IOS_Open(mload_fs, 0); @@ -104,22 +130,16 @@ int mload_init() usleep(250 * 1000); } - return mload_fd; -} - -// to close the device (remember call it when rebooting the IOS!) -int mload_close() -{ - int ret; - if (mload_fd < 0) - return -1; + return mload_close(); - ret = IOS_Close(mload_fd); + mloadVersion = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_MLOAD_VERSION, ":"); + iosBase = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_IOS_BASE, ":"); - mload_fd = -1; + if(mloadVersion < 82) // unsupported IOS202 + return mload_close(); - return ret; + return mload_fd; } // fix starlet address to read/write (uses SEEK_SET, etc as mode) @@ -127,6 +147,7 @@ static int mload_seek(int offset, int mode) { if (mload_init() < 0) return -1; + return IOS_Seek(mload_fd, offset, mode); } @@ -135,29 +156,17 @@ static int mload_write(const void * buf, u32 size) { if (mload_init() < 0) return -1; + return IOS_Write(mload_fd, buf, size); } // fill a block (similar to memset) static int mload_memset(void *starlet_addr, int set, int len) { - int ret; - s32 hid = -1; - if (mload_init() < 0) return -1; - hid = iosCreateHeap(0x800); - - if (hid < 0) - return hid; - - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, - set, len); - - iosDestroyHeap(hid); - - return ret; + return IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, set, len); } // load a module from the PPC @@ -202,25 +211,23 @@ static int mload_elf(void *my_elf, data_elf *data_elf) { switch (getbe32(m)) { - case 0x9: - data_elf->start = (void *) getbe32(m+4); - break; - case 0x7D: - data_elf->prio = getbe32(m+4); - break; - case 0x7E: - data_elf->size_stack = getbe32(m+4); - break; - case 0x7F: - data_elf->stack = (void *) (getbe32(m+4)); - break; - + case 0x9: + data_elf->start = (void *) getbe32(m+4); + break; + case 0x7D: + data_elf->prio = getbe32(m+4); + break; + case 0x7E: + data_elf->size_stack = getbe32(m+4); + break; + case 0x7F: + data_elf->stack = (void *) (getbe32(m+4)); + break; } } } else if (entries->type == 1 && entries->memsz != 0 && entries->vaddr != 0) { - if (mload_memset((void *) entries->vaddr, 0, entries->memsz) < 0) return -1; if (mload_seek(entries->vaddr, SEEK_SET) < 0) @@ -229,52 +236,44 @@ static int mload_elf(void *my_elf, data_elf *data_elf) return -1; } } - return 0; } // run one thread (you can use to load modules or binary files) -static int mload_run_thread(void *starlet_addr, void *starlet_top_stack, - int stack_size, int priority) +static int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority) { - int ret; - s32 hid = -1; - if (mload_init() < 0) return -1; - hid = iosCreateHeap(0x800); + return IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", starlet_addr, starlet_top_stack, stack_size, priority); +} - if (hid < 0) - return hid; +// get the base and the size of the memory readable/writable to load modules +static int mload_get_load_base(u32 *starlet_base, int *size) +{ + if (mload_init() < 0) + return -1; - ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", - starlet_addr, starlet_top_stack, stack_size, priority); - - iosDestroyHeap(hid); - - return ret; + return IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOAD_BASE, ":ii", starlet_base, size); } bool load_ehci_module() { - data_elf my_data_elf; - my_data_elf.start = NULL; - my_data_elf.prio = 0; - my_data_elf.stack = NULL; - my_data_elf.size_stack = 0; + data_elf elf; + memset(&elf, 0, sizeof(data_elf)); - if(mload_elf((void *) ehcmodule_elf, &my_data_elf) != 0) + u32 addr; + int len; + + mload_get_load_base(&addr, &len); + + if(mload_elf((void *) ehcmodule_elf, &elf) != 0) return false; - if (mload_run_thread(my_data_elf.start, my_data_elf.stack, - my_data_elf.size_stack, my_data_elf.prio) < 0) - { - usleep(1000); - if (mload_run_thread(my_data_elf.start, my_data_elf.stack, - my_data_elf.size_stack, 0x47) < 0) - return false; - } + if(mload_run_thread(elf.start, elf.stack, elf.size_stack, 0x47) < 0) + return false; + + usleep(5000); return true; } diff --git a/source/utils/mload.h b/source/utils/mload.h index db6bb5b..aa01daf 100644 --- a/source/utils/mload.h +++ b/source/utils/mload.h @@ -18,16 +18,15 @@ #ifndef __MLOAD_H__ #define __MLOAD_H__ -#ifdef __cplusplus extern "C" { -#endif + +extern int mloadVersion; +extern int iosBase; int mload_init(); bool load_ehci_module(); int mload_close(); -#ifdef __cplusplus } -#endif #endif diff --git a/source/utils/usb2storage.c b/source/utils/usb2storage.c index 3b7fc68..4f3c374 100644 --- a/source/utils/usb2storage.c +++ b/source/utils/usb2storage.c @@ -50,22 +50,24 @@ #define debug_printf(fmt, args...) #endif // DEBUG_USB2 -#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8)) -#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1) -#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2) -#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3) +#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8)) +#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1) +#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2) +#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3) #define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4) #define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5) #define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6) #define USB_IOCTL_UMS_IS_INSERTED (UMS_BASE+0x7) +#define USB_IOCTL_UMS_USB_MODE (UMS_BASE+0x8) +#define USB_IOCTL_UMS_GET_USBLAN_PORT (UMS_BASE+0x9) #define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10) -#define USB_IOCTL_UMS_START (UMS_BASE+0x11) -#define USB_IOCTL_UMS_STOP (UMS_BASE+0x12) -#define USB_IOCTL_UMS_EXIT (UMS_BASE+0x16) +#define USB_IOCTL_UMS_START (UMS_BASE+0x11) +#define USB_IOCTL_UMS_STOP (UMS_BASE+0x12) +#define USB_IOCTL_UMS_EXIT (UMS_BASE+0x16) #define UMS_HEAPSIZE 2*1024 -#define UMS_MAXPATH 16 +#define UMS_MAXPATH 16 static s32 hId = -1; static s32 __usb2fd = -1; @@ -81,7 +83,6 @@ static u8 __usb2_heap_created = 0; static DISC_INTERFACE __io_usb1storage; static int usb1disc_inited = 0; extern const DISC_INTERFACE __io_usb2storage; -static int currentMode = 2; // 1 = use USB1 interface, 2 = use USB2 interface static s32 USB2CreateHeap() { @@ -108,11 +109,11 @@ static s32 USB2CreateHeap() static s32 USB2Storage_Initialize() { - static bool inited = false; - - if(inited) + if(__usb2fd > 0) return 0; + char *devicepath = NULL; + if (usb2_mutex == LWP_MUTEX_NULL) LWP_MutexInit(&usb2_mutex, false); @@ -134,26 +135,9 @@ static s32 USB2Storage_Initialize() if (fixed_buffer == NULL) fixed_buffer = __lwp_heap_allocate(&usb2_heap, USB2_BUFFER); - inited = true; - return 0; -} - -static s32 USB2Storage_Open(int verbose) -{ - char *devicepath = NULL; - s32 ret = USB_OK; - u32 size = 0; - - if(__usb2fd > 0) - return 0; - - if(USB2Storage_Initialize() < 0) - return -1; - - LWP_MutexLock(usb2_mutex); - if (__usb2fd <= 0) { + LWP_MutexLock(usb2_mutex); devicepath = iosAlloc(hId, UMS_MAXPATH); if (devicepath == NULL) { @@ -164,16 +148,26 @@ static s32 USB2Storage_Open(int verbose) snprintf(devicepath, USB_MAXPATH, "/dev/usb2"); __usb2fd = IOS_Open(devicepath, 0); iosFree(hId, devicepath); + LWP_MutexUnlock(usb2_mutex); } if(__usb2fd <= 0) return -1; - if (verbose) - ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_SET_VERBOSE, ":"); + return 0; +} + +static s32 USB2Storage_Open() +{ + s32 ret = USB_OK; + u32 size = 0; + + if(USB2Storage_Initialize() < 0) + return -1; + ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_INIT, ":"); debug_printf("usb2 init value: %i\n", ret); - + if (ret < 0) debug_printf("usb2 error init\n"); else @@ -189,7 +183,7 @@ static s32 USB2Storage_Open(int verbose) return ret; } -static void USB2Storage_Close() +void USB2Storage_Close() { if(__usb2fd <= 0) return; @@ -225,28 +219,18 @@ void USB2Enable(bool enable) static bool __usb2storage_Startup(void) { - if(__usb2fd > 0) - return true; - - USB2Storage_Open(0); + if(USB2Storage_Open() < 0) + return false; if(__usb2fd > 0) - { - currentMode = 2; return true; - } - if(__io_usb1storage.startup()) - { - currentMode = 1; - return true; - } return false; } static bool __usb2storage_IsInserted(void) { - if (!__usb2storage_Startup()) + if (USB2Storage_Open() < 0) return false; if(usb2_mutex == LWP_MUTEX_NULL) @@ -257,17 +241,11 @@ static bool __usb2storage_IsInserted(void) LWP_MutexLock(usb2_mutex); int retval = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_IS_INSERTED, ":"); LWP_MutexUnlock(usb2_mutex); - debug_printf("isinserted usb2 retval: %d ret: %d\n",retval,ret); + debug_printf("isinserted usb2 retval: %d \n",retval); if (retval > 0) return true; } - - if (__io_usb1storage.isInserted() > 0) - { - debug_printf("isinserted usb1 retval: %d\n",retval); - return true; - } return false; } @@ -277,9 +255,6 @@ static bool __usb2storage_ReadSectors(u32 sector, u32 numSectors, void *buffer) u32 sectors = 0; uint8_t *dest = buffer; - if (currentMode == 1) - return __io_usb1storage.readSectors(sector, numSectors, buffer); - if (__usb2fd < 1 || usb2_mutex == LWP_MUTEX_NULL) return false; @@ -320,9 +295,6 @@ static bool __usb2storage_WriteSectors(u32 sector, u32 numSectors, const void *b u32 sectors = 0; uint8_t *dest = (uint8_t *) buffer; - if (currentMode == 1) - return __io_usb1storage.writeSectors(sector, numSectors, buffer); - if (__usb2fd < 1 || usb2_mutex == LWP_MUTEX_NULL) return false; @@ -358,20 +330,26 @@ static bool __usb2storage_WriteSectors(u32 sector, u32 numSectors, const void *b static bool __usb2storage_ClearStatus(void) { - if (currentMode == 1) - return __io_usb1storage.clearStatus(); - return true; } static bool __usb2storage_Shutdown(void) { - if (currentMode == 1) - return __io_usb1storage.shutdown(); - return true; } +void SetUSB2Mode(int mode) +{ + USB2Storage_Initialize(); + IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_USB_MODE, "b:",(u8)mode); +} + +int GetUSB2LanPort() +{ + USB2Storage_Initialize(); + return IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_GET_USBLAN_PORT, ":"); +} + const DISC_INTERFACE __io_usb2storage = { DEVICE_TYPE_WII_USB, FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB, diff --git a/source/utils/usb2storage.h b/source/utils/usb2storage.h index b6b9eb9..d7bed91 100644 --- a/source/utils/usb2storage.h +++ b/source/utils/usb2storage.h @@ -15,6 +15,13 @@ #endif void USB2Enable(bool e); +void USB2Storage_Close(); +int GetUSB2LanPort(); +void SetUSB2Mode(int mode); +//mode 0: port0 disabled & port1 disabled +//mode 1: port0 enabled & port1 disabled +//mode 2: port0 disabled & port1 enabled +//mode 3: port0 enabled & port1 enabled #ifdef __cplusplus }