updated usb2 support (now supports both ports). requires new cIOS 202. freetypegx optimization.

This commit is contained in:
dborth 2010-07-06 06:39:15 +00:00
parent b330107e8d
commit c162af659e
7 changed files with 209 additions and 210 deletions

View File

@ -252,6 +252,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
@ -318,6 +343,8 @@ main(int argc, char *argv[])
#endif
#ifdef HW_RVL
bool usblan = USBLANDetected();
// try to load IOS 202
if(FindIOS(202))
IOS_ReloadIOS(202);
@ -326,12 +353,34 @@ main(int argc, char *argv[])
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

View File

@ -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;
}
/**

Binary file not shown.

View File

@ -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 <stdio.h>
@ -22,25 +22,15 @@
#include <string.h>
#include <ogcsys.h>
#include <gccore.h>
#include <ogc/ipc.h>
#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;
}

View File

@ -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

View File

@ -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,

View File

@ -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
}