Started implementing code for new3ds mvd. Added osConvertOldLINEARMemToNew().
This commit is contained in:
parent
d95e95cf13
commit
6d2a0f5fa3
@ -25,6 +25,7 @@ extern "C" {
|
|||||||
#include <3ds/services/ptm.h>
|
#include <3ds/services/ptm.h>
|
||||||
#include <3ds/services/soc.h>
|
#include <3ds/services/soc.h>
|
||||||
#include <3ds/services/mic.h>
|
#include <3ds/services/mic.h>
|
||||||
|
#include <3ds/services/mvd.h>
|
||||||
|
|
||||||
#include <3ds/gpu/gx.h>
|
#include <3ds/gpu/gx.h>
|
||||||
#include <3ds/gpu/gpu.h>
|
#include <3ds/gpu/gpu.h>
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
(((major)<<24)|((minor)<<16)|((revision)<<8))
|
(((major)<<24)|((minor)<<16)|((revision)<<8))
|
||||||
|
|
||||||
u32 osConvertVirtToPhys(u32 vaddr);
|
u32 osConvertVirtToPhys(u32 vaddr);
|
||||||
|
u32 osConvertOldLINEARMemToNew(u32 addr);//Converts 0x14* vmem to 0x30*. Returns the input addr when it's already within the new vmem. Returns 0 when outside of either LINEAR mem areas.
|
||||||
const char* osStrError(u32 error);
|
const char* osStrError(u32 error);
|
||||||
u32 osGetFirmVersion();
|
u32 osGetFirmVersion();
|
||||||
u32 osGetKernelVersion();
|
u32 osGetKernelVersion();
|
||||||
|
36
libctru/include/3ds/services/mvd.h
Normal file
36
libctru/include/3ds/services/mvd.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
//New3DS-only, see also: http://3dbrew.org/wiki/MVD_Services
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MVDTYPE_COLORFORMATCONV = 0x00010001,
|
||||||
|
MVDTYPE_H264 = 0x00020001
|
||||||
|
} mvdstdType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mvdstdType type;
|
||||||
|
u32 unk_x04;
|
||||||
|
u32 unk_x08;
|
||||||
|
u32 width0, height0;
|
||||||
|
u32 physaddr_colorconv_indata;
|
||||||
|
u32 unk_x18[0x28>>2];
|
||||||
|
u32 flag_x40;//0x0 for colorconv, 0x1 for H.264
|
||||||
|
u32 unk_x44;
|
||||||
|
u32 unk_x48;
|
||||||
|
u32 height1, width1;//Only set for H.264.
|
||||||
|
u32 unk_x54;
|
||||||
|
u32 unk_x58;
|
||||||
|
u32 width2, height2;
|
||||||
|
u32 physaddr_outdata0;
|
||||||
|
u32 physaddr_outdata1_colorconv;
|
||||||
|
u32 unk_x6c[0xb0>>2];
|
||||||
|
} mvdstdConfig;
|
||||||
|
|
||||||
|
void mvdstdGenerateDefaultConfig(mvdstdConfig *config, u32 width, u32 height, u32 *vaddr_colorconv_indata, u32 *vaddr_outdata0, u32 *vaddr_outdata1_colorconv);
|
||||||
|
|
||||||
|
Result mvdstdInit(mvdstdType type, u32 size);//The input size isn't used when type==MVDTYPE_COLORFORMATCONV. H.264 isn't supported currently.
|
||||||
|
Result mvdstdShutdown();
|
||||||
|
|
||||||
|
Result mvdstdSetConfig(mvdstdConfig *config);
|
||||||
|
Result mvdstdProcessFrame(mvdstdConfig *config, u32 *h264_vaddr_inframe, u32 h264_inframesize, u32 h264_frameid);
|
||||||
|
|
@ -29,6 +29,13 @@ u32 osConvertVirtToPhys(u32 vaddr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 osConvertOldLINEARMemToNew(u32 vaddr)
|
||||||
|
{
|
||||||
|
if(vaddr >= 0x30000000 && vaddr < 0x40000000)return vaddr;
|
||||||
|
if(vaddr >= 0x14000000 && vaddr < 0x1c000000)return vaddr+=0x1c000000;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns number of milliseconds since 1st Jan 1900 00:00.
|
// Returns number of milliseconds since 1st Jan 1900 00:00.
|
||||||
u64 osGetTime() {
|
u64 osGetTime() {
|
||||||
volatile datetime_t* dt;
|
volatile datetime_t* dt;
|
||||||
|
197
libctru/source/services/mvd.c
Normal file
197
libctru/source/services/mvd.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
mvd.c - code for using this: http://3dbrew.org/wiki/MVD_Services
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
|
Handle mvdstdHandle;
|
||||||
|
static u32 mvdstdInitialized = 0;
|
||||||
|
static mvdstdType mvdstd_type;
|
||||||
|
static u32 *mvdstd_workbuf = NULL;
|
||||||
|
static size_t mvdstd_workbufsize = 0;
|
||||||
|
|
||||||
|
static Result mvdstdipc_Initialize(u32 *buf, u32 bufsize, Handle kprocess)
|
||||||
|
{
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = 0x00010082; //request header code
|
||||||
|
cmdbuf[1] = (u32)buf;
|
||||||
|
cmdbuf[2] = bufsize;
|
||||||
|
cmdbuf[3] = 0;
|
||||||
|
cmdbuf[4] = kprocess;
|
||||||
|
|
||||||
|
Result ret=0;
|
||||||
|
if((ret=svcSendSyncRequest(mvdstdHandle)))return ret;
|
||||||
|
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result mvdstdipc_Shutdown()
|
||||||
|
{
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = 0x00020000; //request header code
|
||||||
|
|
||||||
|
Result ret=0;
|
||||||
|
if((ret = svcSendSyncRequest(mvdstdHandle)))return ret;
|
||||||
|
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result mvdstdipc_cmd18()
|
||||||
|
{
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = 0x00180000; //request header code
|
||||||
|
|
||||||
|
Result ret=0;
|
||||||
|
if((ret=svcSendSyncRequest(mvdstdHandle)))return ret;
|
||||||
|
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result mvdstdipc_cmd19()
|
||||||
|
{
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = 0x00190000; //request header code
|
||||||
|
|
||||||
|
Result ret=0;
|
||||||
|
if((ret=svcSendSyncRequest(mvdstdHandle)))return ret;
|
||||||
|
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result mvdstdipc_cmd1a()
|
||||||
|
{
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = 0x001A0000; //request header code
|
||||||
|
|
||||||
|
Result ret=0;
|
||||||
|
if((ret=svcSendSyncRequest(mvdstdHandle)))return ret;
|
||||||
|
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result mvdstdSetConfig(mvdstdConfig *config)
|
||||||
|
{
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = 0x001E0044; //request header code
|
||||||
|
cmdbuf[1] = sizeof(mvdstdConfig);
|
||||||
|
cmdbuf[2] = 0;
|
||||||
|
cmdbuf[3] = 0xffff8001;
|
||||||
|
cmdbuf[4] = (sizeof(mvdstdConfig)<<4) | 10;
|
||||||
|
cmdbuf[5] = (u32)config;
|
||||||
|
|
||||||
|
Result ret=0;
|
||||||
|
if((ret=svcSendSyncRequest(mvdstdHandle)))return ret;
|
||||||
|
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void mvdstdGenerateDefaultConfig(mvdstdConfig *config, u32 width, u32 height, u32 *vaddr_colorconv_indata, u32 *vaddr_outdata0, u32 *vaddr_outdata1_colorconv)
|
||||||
|
{
|
||||||
|
memset(config, 0, sizeof(mvdstdConfig));
|
||||||
|
|
||||||
|
config->type = mvdstd_type;
|
||||||
|
|
||||||
|
config->width0 = width;
|
||||||
|
config->height0 = height;
|
||||||
|
|
||||||
|
if(mvdstd_type==MVDTYPE_COLORFORMATCONV)config->physaddr_colorconv_indata = osConvertVirtToPhys((u32)vaddr_colorconv_indata);
|
||||||
|
|
||||||
|
if(mvdstd_type==MVDTYPE_H264)
|
||||||
|
{
|
||||||
|
config->flag_x40 = 1;
|
||||||
|
config->height1 = height;
|
||||||
|
config->width1 = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->unk_x58 = 0x40002;
|
||||||
|
|
||||||
|
config->width2 = width;
|
||||||
|
config->height2 = height;
|
||||||
|
|
||||||
|
config->physaddr_outdata0 = osConvertVirtToPhys((u32)vaddr_outdata0);
|
||||||
|
if(mvdstd_type==MVDTYPE_COLORFORMATCONV)config->physaddr_outdata1_colorconv = osConvertVirtToPhys((u32)vaddr_outdata1_colorconv);
|
||||||
|
|
||||||
|
config->unk_x6c[0] = 0x1;
|
||||||
|
config->unk_x6c[(0x84-0x6c)>>2] = 0x12a;
|
||||||
|
config->unk_x6c[(0x88-0x6c)>>2] = 0x199;
|
||||||
|
config->unk_x6c[(0x8c-0x6c)>>2] = 0xd0;
|
||||||
|
config->unk_x6c[(0x90-0x6c)>>2] = 0x64;
|
||||||
|
config->unk_x6c[(0x94-0x6c)>>2] = 0x204;
|
||||||
|
config->unk_x6c[(0xa8-0x6c)>>2] = 0x1;
|
||||||
|
config->unk_x6c[(0x104-0x6c)>>2] = 0x1;
|
||||||
|
config->unk_x6c[(0x110-0x6c)>>2] = 0x200;
|
||||||
|
config->unk_x6c[(0x114-0x6c)>>2] = 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result mvdstdInit(mvdstdType type, u32 size)
|
||||||
|
{
|
||||||
|
Result ret=0;
|
||||||
|
|
||||||
|
if(mvdstdInitialized)return 0;
|
||||||
|
|
||||||
|
mvdstd_workbufsize = size;
|
||||||
|
mvdstd_type = type;
|
||||||
|
|
||||||
|
if(type==MVDTYPE_COLORFORMATCONV)mvdstd_workbufsize = 1;
|
||||||
|
if(type!=MVDTYPE_COLORFORMATCONV)return -2;//H264 isn't supported atm.
|
||||||
|
|
||||||
|
if((ret=srvGetServiceHandle(&mvdstdHandle, "mvd:STD")))return ret;
|
||||||
|
|
||||||
|
mvdstd_workbuf = linearAlloc(mvdstd_workbufsize);
|
||||||
|
if(mvdstd_workbuf==NULL)return -1;
|
||||||
|
|
||||||
|
ret = mvdstdipc_Initialize((u32*)osConvertOldLINEARMemToNew((u32)mvdstd_workbuf), mvdstd_workbufsize, 0xffff8001);
|
||||||
|
if(ret<0)
|
||||||
|
{
|
||||||
|
svcCloseHandle(mvdstdHandle);
|
||||||
|
linearFree(mvdstd_workbuf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mvdstdipc_cmd18();
|
||||||
|
if(ret<0)
|
||||||
|
{
|
||||||
|
mvdstdipc_Shutdown();
|
||||||
|
svcCloseHandle(mvdstdHandle);
|
||||||
|
linearFree(mvdstd_workbuf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mvdstdInitialized = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result mvdstdShutdown()
|
||||||
|
{
|
||||||
|
if(!mvdstdInitialized)return 0;
|
||||||
|
|
||||||
|
if(mvdstd_type==MVDTYPE_COLORFORMATCONV)
|
||||||
|
{
|
||||||
|
mvdstdipc_cmd19();
|
||||||
|
}
|
||||||
|
|
||||||
|
mvdstdipc_Shutdown();
|
||||||
|
|
||||||
|
svcCloseHandle(mvdstdHandle);
|
||||||
|
|
||||||
|
linearFree(mvdstd_workbuf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result mvdstdProcessFrame(mvdstdConfig *config, u32 *h264_vaddr_inframe, u32 h264_inframesize, u32 h264_frameid)
|
||||||
|
{
|
||||||
|
Result ret;
|
||||||
|
|
||||||
|
if(config==NULL)return -1;
|
||||||
|
if(mvdstd_type!=MVDTYPE_COLORFORMATCONV)return -2;
|
||||||
|
|
||||||
|
ret = mvdstdSetConfig(config);
|
||||||
|
if(ret<0)return ret;
|
||||||
|
|
||||||
|
return mvdstdipc_cmd1a();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user