Merge pull request #714 from reicast/wip/nacl-and-emscripten

NaCL & Emscripten targets

- CPU_GENERIC
- TARGET_NO_THREADS
- TARGET_NO_NIXPROF
- TARGET_NO_EXCEPTIONS
- TARGET_NO_NVMEM
- TARGET_BOUNDED_EXECUTION
- TARGET_NO_COREIO_HTTP
This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2015-08-03 11:28:29 +02:00
commit 0343feffa6
32 changed files with 1263 additions and 139 deletions

View File

@ -140,6 +140,7 @@
#define CPU_ARM 0x20000002 #define CPU_ARM 0x20000002
#define CPU_MIPS 0x20000003 #define CPU_MIPS 0x20000003
#define CPU_X64 0x20000004 #define CPU_X64 0x20000004
#define CPU_GENERIC 0x20000005 //used for pnacl, emscripten, etc
//BUILD_COMPILER //BUILD_COMPILER
#define COMPILER_VC 0x30000001 #define COMPILER_VC 0x30000001
@ -192,9 +193,9 @@
#elif defined(TARGET_GCW0) #elif defined(TARGET_GCW0)
#define HOST_OS OS_LINUX #define HOST_OS OS_LINUX
#define HOST_CPU CPU_MIPS #define HOST_CPU CPU_MIPS
#elif defined(TARGET_NACL32) #elif defined(TARGET_NACL32) || defined(TARGET_EMSCRIPTEN)
#define HOST_OS OS_LINUX #define HOST_OS OS_LINUX
#define HOST_CPU CPU_X86 #define HOST_CPU CPU_GENERIC
#elif defined(TARGET_IPHONE) #elif defined(TARGET_IPHONE)
#define HOST_OS OS_DARWIN #define HOST_OS OS_DARWIN
#define HOST_CPU CPU_ARM #define HOST_CPU CPU_ARM
@ -220,6 +221,15 @@
#define FEAT_DSPREC DYNAREC_NONE #define FEAT_DSPREC DYNAREC_NONE
#endif #endif
#if defined(TARGET_NO_NIXPROF)
#define FEAT_HAS_NIXPROF 0
#endif
#if defined(TARGET_NO_COREIO_HTTP)
#define FEAT_HAS_COREIO_HTTP 0
#endif
//defaults //defaults
#ifndef FEAT_SHREC #ifndef FEAT_SHREC
#define FEAT_SHREC DYNAREC_JIT #define FEAT_SHREC DYNAREC_JIT
@ -241,6 +251,16 @@
#endif #endif
#endif #endif
#ifndef FEAT_HAS_NIXPROF
#if HOST_OS != OS_WINDOWS
#define FEAT_HAS_NIXPROF 1
#endif
#endif
#ifndef FEAT_HAS_COREIO_HTTP
#define FEAT_HAS_COREIO_HTTP 1
#endif
//Depricated build configs //Depricated build configs
#ifdef HOST_NO_REC #ifdef HOST_NO_REC
#error Dont use HOST_NO_REC #error Dont use HOST_NO_REC

View File

@ -47,6 +47,10 @@ else
RZDCY_MODULES += rend/norend/ RZDCY_MODULES += rend/norend/
endif endif
ifndef NO_NIXPROF
RZDCY_MODULES += linux/nixprof/
endif
ifdef FOR_ANDROID ifdef FOR_ANDROID
RZDCY_MODULES += android/ deps/libandroid/ deps/libzip/ RZDCY_MODULES += android/ deps/libandroid/ deps/libzip/
endif endif

View File

@ -13,20 +13,24 @@
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
#pragma comment (lib, "wsock32.lib")
#include <string> #include <string>
#include <sstream> #include <sstream>
#if HOST_OS == OS_LINUX || HOST_OS == OS_DARWIN #if FEAT_HAS_COREIO_HTTP
#if HOST_OS == OS_LINUX
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netdb.h> #include <netdb.h>
#include <unistd.h> #include <unistd.h>
#else
#pragma comment (lib, "wsock32.lib")
#endif
#endif #endif
#if FEAT_HAS_COREIO_HTTP
string url_encode(const string &value) { string url_encode(const string &value) {
ostringstream escaped; ostringstream escaped;
escaped.fill('0'); escaped.fill('0');
@ -186,6 +190,7 @@ _data:
return rv; return rv;
} }
#endif
struct CORE_FILE { struct CORE_FILE {
FILE* f; FILE* f;
@ -203,7 +208,7 @@ core_file* core_fopen(const char* filename)
CORE_FILE* rv = new CORE_FILE(); CORE_FILE* rv = new CORE_FILE();
rv->f = 0; rv->f = 0;
rv->path = p; rv->path = p;
#if FEAT_HAS_COREIO_HTTP
if (p.substr(0,7)=="http://") { if (p.substr(0,7)=="http://") {
rv->host = p.substr(7,p.npos); rv->host = p.substr(7,p.npos);
rv->host = rv->host.substr(0, rv->host.find_first_of("/")); rv->host = rv->host.substr(0, rv->host.find_first_of("/"));
@ -217,7 +222,9 @@ core_file* core_fopen(const char* filename)
rv->host = rv->host.substr(0, rv->host.find_first_of(":")); rv->host = rv->host.substr(0, rv->host.find_first_of(":"));
sscanf(port.c_str(),"%d",&rv->port); sscanf(port.c_str(),"%d",&rv->port);
} }
} else { } else
#endif
{
rv->f = fopen(filename, "rb"); rv->f = fopen(filename, "rb");
if (!rv->f) { if (!rv->f) {
@ -257,7 +264,9 @@ int core_fread(core_file* fc, void* buff, size_t len)
if (f->f) { if (f->f) {
fread(buff,1,len,f->f); fread(buff,1,len,f->f);
} else { } else {
#if FEAT_HAS_COREIO_HTTP
HTTP_GET(f->host, f->port, f->path, f->seek_ptr, len, buff); HTTP_GET(f->host, f->port, f->path, f->seek_ptr, len, buff);
#endif
} }
f->seek_ptr += len; f->seek_ptr += len;
@ -293,6 +302,8 @@ size_t core_fsize(core_file* fc)
return rv; return rv;
} }
else { else {
#if FEAT_HAS_COREIO_HTTP
return HTTP_GET(f->host, f->port, f->path, 0, 0,0); return HTTP_GET(f->host, f->port, f->path, 0, 0,0);
#endif
} }
} }

View File

@ -393,7 +393,7 @@ void _vmem_term()
#include "hw/pvr/pvr_mem.h" #include "hw/pvr/pvr_mem.h"
#include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_mem.h"
#ifndef TARGET_NACL32 #if !defined(TARGET_NO_NVMEM)
#define MAP_RAM_START_OFFSET 0 #define MAP_RAM_START_OFFSET 0
#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) #define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE)
@ -581,8 +581,12 @@ void _vmem_bm_pagefail(void** ptr,u32 PAGE_SZ);
u32 pagecnt; u32 pagecnt;
void _vmem_bm_reset() void _vmem_bm_reset()
{ {
#if HOST_OS == OS_DARWIN #if defined(TARGET_NO_NVMEM)
//On iOS we allways allocate all of the mapping table return;
#endif
#if (HOST_OS == OS_DARWIN)
//On iOS & nacl we allways allocate all of the mapping table
mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_READ | PROT_WRITE); mprotect(p_sh4rcb, sizeof(p_sh4rcb->fpcb), PROT_READ | PROT_WRITE);
return; return;
#endif #endif
@ -726,16 +730,27 @@ bool _vmem_reserve()
} }
#else #else
void* malloc_pages(size_t size) {
u8* rv = (u8*)malloc(size + PAGE_SIZE);
return rv + PAGE_SIZE - ((unat)rv % PAGE_SIZE);
}
bool _vmem_reserve() bool _vmem_reserve()
{ {
p_sh4rcb=(Sh4RCB*)malloc_pages(sizeof(Sh4RCB));
mem_b.size=RAM_SIZE; mem_b.size=RAM_SIZE;
mem_b.data=(u8*)malloc(RAM_SIZE); mem_b.data=(u8*)malloc_pages(RAM_SIZE);
vram.size=VRAM_SIZE; vram.size=VRAM_SIZE;
vram.data=(u8*)malloc(VRAM_SIZE); vram.data=(u8*)malloc_pages(VRAM_SIZE);
aica_ram.size=ARAM_SIZE; aica_ram.size=ARAM_SIZE;
aica_ram.data=(u8*)malloc(ARAM_SIZE); aica_ram.data=(u8*)malloc_pages(ARAM_SIZE);
return true;
} }
#endif #endif

View File

@ -66,8 +66,11 @@ u32 VertexCount=0;
u32 FrameCount=1; u32 FrameCount=1;
Renderer* renderer; Renderer* renderer;
#if !defined(TARGET_NO_THREADS)
cResetEvent rs(false,true); cResetEvent rs(false,true);
cResetEvent re(false,true); cResetEvent re(false,true);
#endif
int max_idx,max_mvo,max_op,max_pt,max_tr,max_vtx,max_modt, ovrn; int max_idx,max_mvo,max_op,max_pt,max_tr,max_vtx,max_modt, ovrn;
@ -184,7 +187,9 @@ TA_context* read_frame(const char* file, u8* vram_ref) {
bool rend_frame(TA_context* ctx, bool draw_osd) { bool rend_frame(TA_context* ctx, bool draw_osd) {
bool proc = renderer->Process(ctx); bool proc = renderer->Process(ctx);
#if !defined(TARGET_NO_THREADS)
re.Set(); re.Set();
#endif
bool do_swp = proc && renderer->Render(); bool do_swp = proc && renderer->Render();
@ -199,11 +204,12 @@ bool rend_single_frame()
//wait render start only if no frame pending //wait render start only if no frame pending
do do
{ {
#if !defined(TARGET_NO_THREADS)
rs.Wait(); rs.Wait();
#endif
_pvrrc = DequeueRender(); _pvrrc = DequeueRender();
} }
while (!_pvrrc); while (!_pvrrc);
bool do_swp = rend_frame(_pvrrc, true); bool do_swp = rend_frame(_pvrrc, true);
//clear up & free data .. //clear up & free data ..
@ -256,8 +262,9 @@ void* rend_thread(void* p)
} }
} }
#if !defined(TARGET_NO_THREADS)
cThread rthd(rend_thread,0); cThread rthd(rend_thread,0);
#endif
bool pend_rend = false; bool pend_rend = false;
@ -301,7 +308,11 @@ void rend_start_render()
#endif #endif
if (QueueRender(ctx)) { if (QueueRender(ctx)) {
palette_update(); palette_update();
#if !defined(TARGET_NO_THREADS)
rs.Set(); rs.Set();
#else
rend_single_frame();
#endif
pend_rend = true; pend_rend = true;
} }
} }
@ -325,8 +336,13 @@ void rend_end_render()
#endif #endif
#endif #endif
if (pend_rend) if (pend_rend) {
#if !defined(TARGET_NO_THREADS)
re.Wait(); re.Wait();
#else
renderer->Present();
#endif
}
} }
/* /*
@ -356,7 +372,13 @@ bool rend_init()
#endif #endif
#if !defined(_ANDROID) && HOST_OS != OS_DARWIN #if !defined(_ANDROID) && HOST_OS != OS_DARWIN
#if !defined(TARGET_NO_THREADS)
rthd.Start(); rthd.Start();
#else
if (!renderer->Init()) die("rend->init() failed\n");
renderer->Resize(640, 480);
#endif
#endif #endif
#if SET_AFNT #if SET_AFNT

View File

@ -20,20 +20,20 @@ static TaListFP* ta_poly_data_lut[15] =
//32/64b , full //32/64b , full
static TaPolyParamFP* ta_poly_param_lut[5]= static TaPolyParamFP* ta_poly_param_lut[5]=
{ {
(TaPolyParamFP*)AppendPolyParam0, AppendPolyParam0,
(TaPolyParamFP*)AppendPolyParam1, AppendPolyParam1,
(TaPolyParamFP*)AppendPolyParam2Full, AppendPolyParam2Full,
(TaPolyParamFP*)AppendPolyParam3, AppendPolyParam3,
(TaPolyParamFP*)AppendPolyParam4Full AppendPolyParam4Full
}; };
//64b , first part //64b , first part
static TaPolyParamFP* ta_poly_param_a_lut[5]= static TaPolyParamFP* ta_poly_param_a_lut[5]=
{ {
(TaPolyParamFP*)0, (TaPolyParamFP*)0,
(TaPolyParamFP*)0, (TaPolyParamFP*)0,
(TaPolyParamFP*)AppendPolyParam2A, AppendPolyParam2A,
(TaPolyParamFP*)0, (TaPolyParamFP*)0,
(TaPolyParamFP*)AppendPolyParam4A AppendPolyParam4A
}; };
//64b , , second part //64b , , second part
@ -41,7 +41,7 @@ static TaListFP* ta_poly_param_b_lut[5]=
{ {
(TaListFP*)0, (TaListFP*)0,
(TaListFP*)0, (TaListFP*)0,
(TaListFP*)ta_poly_B_32<2>, ta_poly_B_32<2>,
(TaListFP*)0, (TaListFP*)0,
(TaListFP*)ta_poly_B_32<4> ta_poly_B_32<4>
}; };

View File

@ -113,6 +113,14 @@ TA_context* DequeueRender()
return rv; return rv;
} }
bool rend_framePending() {
mtx_rqueue.Lock();
TA_context* rv = rqueue;
mtx_rqueue.Unlock();
return rv != 0;
}
void FinishRender(TA_context* ctx) void FinishRender(TA_context* ctx)
{ {
verify(rqueue == ctx); verify(rqueue == ctx);

View File

@ -111,7 +111,7 @@ const u32 SZ64=2;
#include "ta_structs.h" #include "ta_structs.h"
typedef Ta_Dma* DYNACALL TaListFP(Ta_Dma* data,Ta_Dma* data_end); typedef Ta_Dma* DYNACALL TaListFP(Ta_Dma* data,Ta_Dma* data_end);
typedef u32 TACALL TaPolyParamFP(void* ptr); typedef void TACALL TaPolyParamFP(void* ptr);
//#define TaCmd ((TaListFP*&)sh4rcb.tacmd_void) //#define TaCmd ((TaListFP*&)sh4rcb.tacmd_void)
TaListFP* TaCmd; TaListFP* TaCmd;
@ -351,14 +351,18 @@ strip_end:
return data+poly_size; return data+poly_size;
} }
static void TACALL AppendPolyParam2Full(Ta_Dma* pp) static void TACALL AppendPolyParam2Full(void* vpp)
{ {
Ta_Dma* pp=(Ta_Dma*)vpp;
AppendPolyParam2A((TA_PolyParam2A*)&pp[0]); AppendPolyParam2A((TA_PolyParam2A*)&pp[0]);
AppendPolyParam2B((TA_PolyParam2B*)&pp[1]); AppendPolyParam2B((TA_PolyParam2B*)&pp[1]);
} }
static void TACALL AppendPolyParam4Full(Ta_Dma* pp) static void TACALL AppendPolyParam4Full(void* vpp)
{ {
Ta_Dma* pp=(Ta_Dma*)vpp;
AppendPolyParam4A((TA_PolyParam4A*)&pp[0]); AppendPolyParam4A((TA_PolyParam4A*)&pp[0]);
AppendPolyParam4B((TA_PolyParam4B*)&pp[1]); AppendPolyParam4B((TA_PolyParam4B*)&pp[1]);
} }
@ -390,6 +394,7 @@ public:
//32Bw3 //32Bw3
case ParamType_End_Of_List: case ParamType_End_Of_List:
{ {
if (CurrentList==ListType_None) if (CurrentList==ListType_None)
{ {
CurrentList=data->pcw.ListType; CurrentList=data->pcw.ListType;
@ -412,16 +417,17 @@ public:
//32B //32B
case ParamType_User_Tile_Clip: case ParamType_User_Tile_Clip:
{ {
SetTileClip(data->data_32[3]&63,data->data_32[4]&31,data->data_32[5]&63,data->data_32[6]&31); SetTileClip(data->data_32[3]&63,data->data_32[4]&31,data->data_32[5]&63,data->data_32[6]&31);
//*cough* ignore it :p
data+=SZ32; data+=SZ32;
} }
break; break;
//32B //32B
case ParamType_Object_List_Set: case ParamType_Object_List_Set:
{ {
die("ParamType_Object_List_Set"); die("ParamType_Object_List_Set");
//*cough* ignore it :p // *cough* ignore it :p
data+=SZ32; data+=SZ32;
} }
break; break;
@ -431,6 +437,7 @@ public:
//PolyType :32B/64B //PolyType :32B/64B
case ParamType_Polygon_or_Modifier_Volume: case ParamType_Polygon_or_Modifier_Volume:
{ {
TA_PP; TA_PP;
group_EN(); group_EN();
//Yep , C++ IS lame & limited //Yep , C++ IS lame & limited
@ -458,12 +465,14 @@ public:
if (data != data_end || psz==1) if (data != data_end || psz==1)
{ {
//poly , 32B/64B //poly , 32B/64B
ta_poly_param_lut[ppid](data); ta_poly_param_lut[ppid](data);
data+=psz; data+=psz;
} }
else else
{ {
//AppendPolyParam64A((TA_PolyParamA*)data); //AppendPolyParam64A((TA_PolyParamA*)data);
//64b , first part //64b , first part
ta_poly_param_a_lut[ppid](data); ta_poly_param_a_lut[ppid](data);
@ -478,6 +487,7 @@ public:
//Sets Sprite info , and switches to ta_sprite_data function //Sets Sprite info , and switches to ta_sprite_data function
case ParamType_Sprite: case ParamType_Sprite:
{ {
TA_SP; TA_SP;
group_EN(); group_EN();
if (CurrentList==ListType_None) if (CurrentList==ListType_None)
@ -494,6 +504,7 @@ public:
case ParamType_Vertex_Parameter: case ParamType_Vertex_Parameter:
//log ("vtx"); //log ("vtx");
{ {
//printf("VTX:0x%08X\n",VerxexDataFP); //printf("VTX:0x%08X\n",VerxexDataFP);
//verify(VerxexDataFP!=NullVertexData); //verify(VerxexDataFP!=NullVertexData);
data=VerxexDataFP(data,data_end); data=VerxexDataFP(data,data_end);
@ -817,40 +828,54 @@ public:
//poly param handling //poly param handling
__forceinline __forceinline
static void TACALL AppendPolyParam0(TA_PolyParam0* pp) static void TACALL AppendPolyParam0(void* vpp)
{ {
TA_PolyParam0* pp=(TA_PolyParam0*)vpp;
glob_param_bdc(pp); glob_param_bdc(pp);
} }
__forceinline __forceinline
static void TACALL AppendPolyParam1(TA_PolyParam1* pp) static void TACALL AppendPolyParam1(void* vpp)
{ {
TA_PolyParam1* pp=(TA_PolyParam1*)vpp;
glob_param_bdc(pp); glob_param_bdc(pp);
poly_float_color(FaceBaseColor,FaceColor); poly_float_color(FaceBaseColor,FaceColor);
} }
__forceinline __forceinline
static void TACALL AppendPolyParam2A(TA_PolyParam2A* pp) static void TACALL AppendPolyParam2A(void* vpp)
{ {
TA_PolyParam2A* pp=(TA_PolyParam2A*)vpp;
glob_param_bdc(pp); glob_param_bdc(pp);
} }
__forceinline __forceinline
static void TACALL AppendPolyParam2B(TA_PolyParam2B* pp) static void TACALL AppendPolyParam2B(void* vpp)
{ {
TA_PolyParam2B* pp=(TA_PolyParam2B*)vpp;
poly_float_color(FaceBaseColor,FaceColor); poly_float_color(FaceBaseColor,FaceColor);
poly_float_color(FaceOffsColor,FaceOffset); poly_float_color(FaceOffsColor,FaceOffset);
} }
__forceinline __forceinline
static void TACALL AppendPolyParam3(TA_PolyParam3* pp) static void TACALL AppendPolyParam3(void* vpp)
{ {
TA_PolyParam3* pp=(TA_PolyParam3*)vpp;
glob_param_bdc(pp); glob_param_bdc(pp);
} }
__forceinline __forceinline
static void TACALL AppendPolyParam4A(TA_PolyParam4A* pp) static void TACALL AppendPolyParam4A(void* vpp)
{ {
TA_PolyParam4A* pp=(TA_PolyParam4A*)vpp;
glob_param_bdc(pp); glob_param_bdc(pp);
} }
__forceinline __forceinline
static void TACALL AppendPolyParam4B(TA_PolyParam4B* pp) static void TACALL AppendPolyParam4B(void* vpp)
{ {
TA_PolyParam4B* pp=(TA_PolyParam4B*)vpp;
poly_float_color(FaceBaseColor,FaceColor0); poly_float_color(FaceBaseColor,FaceColor0);
} }
@ -1419,7 +1444,6 @@ bool ta_parse_vdrc(TA_context* ctx)
vd_rc = vd_ctx->rend; vd_rc = vd_ctx->rend;
ta_parse_cnt++; ta_parse_cnt++;
if (0 == (ta_parse_cnt % ( settings.pvr.ta_skip + 1))) if (0 == (ta_parse_cnt % ( settings.pvr.ta_skip + 1)))
{ {
TAFifo0.vdec_init(); TAFifo0.vdec_init();
@ -1430,6 +1454,7 @@ bool ta_parse_vdrc(TA_context* ctx)
do do
{ {
ta_data =TaCmd(ta_data,ta_data_end); ta_data =TaCmd(ta_data,ta_data_end);
} }
while(ta_data<=ta_data_end); while(ta_data<=ta_data_end);

View File

@ -380,9 +380,11 @@ void bm_Reset()
blocks_page[i].clear(); blocks_page[i].clear();
} }
#if !defined(TARGET_NO_NVMEM)
_vmem_bm_reset(); _vmem_bm_reset();
#endif
#if HOST_OS == OS_DARWIN #if (HOST_OS == OS_DARWIN) || defined(TARGET_NO_NVMEM)
//lazy allocation isn't working on iOS //lazy allocation isn't working on iOS
for (u32 i=0;i<(8*1024*1024);i++) for (u32 i=0;i<(8*1024*1024);i++)
{ {

View File

@ -88,7 +88,9 @@ void recSh4_Run()
verify(rcb_noffs(&next_pc)==-184); verify(rcb_noffs(&next_pc)==-184);
ngen_mainloop(sh4_dyna_rcb); ngen_mainloop(sh4_dyna_rcb);
#if !defined(TARGET_BOUNDED_EXECUTION)
sh4_int_bCpuRun=false; sh4_int_bCpuRun=false;
#endif
} }
void emit_Write32(u32 data) void emit_Write32(u32 data)
@ -415,8 +417,9 @@ void recSh4_Init()
verify(rcb_noffs(&p_sh4rcb->cntx.sh4_sched_next) == -152); verify(rcb_noffs(&p_sh4rcb->cntx.sh4_sched_next) == -152);
verify(rcb_noffs(&p_sh4rcb->cntx.interrupt_pend) == -148); verify(rcb_noffs(&p_sh4rcb->cntx.interrupt_pend) == -148);
#if !defined(TARGET_NO_NVMEM)
verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x0C000000)); verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x0C000000));
#endif
//align to next page .. //align to next page ..
CodeCache = (u8*)(((unat)SH4_TCB+4095)& ~4095); CodeCache = (u8*)(((unat)SH4_TCB+4095)& ~4095);
@ -433,11 +436,13 @@ void recSh4_Init()
printf("\n\t CodeCache addr: %p | from: %p | addr here: %p\n", CodeCache, CodeCache, recSh4_Init); printf("\n\t CodeCache addr: %p | from: %p | addr here: %p\n", CodeCache, CodeCache, recSh4_Init);
#if FEAT_SHREC == DYNAREC_JIT
if (mprotect(CodeCache, CODE_SIZE*2, PROT_READ|PROT_WRITE|PROT_EXEC)) if (mprotect(CodeCache, CODE_SIZE*2, PROT_READ|PROT_WRITE|PROT_EXEC))
{ {
perror("\n\tError,Couldnt mprotect CodeCache!"); perror("\n\tError,Couldnt mprotect CodeCache!");
verify(false); die("Couldnt mprotect CodeCache");
} }
#endif
memset(CodeCache,0xFF,CODE_SIZE*2); memset(CodeCache,0xFF,CODE_SIZE*2);

View File

@ -38,7 +38,11 @@ void Sh4_int_Run()
s32 l=SH4_TIMESLICE; s32 l=SH4_TIMESLICE;
#if !defined(TARGET_BOUNDED_EXECUTION)
do do
#else
for (int i=0; i<10000; i++)
#endif
{ {
do do
{ {
@ -50,10 +54,13 @@ void Sh4_int_Run()
} while(l>0); } while(l>0);
l+=SH4_TIMESLICE; l+=SH4_TIMESLICE;
UpdateSystem_INTC(); UpdateSystem_INTC();
#if !defined(TARGET_BOUNDED_EXECUTION)
} while(sh4_int_bCpuRun); } while(sh4_int_bCpuRun);
sh4_int_bCpuRun=false; sh4_int_bCpuRun=false;
#else
}
#endif
} }
void Sh4_int_Stop() void Sh4_int_Stop()

View File

@ -1301,7 +1301,11 @@ void DYNACALL do_sqw_mmu(u32 dst) { do_sqw<true>(dst); }
#if HOST_CPU!=CPU_ARM #if HOST_CPU!=CPU_ARM
extern "C" void DYNACALL do_sqw_nommu_area_3(u32 dst,u8* sqb) extern "C" void DYNACALL do_sqw_nommu_area_3(u32 dst,u8* sqb)
{ {
#if defined (TARGET_NO_NVMEM)
u8* pmem = mem_b.data;
#else
u8* pmem=sqb+512+0x0C000000; u8* pmem=sqb+512+0x0C000000;
#endif
memcpy((u64*)&pmem[dst&(RAM_MASK-0x1F)],(u64*)&sqb[dst & 0x20],32); memcpy((u64*)&pmem[dst&(RAM_MASK-0x1F)],(u64*)&sqb[dst & 0x20],32);
} }

View File

@ -15,6 +15,9 @@
#include "hw/sh4/dyna/blockmanager.h" #include "hw/sh4/dyna/blockmanager.h"
#include <unistd.h> #include <unistd.h>
#if defined(TARGET_EMSCRIPTEN)
#include <emscripten.h>
#endif
@ -32,7 +35,7 @@
map<int, int> x11_keymap; map<int, int> x11_keymap;
#endif #endif
#if !defined(ANDROID) && HOST_OS != OS_DARWIN #if !defined(ANDROID) && HOST_OS != OS_DARWIN && !defined(TARGET_EMSCRIPTEN)
#include <linux/joystick.h> #include <linux/joystick.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@ -138,8 +141,7 @@ void SetupInput()
rt[port]=0; rt[port]=0;
lt[port]=0; lt[port]=0;
} }
#if HOST_OS != OS_DARWIN && !defined(TARGET_EMSCRIPTEN)
#if HOST_OS != OS_DARWIN
if (true) { if (true) {
#ifdef TARGET_PANDORA #ifdef TARGET_PANDORA
const char* device = "/dev/input/event4"; const char* device = "/dev/input/event4";
@ -160,10 +162,10 @@ void SetupInput()
else else
perror("evdev open"); perror("evdev open");
} }
#endif
// Open joystick device // Open joystick device
JoyFD = open("/dev/input/js0",O_RDONLY); JoyFD = open("/dev/input/js0",O_RDONLY);
#if HOST_OS != OS_DARWIN
if(JoyFD>=0) if(JoyFD>=0)
{ {
int AxisCount,ButtonCount; int AxisCount,ButtonCount;
@ -191,7 +193,7 @@ void SetupInput()
} }
bool HandleKb(u32 port) { bool HandleKb(u32 port) {
#if HOST_OS != OS_DARWIN #if HOST_OS != OS_DARWIN && !defined(TARGET_EMSCRIPTEN)
if (kbfd < 0) if (kbfd < 0)
return false; return false;
@ -297,7 +299,7 @@ bool HandleJoystick(u32 port)
// Joystick must be connected // Joystick must be connected
if(JoyFD<0) return false; if(JoyFD<0) return false;
#if HOST_OS != OS_DARWIN #if HOST_OS != OS_DARWIN && !defined(TARGET_EMSCRIPTEN)
struct js_event JE; struct js_event JE;
while(read(JoyFD,&JE,sizeof(JE))==sizeof(JE)) while(read(JoyFD,&JE,sizeof(JE))==sizeof(JE))
if (JE.number<MAP_SIZE) if (JE.number<MAP_SIZE)
@ -418,6 +420,10 @@ void UpdateInputState(u32 port)
rt[port]=0; rt[port]=0;
lt[port]=0; lt[port]=0;
#if defined(TARGET_EMSCRIPTEN)
return;
#endif
#if defined(TARGET_GCW0) || defined(TARGET_PANDORA) #if defined(TARGET_GCW0) || defined(TARGET_PANDORA)
HandleJoystick(port); HandleJoystick(port);
HandleKb(port); HandleKb(port);
@ -784,13 +790,13 @@ int main(int argc, wchar* argv[])
//if (argc==2) //if (argc==2)
//ndcid=atoi(argv[1]); //ndcid=atoi(argv[1]);
if (setup_curses() < 0) die("failed to setup curses!\n"); if (setup_curses() < 0) printf("failed to setup curses!\n");
#ifdef TARGET_PANDORA #ifdef TARGET_PANDORA
signal(SIGSEGV, clean_exit); signal(SIGSEGV, clean_exit);
signal(SIGKILL, clean_exit); signal(SIGKILL, clean_exit);
#endif #endif
#if defined(USES_HOMEDIR) && HOST_OS != OS_DARWIN #if defined(USES_HOMEDIR) && HOST_OS != OS_DARWIN && !defined(TARGET_EMSCRIPTEN)
string home = (string)getenv("HOME"); string home = (string)getenv("HOME");
if(home.c_str()) if(home.c_str())
{ {
@ -835,7 +841,12 @@ int main(int argc, wchar* argv[])
dc_init(argc,argv); dc_init(argc,argv);
#if !defined(TARGET_EMSCRIPTEN)
dc_run(); dc_run();
#else
emscripten_set_main_loop(&dc_run, 100, false);
#endif
#ifdef TARGET_PANDORA #ifdef TARGET_PANDORA
clean_exit(0); clean_exit(0);
@ -852,5 +863,10 @@ int push_vmu_screen(u8* buffer) { return 0; }
void os_DebugBreak() void os_DebugBreak()
{ {
#if !defined(TARGET_EMSCRIPTEN)
raise(SIGTRAP); raise(SIGTRAP);
#else
printf("DEBUGBREAK!\n");
exit(-1);
#endif
} }

View File

@ -6,8 +6,10 @@
#define _XOPEN_SOURCE 1 #define _XOPEN_SOURCE 1
#define __USE_GNU 1 #define __USE_GNU 1
#endif #endif
#if !defined(TARGET_NACL32)
#include <poll.h> #include <poll.h>
#include <termios.h> #include <termios.h>
#endif
//#include <curses.h> //#include <curses.h>
#include <fcntl.h> #include <fcntl.h>
#include <semaphore.h> #include <semaphore.h>
@ -16,10 +18,10 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/time.h> #include <sys/time.h>
#if !defined(_ANDROID) && !TARGET_OS_IPHONE #if !defined(_ANDROID) && !defined(TARGET_OS_IPHONE) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN)
#include <sys/personality.h> #include <sys/personality.h>
#include <dlfcn.h>
#endif #endif
#include <dlfcn.h>
#include <unistd.h> #include <unistd.h>
#include "hw/sh4/dyna/blockmanager.h" #include "hw/sh4/dyna/blockmanager.h"
@ -27,6 +29,7 @@
#include "hw/sh4/dyna/ngen.h" #include "hw/sh4/dyna/ngen.h"
#if !defined(TARGET_NO_EXCEPTIONS)
bool ngen_Rewrite(unat& addr,unat retadr,unat acc); bool ngen_Rewrite(unat& addr,unat retadr,unat acc);
u32* ngen_readm_fail_v2(u32* ptr,u32* regs,u32 saddr); u32* ngen_readm_fail_v2(u32* ptr,u32* regs,u32 saddr);
bool VramLockedWrite(u8* address); bool VramLockedWrite(u8* address);
@ -51,6 +54,7 @@ void sigill_handler(int sn, siginfo_t * si, void *segfault_ctx) {
} }
#endif #endif
#if !defined(TARGET_NO_EXCEPTIONS)
void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) void fault_handler (int sn, siginfo_t * si, void *segfault_ctx)
{ {
rei_host_context_t ctx; rei_host_context_t ctx;
@ -96,16 +100,18 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx)
signal(SIGSEGV, SIG_DFL); signal(SIGSEGV, SIG_DFL);
} }
} }
#endif
#endif
void install_fault_handler (void) void install_fault_handler (void)
{ {
#if !defined(TARGET_NO_EXCEPTIONS)
struct sigaction act, segv_oact; struct sigaction act, segv_oact;
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_sigaction = fault_handler; act.sa_sigaction = fault_handler;
sigemptyset(&act.sa_mask); sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &act, &segv_oact); sigaction(SIGSEGV, &act, &segv_oact);
#if HOST_OS == OS_DARWIN #if HOST_OS == OS_DARWIN
//this is broken on osx/ios/mach in general //this is broken on osx/ios/mach in general
sigaction(SIGBUS, &act, &segv_oact); sigaction(SIGBUS, &act, &segv_oact);
@ -113,8 +119,10 @@ void install_fault_handler (void)
act.sa_sigaction = sigill_handler; act.sa_sigaction = sigill_handler;
sigaction(SIGILL, &act, &segv_oact); sigaction(SIGILL, &act, &segv_oact);
#endif #endif
#endif
} }
#if !defined(TARGET_NO_THREADS)
//Thread class //Thread class
cThread::cThread(ThreadEntryFP* function,void* prm) cThread::cThread(ThreadEntryFP* function,void* prm)
@ -134,6 +142,7 @@ void cThread::WaitToEnd()
} }
//End thread class //End thread class
#endif
//cResetEvent Calss //cResetEvent Calss
cResetEvent::cResetEvent(bool State,bool Auto) cResetEvent::cResetEvent(bool State,bool Auto)
@ -182,6 +191,7 @@ void cResetEvent::Wait()//Wait for signal , then reset
void VArray2::LockRegion(u32 offset,u32 size) void VArray2::LockRegion(u32 offset,u32 size)
{ {
#if !defined(TARGET_NO_EXCEPTIONS)
u32 inpage=offset & PAGE_MASK; u32 inpage=offset & PAGE_MASK;
u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ ); u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ );
if (rv!=0) if (rv!=0)
@ -189,6 +199,10 @@ void VArray2::LockRegion(u32 offset,u32 size)
printf("mprotect(%08X,%08X,R) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno); printf("mprotect(%08X,%08X,R) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno);
die("mprotect failed ..\n"); die("mprotect failed ..\n");
} }
#else
printf("VA2: LockRegion\n");
#endif
} }
void print_mem_addr() void print_mem_addr()
@ -228,6 +242,7 @@ void print_mem_addr()
void VArray2::UnLockRegion(u32 offset,u32 size) void VArray2::UnLockRegion(u32 offset,u32 size)
{ {
#if !defined(TARGET_NO_EXCEPTIONS)
u32 inpage=offset & PAGE_MASK; u32 inpage=offset & PAGE_MASK;
u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ | PROT_WRITE); u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ | PROT_WRITE);
if (rv!=0) if (rv!=0)
@ -236,6 +251,9 @@ void VArray2::UnLockRegion(u32 offset,u32 size)
printf("mprotect(%08X,%08X,RW) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno); printf("mprotect(%08X,%08X,RW) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno);
die("mprotect failed ..\n"); die("mprotect failed ..\n");
} }
#else
printf("VA2: UnLockRegion\n");
#endif
} }
double os_GetSeconds() double os_GetSeconds()
{ {
@ -276,7 +294,7 @@ void enable_runfast()
} }
void linux_fix_personality() { void linux_fix_personality() {
#if !defined(_ANDROID) && !TARGET_OS_IPHONE #if HOST_OS == OS_LINUX && !defined(_ANDROID) && !defined(TARGET_OS_IPHONE) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN)
printf("Personality: %08X\n", personality(0xFFFFFFFF)); printf("Personality: %08X\n", personality(0xFFFFFFFF));
personality(~READ_IMPLIES_EXEC & personality(0xFFFFFFFF)); personality(~READ_IMPLIES_EXEC & personality(0xFFFFFFFF));
printf("Updated personality: %08X\n", personality(0xFFFFFFFF)); printf("Updated personality: %08X\n", personality(0xFFFFFFFF));
@ -284,6 +302,7 @@ void linux_fix_personality() {
} }
void linux_rpi2_init() { void linux_rpi2_init() {
#if (HOST_OS == OS_LINUX) && !defined(_ANDROID) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN)
void* handle; void* handle;
void (*rpi_bcm_init)(void); void (*rpi_bcm_init)(void);
@ -297,6 +316,7 @@ void linux_rpi2_init() {
rpi_bcm_init(); rpi_bcm_init();
} }
} }
#endif
} }
void common_linux_setup() void common_linux_setup()

View File

@ -8,7 +8,9 @@
#define __USE_GNU 1 #define __USE_GNU 1
#endif #endif
#if !defined(TARGET_NO_EXCEPTIONS)
#include <ucontext.h> #include <ucontext.h>
#endif
#endif #endif
@ -27,6 +29,7 @@ void bicopy(Ta& rei, Tb& seg, bool to_segfault) {
void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_segfault) { void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_segfault) {
#if !defined(TARGET_NO_EXCEPTIONS)
#if HOST_CPU == CPU_ARM #if HOST_CPU == CPU_ARM
#if HOST_OS == OS_LINUX #if HOST_OS == OS_LINUX
bicopy(reictx->pc, MCTX(.arm_pc), to_segfault); bicopy(reictx->pc, MCTX(.arm_pc), to_segfault);
@ -64,6 +67,7 @@ void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_se
#else #else
#error Unsupported HOST_CPU #error Unsupported HOST_CPU
#endif #endif
#endif
} }

View File

@ -1,4 +1,6 @@
#include "types.h" #include "types.h"
#if FEAT_HAS_NIXPROF
#include "cfg/cfg.h" #include "cfg/cfg.h"
@ -33,7 +35,7 @@
#include <set> #include <set>
#include "deps/libelf/elf.h" #include "deps/libelf/elf.h"
#include "context.h" #include "linux/context.h"
/** /**
@file CallStack_Android.h @file CallStack_Android.h
@ -298,3 +300,4 @@ void sample_Stop()
} }
printf("sampling profiler: stopped\n"); printf("sampling profiler: stopped\n");
} }
#endif

View File

@ -6,8 +6,23 @@
#include "ppapi/cpp/module.h" #include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h" #include "ppapi/cpp/var.h"
#include <sys/mount.h>
#include "nacl_io/ioctl.h"
#include "nacl_io/nacl_io.h"
#include "ppapi/cpp/graphics_3d.h"
#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "types.h" #include "types.h"
#include <GLES2/gl2.h>
extern int screen_width,screen_height;
bool rend_single_frame();
bool gles_init();
extern "C" int reicast_main(int argc, char* argv[]);
int msgboxf(const wchar* text,unsigned int type,...) int msgboxf(const wchar* text,unsigned int type,...)
{ {
va_list args; va_list args;
@ -21,16 +36,56 @@ int msgboxf(const wchar* text,unsigned int type,...)
return 0; return 0;
} }
int dc_init(int argc,wchar* argv[]);
void dc_run();
bool rend_framePending();
pthread_t emut;
void* emuthread(void* ) {
printf("Emu thread starting up");
char *Args[3];
Args[0] = "dc";
SetHomeDir("/http");
dc_init(1,Args);
dc_run();
return 0;
}
namespace hello_world namespace hello_world
{ {
class HelloWorldInstance;
HelloWorldInstance* rei_instance;
class HelloWorldInstance : public pp::Instance { class HelloWorldInstance : public pp::Instance {
public: public:
explicit HelloWorldInstance(PP_Instance instance) : pp::Instance(instance) { explicit HelloWorldInstance(PP_Instance instance) : pp::Instance(instance), callback_factory_(this) {
printf("HelloWorldInstance.\n"); rei_instance = this;
printf("Reicast NACL loaded\n");
nacl_io_init_ppapi(instance, pp::Module::Get()->get_browser_interface());
umount("/");
mount("", "/", "memfs", 0, "");
mount("", /* source. Use relative URL */
"/http", /* target */
"httpfs", /* filesystemtype */
0, /* mountflags */
""); /* data */
pthread_create(&emut, NULL, emuthread, 0);
} }
virtual ~HelloWorldInstance() {} virtual ~HelloWorldInstance() {}
pp::CompletionCallbackFactory<HelloWorldInstance> callback_factory_;
pp::Graphics3D context_;
int32_t width_;
int32_t height_;
/// Called by the browser to handle the postMessage() call in Javascript. /// Called by the browser to handle the postMessage() call in Javascript.
/// Detects which method is being called from the message contents, and /// Detects which method is being called from the message contents, and
/// calls the appropriate function. Posts the result back to the browser /// calls the appropriate function. Posts the result back to the browser
@ -40,6 +95,82 @@ class HelloWorldInstance : public pp::Instance {
/// the 'reverseText' form contains the string to reverse following a ':' /// the 'reverseText' form contains the string to reverse following a ':'
/// separator. /// separator.
virtual void HandleMessage(const pp::Var& var_message); virtual void HandleMessage(const pp::Var& var_message);
bool InitGL(int32_t new_width, int32_t new_height) {
if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) {
fprintf(stderr, "Unable to initialize GL PPAPI!\n");
return false;
}
const int32_t attrib_list[] = {
PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
PP_GRAPHICS3DATTRIB_WIDTH, new_width,
PP_GRAPHICS3DATTRIB_HEIGHT, new_height,
PP_GRAPHICS3DATTRIB_NONE
};
context_ = pp::Graphics3D(this, attrib_list);
if (!BindGraphics(context_)) {
fprintf(stderr, "Unable to bind 3d context!\n");
context_ = pp::Graphics3D();
glSetCurrentContextPPAPI(0);
return false;
}
glSetCurrentContextPPAPI(context_.pp_resource());
return true;
}
virtual void DidChangeView(const pp::View& view) {
// Pepper specifies dimensions in DIPs (device-independent pixels). To
// generate a context that is at device-pixel resolution on HiDPI devices,
// scale the dimensions by view.GetDeviceScale().
int32_t new_width = view.GetRect().width() * view.GetDeviceScale();
int32_t new_height = view.GetRect().height() * view.GetDeviceScale();
if (context_.is_null()) {
if (!InitGL(new_width, new_height)) {
// failed.
return;
}
verify(gles_init() == true);
RenderLoop(0);
} else {
// Resize the buffers to the new size of the module.
int32_t result = context_.ResizeBuffers(new_width, new_height);
if (result < 0) {
printf("Unable to resize buffers to %d x %d!\n");
return;
}
}
width_ = new_width;
height_ = new_height;
glViewport(0, 0, width_, height_);
printf("Resize: %d x %d\n", new_width, new_height);
}
void RenderLoop(int32_t) {
screen_width = width_;
screen_height = height_;
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (rend_framePending()) {
while (!rend_single_frame()) ;
printf("Rendered frame\n");
}
printf("Swapping buffers\n");
context_.SwapBuffers(
callback_factory_.NewCallback(&HelloWorldInstance::RenderLoop));
}
}; };
void HelloWorldInstance::HandleMessage(const pp::Var& var_message) { void HelloWorldInstance::HandleMessage(const pp::Var& var_message) {
@ -47,13 +178,12 @@ void HelloWorldInstance::HandleMessage(const pp::Var& var_message) {
return; return;
} }
pp::Var return_var;
// Post the return result back to the browser. Note that HandleMessage() is // Post the return result back to the browser. Note that HandleMessage() is
// always called on the main thread, so it's OK to post the return message // always called on the main thread, so it's OK to post the return message
// directly from here. The return post is asynhronous: PostMessage returns // directly from here. The return post is asynhronous: PostMessage returns
// immediately. // immediately.
PostMessage(return_var);
//PostMessage(return_var);
} }
/// The Module class. The browser calls the CreateInstance() method to create /// The Module class. The browser calls the CreateInstance() method to create
@ -63,7 +193,7 @@ void HelloWorldInstance::HandleMessage(const pp::Var& var_message) {
class HelloWorldModule : public pp::Module { class HelloWorldModule : public pp::Module {
public: public:
HelloWorldModule() : pp::Module() { HelloWorldModule() : pp::Module() {
printf("Got here.\n");
} }
virtual ~HelloWorldModule() {} virtual ~HelloWorldModule() {}
@ -77,6 +207,19 @@ class HelloWorldModule : public pp::Module {
}; };
} // namespace hello_world } // namespace hello_world
int nacl_printf(const wchar* text,...)
{
va_list args;
wchar temp[2048];
va_start(args, text);
int rv = vsprintf(temp, text, args);
va_end(args);
if (hello_world::rei_instance)
hello_world::rei_instance->PostMessage(pp::Var(temp));
return rv;
}
namespace pp { namespace pp {
/// Factory function called by the browser when the module is first loaded. /// Factory function called by the browser when the module is first loaded.
@ -90,3 +233,54 @@ Module* CreateModule() {
return new hello_world::HelloWorldModule(); return new hello_world::HelloWorldModule();
} }
} // namespace pp } // namespace pp
u16 kcode[4];
u32 vks[4];
s8 joyx[4],joyy[4];
u8 rt[4],lt[4];
int get_mic_data(u8* buffer) { return 0; }
int push_vmu_screen(u8* buffer) { return 0; }
void os_SetWindowText(const char * text) {
puts(text);
}
void os_DoEvents() {
}
void UpdateInputState(u32 port) {
}
void os_CreateWindow() {
}
void os_DebugBreak() {
exit(1);
}
void* libPvr_GetRenderTarget() {
return 0;
}
void* libPvr_GetRenderSurface() {
return 0;
}
bool gl_init(void*, void*) {
return true;
}
void gl_term() {
}
void gl_swap() {
}

18
core/nacl/nacl_lin.cpp Normal file
View File

@ -0,0 +1,18 @@
#define PUTS_REAL puts
#include <types.h>
#include <stdarg.h>
int nacl_printf(const wchar* text,...)
{
va_list args;
wchar temp[2048];
va_start(args, text);
int rv = vsprintf(temp, text, args);
va_end(args);
PUTS_REAL(temp);
return rv;
}

View File

@ -129,17 +129,16 @@ void plugins_Reset(bool Manual)
//libExtDevice_Reset(Manual); //libExtDevice_Reset(Manual);
} }
#if !defined(TARGET_NO_WEBUI)
void* webui_th(void* p) void* webui_th(void* p)
{ {
#if (HOST_OS == OS_WINDOWS || HOST_OS == OS_LINUX) && !defined(TARGET_PANDORA) && defined(WEBUI)
webui_start(); webui_start();
#endif
return 0; return 0;
} }
cThread webui_thd(&webui_th,0); cThread webui_thd(&webui_th,0);
#endif
int dc_init(int argc,wchar* argv[]) int dc_init(int argc,wchar* argv[])
{ {
@ -152,7 +151,9 @@ int dc_init(int argc,wchar* argv[])
return -1; return -1;
} }
#if !defined(TARGET_NO_WEBUI)
webui_thd.Start(); webui_thd.Start();
#endif
if(ParseCommandLine(argc,argv)) if(ParseCommandLine(argc,argv))
{ {

View File

@ -52,7 +52,11 @@ void ngen_mainloop(void* v_cntx)
cycle_counter = 0; cycle_counter = 0;
#if !defined(TARGET_BOUNDED_EXECUTION)
for (;;) { for (;;) {
#else
for (int i=0; i<10000; i++) {
#endif
cycle_counter = SH4_TIMESLICE; cycle_counter = SH4_TIMESLICE;
do { do {
DynarecCodeEntryPtr rcb = bm_GetCode(ctx->cntx.pc); DynarecCodeEntryPtr rcb = bm_GetCode(ctx->cntx.pc);

View File

@ -354,7 +354,7 @@ gl_ctx gl;
int screen_width; int screen_width;
int screen_height; int screen_height;
#if HOST_OS != OS_DARWIN #if (HOST_OS != OS_DARWIN) && !defined(TARGET_NACL32)
#ifdef GLES #ifdef GLES
// Create a basic GLES context // Create a basic GLES context
bool gl_init(void* wind, void* disp) bool gl_init(void* wind, void* disp)
@ -755,11 +755,12 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader)
{ {
if (compile_log_len==0) if (compile_log_len==0)
compile_log_len=1; compile_log_len=1;
compile_log_len+= 1024;
char* compile_log=(char*)malloc(compile_log_len); char* compile_log=(char*)malloc(compile_log_len);
*compile_log=0; *compile_log=0;
glGetProgramInfoLog(program, compile_log_len, &compile_log_len, compile_log); glGetProgramInfoLog(program, compile_log_len, &compile_log_len, compile_log);
printf("Shader linking: %s \n%s\n",result?"linked":"failed to link",compile_log); printf("Shader linking: %s \n (%d bytes), - %s -\n",result?"linked":"failed to link", compile_log_len,compile_log);
free(compile_log); free(compile_log);
die("shader compile fail\n"); die("shader compile fail\n");
@ -961,7 +962,7 @@ bool gles_init()
if (!gl_create_resources()) if (!gl_create_resources())
return false; return false;
#if defined(GLES) && HOST_OS != OS_DARWIN #if defined(GLES) && HOST_OS != OS_DARWIN && !defined(TARGET_NACL32)
#ifdef TARGET_PANDORA #ifdef TARGET_PANDORA
fbdev=open("/dev/fb0", O_RDONLY); fbdev=open("/dev/fb0", O_RDONLY);
#else #else

View File

@ -3,12 +3,14 @@
#ifdef GLES #ifdef GLES
#ifdef TARGET_IPHONE //apple-specific ogles2 headers #if defined(TARGET_IPHONE) //apple-specific ogles2 headers
//#include <APPLE/egl.h> //#include <APPLE/egl.h>
#include <OpenGLES/ES2/gl.h> #include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h> #include <OpenGLES/ES2/glext.h>
#else #else
#if !defined(TARGET_NACL32)
#include <EGL/egl.h> #include <EGL/egl.h>
#endif
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#endif #endif
@ -57,7 +59,7 @@ struct PipelineShader
struct gl_ctx struct gl_ctx
{ {
#if defined(GLES) && HOST_OS != OS_DARWIN #if defined(GLES) && HOST_OS != OS_DARWIN && !defined(TARGET_NACL32)
struct struct
{ {
EGLNativeWindowType native_wind; EGLNativeWindowType native_wind;

View File

@ -163,6 +163,7 @@ public:
//Windoze code //Windoze code
//Threads //Threads
#if !defined(HOST_NO_THREADS)
typedef void* ThreadEntryFP(void* param); typedef void* ThreadEntryFP(void* param);
typedef void* THREADHANDLE; typedef void* THREADHANDLE;
@ -179,7 +180,7 @@ public :
void Start(); void Start();
void WaitToEnd(); void WaitToEnd();
}; };
#endif
//Wait Events //Wait Events
typedef void* EVENTHANDLE; typedef void* EVENTHANDLE;
class cResetEvent class cResetEvent

View File

@ -430,6 +430,12 @@ struct maple_device_instance
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#if defined(TARGET_NACL32)
int nacl_printf(const wchar* Text,...);
#define printf nacl_printf
#define puts(X) printf("%s\n", X)
#endif
//includes from c++rt //includes from c++rt
#include <vector> #include <vector>
#include <string> #include <string>

68
shell/emscripten/Makefile Normal file
View File

@ -0,0 +1,68 @@
LOCAL_PATH := $(call my-dir)
FOR_LINUX :=1
NOT_ARM := 1
#NO_REC := 1
#NO_REND := 1
CPP_REC := 1
NO_NIXPROF := 1
RZDCY_SRC_DIR = ../../core
include $(RZDCY_SRC_DIR)/core.mk
CC_PREFIX ?=
CXX=${CC_PREFIX}em++
CC=${CC_PREFIX}emcc
#AS=${CC_PREFIX}as
STRIP=${CC_PREFIX}emstrip
LD=${CC}
MFLAGS :=
ASFLAGS :=
LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common
CXXONLYFLAGS := -std=c++11
CXXFLAGS := -O3 -D GLES -D RELEASE -c -D TARGET_EMSCRIPTEN -D TARGET_NO_REC -D TARGET_NO_NVMEM -D TARGET_NO_WEBUI -D TARGET_NO_THREADS -D TARGET_BOUNDED_EXECUTION -D TARGET_NO_EXCEPTIONS -D TARGET_NO_COREIO_HTTP
CXXFLAGS += -fno-strict-aliasing
CXXFLAGS += -ffast-math
CXXFLAGS += $(CFLAGS) $(MFLAGS) -fno-exceptions -fno-rtti
INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos -I../linux-deps/include
LIBS := #emscripten has all the basic libs, and egl, and sdl, built in
OBJECTS=$(RZDCY_FILES:.cpp=.build.obj)
OBJECTS:=$(OBJECTS:.c=.build.obj)
OBJECTS:=$(OBJECTS:.S=.build.obj)
OBJECTS:=$(patsubst $(RZDCY_SRC_DIR)/%,obj/%,$(OBJECTS))
EXECUTABLE=reicast.html
all: $(CPPFILES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
echo $(RZDCY_FILES)
$(CXX) $(MFLAGS) $(EXTRAFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ --preload-file data/dc_boot.bin --preload-file data/dc_flash.bin -s TOTAL_MEMORY=96000000 -s NO_EXIT_RUNTIME=1 -O3
obj/%.build.obj : $(RZDCY_SRC_DIR)/%.cpp
mkdir -p $(dir $@)
$(CXX) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $(CXXONLYFLAGS) $< -o $@
obj/%.build.obj : $(RZDCY_SRC_DIR)/%.c
mkdir -p $(dir $@)
$(CC) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@
obj/%.build.obj : $(RZDCY_SRC_DIR)/%.S
mkdir -p $(dir $@)
$(AS) $(ASFLAGS) $(INCS) $< -o $@
clean:
rm $(OBJECTS) $(EXECUTABLE) -f

View File

@ -1,73 +1,52 @@
VALID_TOOLCHAINS := pnacl newlib glibc
CONFIG ?= Debug
include $(NACL_SDK_ROOT)/tools/common.mk
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
FOR_LINUX :=1
NOT_ARM := 1 NOT_ARM := 1
NO_REC := 1 CPP_REC := 1
#NO_REND := 1 #NO_REND := 1
NO_NIXPROF := 1
RZDCY_SRC_DIR = ../../core RZDCY_SRC_DIR = ../../core
include $(RZDCY_SRC_DIR)/core.mk include $(RZDCY_SRC_DIR)/core.mk
PROJECT:=reicast TARGET = reicast
LDFLAGS:=-lppapi_gles2 -lppapi_cpp -lppapi DEPS = nacl_io
LIBS = ppapi_gles2 ppapi_cpp ppapi pthread nacl_io
#CXX_SOURCES := $(foreach dir,$(SOURCES),$(wildcard $(dir)*.cpp))
#CC_SOURCES += $(foreach dir,$(SOURCES),$(wildcard $(dir)*.c))
CFLAGS = -Wno-error -Wno-ignored-attributes
CFLAGS += -O3 -fno-strict-aliasing -ffast-math
CFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps
CFLAGS += -D RELEASE -D TARGET_NO_JIT -D TARGET_NACL32 -DGLES
CFLAGS += -D TARGET_NO_EXCEPTIONS -D TARGET_NO_NVMEM -D TARGET_NO_WEBUI -D TARGET_NO_COREIO_HTTP
SOURCES = $(RZDCY_FILES) ../../core/nacl/nacl.cpp
# Project Build flags # Project Build flags
WARNINGS:=-Wno-long-long -Wswitch-enum WARNINGS ?=-Wno-long-long -Wno-switch-enum
CXXFLAGS:=-pthread -std=gnu++0x $(WARNINGS) CXXFLAGS += -std=gnu++0x $(WARNINGS)
CXXFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos -I../linux-deps/include -D RELEASE -D TARGET_NO_REC -D TARGET_NACL32
#
# Compute tool paths
#
#
OSNAME:=$(shell python $(NACL_SDK_ROOT)/tools/getos.py)
TC_PATH:=$(NACL_SDK_ROOT)/toolchain/$(OSNAME)_x86_newlib
CXX:=$(TC_PATH)/bin/i686-nacl-g++
CC:=$(TC_PATH)/bin/i686-nacl-gcc
#
# Disable DOS PATH warning when using Cygwin based tools Windows
#
CYGWIN ?= nodosfilewarning
export CYGWIN
# Declare the ALL target first, to make the 'all' target the default build # Build rules generated by macros from common.mk:
all: $(PROJECT)_x86_32.nexe
# Define 32 bit compile and link rules for C++ sources $(foreach dep,$(DEPS),$(eval $(call DEPEND_RULE,$(dep))))
CXX_32_OBJSX:=$(patsubst %.cpp,%.nacl_86x32_build_obj,$(RZDCY_FILES))
CXX_32_OBJSY:=$(patsubst %.c,%.nacl_86x32_build_obj,$(CXX_32_OBJSX))
CXX_32_OBJS:=$(patsubst %.S,%.nacl_86x32_build_obj,$(CXX_32_OBJSY))
#CC_32_OBJS:=$(patsubst %.c,%.build_obj_nacl_32,$(CC_SOURCES))
x86_32_OBJS:=$(CXX_32_OBJS) $(CC_32_OBJS) $(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
%.nacl_86x32_build_obj : %.cpp $(THIS_MAKE) # The PNaCl workflow uses both an unstripped and finalized/stripped binary.
$(CXX) -o $@ -c $< -m32 -O0 -g $(CXXFLAGS) # On NaCl, only produce a stripped binary for Release configs (not Debug).
ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
%.nacl_86x32_build_obj : %.c $(THIS_MAKE) $(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(CC) -o $@ -c $< -m32 -O0 -g $(CXXFLAGS) $(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
$(PROJECT)_x86_32.nexe : $(x86_32_OBJS) $(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
echo $(x86_32_OBJS) endif
$(CXX) -o $@ $^ -m32 -O0 -g $(CXXFLAGS) $(LDFLAGS)
clean:
rm $(x86_32_OBJS)
# Define a phony rule so it always runs, to build nexe and start up server.
.PHONY: RUN
RUN: all
python ../httpd.py
SHELL = sh
$(eval $(call NMF_RULE,$(TARGET),))

40
shell/nacl/background.js Normal file
View File

@ -0,0 +1,40 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function makeURL(toolchain, config) {
return 'index.html?tc=' + toolchain + '&config=' + config;
}
function createWindow(url) {
console.log('loading ' + url);
chrome.app.window.create(url, {
width: 1024,
height: 800,
frame: 'none'
});
}
function onLaunched(launchData) {
// Send and XHR to get the URL to load from a configuration file.
// Normally you won't need to do this; just call:
//
// chrome.app.window.create('<your url>', {...});
//
// In the SDK we want to be able to load different URLs (for different
// toolchain/config combinations) from the commandline, so we to read
// this information from the file "run_package_config".
var xhr = new XMLHttpRequest();
xhr.open('GET', 'run_package_config', true);
xhr.onload = function() {
var toolchain_config = this.responseText.split(' ');
createWindow(makeURL.apply(null, toolchain_config));
};
xhr.onerror = function() {
// Can't find the config file, just load the default.
createWindow('index.html');
};
xhr.send();
}
chrome.app.runtime.onLaunched.addListener(onLaunched);

474
shell/nacl/common.js Normal file
View File

@ -0,0 +1,474 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Set to true when the Document is loaded IFF "test=true" is in the query
// string.
var isTest = false;
// Set to true when loading a "Release" NaCl module, false when loading a
// "Debug" NaCl module.
var isRelease = true;
// Javascript module pattern:
// see http://en.wikipedia.org/wiki/Unobtrusive_JavaScript#Namespaces
// In essence, we define an anonymous function which is immediately called and
// returns a new object. The new object contains only the exported definitions;
// all other definitions in the anonymous function are inaccessible to external
// code.
var common = (function() {
function isHostToolchain(tool) {
return tool == 'win' || tool == 'linux' || tool == 'mac';
}
/**
* Return the mime type for NaCl plugin.
*
* @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc.
* @return {string} The mime-type for the kind of NaCl plugin matching
* the given toolchain.
*/
function mimeTypeForTool(tool) {
// For NaCl modules use application/x-nacl.
var mimetype = 'application/x-nacl';
if (isHostToolchain(tool)) {
// For non-NaCl PPAPI plugins use the x-ppapi-debug/release
// mime type.
if (isRelease)
mimetype = 'application/x-ppapi-release';
else
mimetype = 'application/x-ppapi-debug';
} else if (tool == 'pnacl') {
mimetype = 'application/x-pnacl';
}
return mimetype;
}
/**
* Check if the browser supports NaCl plugins.
*
* @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc.
* @return {bool} True if the browser supports the type of NaCl plugin
* produced by the given toolchain.
*/
function browserSupportsNaCl(tool) {
// Assume host toolchains always work with the given browser.
// The below mime-type checking might not work with
// --register-pepper-plugins.
if (isHostToolchain(tool)) {
return true;
}
var mimetype = mimeTypeForTool(tool);
return navigator.mimeTypes[mimetype] !== undefined;
}
/**
* Inject a script into the DOM, and call a callback when it is loaded.
*
* @param {string} url The url of the script to load.
* @param {Function} onload The callback to call when the script is loaded.
* @param {Function} onerror The callback to call if the script fails to load.
*/
function injectScript(url, onload, onerror) {
var scriptEl = document.createElement('script');
scriptEl.type = 'text/javascript';
scriptEl.src = url;
scriptEl.onload = onload;
if (onerror) {
scriptEl.addEventListener('error', onerror, false);
}
document.head.appendChild(scriptEl);
}
/**
* Run all tests for this example.
*
* @param {Object} moduleEl The module DOM element.
*/
function runTests(moduleEl) {
console.log('runTests()');
common.tester = new Tester();
// All NaCl SDK examples are OK if the example exits cleanly; (i.e. the
// NaCl module returns 0 or calls exit(0)).
//
// Without this exception, the browser_tester thinks that the module
// has crashed.
common.tester.exitCleanlyIsOK();
common.tester.addAsyncTest('loaded', function(test) {
test.pass();
});
if (typeof window.addTests !== 'undefined') {
window.addTests();
}
common.tester.waitFor(moduleEl);
common.tester.run();
}
/**
* Create the Native Client <embed> element as a child of the DOM element
* named "listener".
*
* @param {string} name The name of the example.
* @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc.
* @param {string} path Directory name where .nmf file can be found.
* @param {number} width The width to create the plugin.
* @param {number} height The height to create the plugin.
* @param {Object} attrs Dictionary of attributes to set on the module.
*/
function createNaClModule(name, tool, path, width, height, attrs) {
var moduleEl = document.createElement('embed');
moduleEl.setAttribute('name', 'nacl_module');
moduleEl.setAttribute('id', 'nacl_module');
moduleEl.setAttribute('width', width);
moduleEl.setAttribute('height', height);
moduleEl.setAttribute('path', path);
moduleEl.setAttribute('src', path + '/' + name + '.nmf');
// Add any optional arguments
if (attrs) {
for (var key in attrs) {
moduleEl.setAttribute(key, attrs[key]);
}
}
var mimetype = mimeTypeForTool(tool);
moduleEl.setAttribute('type', mimetype);
// The <EMBED> element is wrapped inside a <DIV>, which has both a 'load'
// and a 'message' event listener attached. This wrapping method is used
// instead of attaching the event listeners directly to the <EMBED> element
// to ensure that the listeners are active before the NaCl module 'load'
// event fires.
var listenerDiv = document.getElementById('listener');
listenerDiv.appendChild(moduleEl);
// Request the offsetTop property to force a relayout. As of Apr 10, 2014
// this is needed if the module is being loaded on a Chrome App's
// background page (see crbug.com/350445).
moduleEl.offsetTop;
// Host plugins don't send a moduleDidLoad message. We'll fake it here.
var isHost = isHostToolchain(tool);
if (isHost) {
window.setTimeout(function() {
moduleEl.readyState = 1;
moduleEl.dispatchEvent(new CustomEvent('loadstart'));
moduleEl.readyState = 4;
moduleEl.dispatchEvent(new CustomEvent('load'));
moduleEl.dispatchEvent(new CustomEvent('loadend'));
}, 100); // 100 ms
}
// This is code that is only used to test the SDK.
if (isTest) {
var loadNaClTest = function() {
injectScript('nacltest.js', function() {
runTests(moduleEl);
});
};
// Try to load test.js for the example. Whether or not it exists, load
// nacltest.js.
injectScript('test.js', loadNaClTest, loadNaClTest);
}
}
/**
* Add the default "load" and "message" event listeners to the element with
* id "listener".
*
* The "load" event is sent when the module is successfully loaded. The
* "message" event is sent when the naclModule posts a message using
* PPB_Messaging.PostMessage() (in C) or pp::Instance().PostMessage() (in
* C++).
*/
function attachDefaultListeners() {
var listenerDiv = document.getElementById('listener');
listenerDiv.addEventListener('load', moduleDidLoad, true);
listenerDiv.addEventListener('message', handleMessage, true);
listenerDiv.addEventListener('error', handleError, true);
listenerDiv.addEventListener('crash', handleCrash, true);
if (typeof window.attachListeners !== 'undefined') {
window.attachListeners();
}
}
/**
* Called when the NaCl module fails to load.
*
* This event listener is registered in createNaClModule above.
*/
function handleError(event) {
// We can't use common.naclModule yet because the module has not been
// loaded.
var moduleEl = document.getElementById('nacl_module');
updateStatus('ERROR [' + moduleEl.lastError + ']');
}
/**
* Called when the Browser can not communicate with the Module
*
* This event listener is registered in attachDefaultListeners above.
*/
function handleCrash(event) {
if (common.naclModule.exitStatus == -1) {
updateStatus('CRASHED');
} else {
updateStatus('EXITED [' + common.naclModule.exitStatus + ']');
}
if (typeof window.handleCrash !== 'undefined') {
window.handleCrash(common.naclModule.lastError);
}
}
/**
* Called when the NaCl module is loaded.
*
* This event listener is registered in attachDefaultListeners above.
*/
function moduleDidLoad() {
common.naclModule = document.getElementById('nacl_module');
updateStatus('RUNNING');
if (typeof window.moduleDidLoad !== 'undefined') {
window.moduleDidLoad();
}
}
/**
* Hide the NaCl module's embed element.
*
* We don't want to hide by default; if we do, it is harder to determine that
* a plugin failed to load. Instead, call this function inside the example's
* "moduleDidLoad" function.
*
*/
function hideModule() {
// Setting common.naclModule.style.display = "None" doesn't work; the
// module will no longer be able to receive postMessages.
common.naclModule.style.height = '0';
}
/**
* Remove the NaCl module from the page.
*/
function removeModule() {
common.naclModule.parentNode.removeChild(common.naclModule);
common.naclModule = null;
}
/**
* Return true when |s| starts with the string |prefix|.
*
* @param {string} s The string to search.
* @param {string} prefix The prefix to search for in |s|.
*/
function startsWith(s, prefix) {
// indexOf would search the entire string, lastIndexOf(p, 0) only checks at
// the first index. See: http://stackoverflow.com/a/4579228
return s.lastIndexOf(prefix, 0) === 0;
}
/** Maximum length of logMessageArray. */
var kMaxLogMessageLength = 20;
/** An array of messages to display in the element with id "log". */
var logMessageArray = [];
/**
* Add a message to an element with id "log".
*
* This function is used by the default "log:" message handler.
*
* @param {string} message The message to log.
*/
function logMessage(message) {
logMessageArray.push(message);
if (logMessageArray.length > kMaxLogMessageLength)
logMessageArray.shift();
document.getElementById('log').textContent = logMessageArray.join('\n');
console.log(message);
}
/**
*/
var defaultMessageTypes = {
'alert': alert,
'log': logMessage
};
/**
* Called when the NaCl module sends a message to JavaScript (via
* PPB_Messaging.PostMessage())
*
* This event listener is registered in createNaClModule above.
*
* @param {Event} message_event A message event. message_event.data contains
* the data sent from the NaCl module.
*/
function handleMessage(message_event) {
if (typeof message_event.data === 'string') {
for (var type in defaultMessageTypes) {
if (defaultMessageTypes.hasOwnProperty(type)) {
if (startsWith(message_event.data, type + ':')) {
func = defaultMessageTypes[type];
func(message_event.data.slice(type.length + 1));
return;
}
}
}
}
if (typeof window.handleMessage !== 'undefined') {
window.handleMessage(message_event);
return;
}
logMessage('Unhandled message: ' + message_event.data);
}
/**
* Called when the DOM content has loaded; i.e. the page's document is fully
* parsed. At this point, we can safely query any elements in the document via
* document.querySelector, document.getElementById, etc.
*
* @param {string} name The name of the example.
* @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc.
* @param {string} path Directory name where .nmf file can be found.
* @param {number} width The width to create the plugin.
* @param {number} height The height to create the plugin.
* @param {Object} attrs Optional dictionary of additional attributes.
*/
function domContentLoaded(name, tool, path, width, height, attrs) {
// If the page loads before the Native Client module loads, then set the
// status message indicating that the module is still loading. Otherwise,
// do not change the status message.
updateStatus('Page loaded.');
if (!browserSupportsNaCl(tool)) {
updateStatus(
'Browser does not support NaCl (' + tool + '), or NaCl is disabled');
} else if (common.naclModule == null) {
updateStatus('Creating embed: ' + tool);
// We use a non-zero sized embed to give Chrome space to place the bad
// plug-in graphic, if there is a problem.
width = typeof width !== 'undefined' ? width : 200;
height = typeof height !== 'undefined' ? height : 200;
attachDefaultListeners();
createNaClModule(name, tool, path, width, height, attrs);
} else {
// It's possible that the Native Client module onload event fired
// before the page's onload event. In this case, the status message
// will reflect 'SUCCESS', but won't be displayed. This call will
// display the current message.
updateStatus('Waiting.');
}
}
/** Saved text to display in the element with id 'statusField'. */
var statusText = 'NO-STATUSES';
/**
* Set the global status message. If the element with id 'statusField'
* exists, then set its HTML to the status message as well.
*
* @param {string} opt_message The message to set. If null or undefined, then
* set element 'statusField' to the message from the last call to
* updateStatus.
*/
function updateStatus(opt_message) {
if (opt_message) {
statusText = opt_message;
}
var statusField = document.getElementById('statusField');
if (statusField) {
statusField.innerHTML = statusText;
}
}
// The symbols to export.
return {
/** A reference to the NaCl module, once it is loaded. */
naclModule: null,
attachDefaultListeners: attachDefaultListeners,
domContentLoaded: domContentLoaded,
createNaClModule: createNaClModule,
hideModule: hideModule,
removeModule: removeModule,
logMessage: logMessage,
updateStatus: updateStatus
};
}());
// Listen for the DOM content to be loaded. This event is fired when parsing of
// the page's document has finished.
document.addEventListener('DOMContentLoaded', function() {
var body = document.body;
// The data-* attributes on the body can be referenced via body.dataset.
if (body.dataset) {
var loadFunction;
if (!body.dataset.customLoad) {
loadFunction = common.domContentLoaded;
} else if (typeof window.domContentLoaded !== 'undefined') {
loadFunction = window.domContentLoaded;
}
// From https://developer.mozilla.org/en-US/docs/DOM/window.location
var searchVars = {};
if (window.location.search.length > 1) {
var pairs = window.location.search.substr(1).split('&');
for (var key_ix = 0; key_ix < pairs.length; key_ix++) {
var keyValue = pairs[key_ix].split('=');
searchVars[unescape(keyValue[0])] =
keyValue.length > 1 ? unescape(keyValue[1]) : '';
}
}
if (loadFunction) {
var toolchains = body.dataset.tools.split(' ');
var configs = body.dataset.configs.split(' ');
var attrs = {};
if (body.dataset.attrs) {
var attr_list = body.dataset.attrs.split(' ');
for (var key in attr_list) {
var attr = attr_list[key].split('=');
var key = attr[0];
var value = attr[1];
attrs[key] = value;
}
}
var tc = toolchains.indexOf(searchVars.tc) !== -1 ?
searchVars.tc : toolchains[0];
// If the config value is included in the search vars, use that.
// Otherwise default to Release if it is valid, or the first value if
// Release is not valid.
if (configs.indexOf(searchVars.config) !== -1)
var config = searchVars.config;
else if (configs.indexOf('Release') !== -1)
var config = 'Release';
else
var config = configs[0];
var pathFormat = body.dataset.path;
var path = pathFormat.replace('{tc}', tc).replace('{config}', config);
isTest = searchVars.test === 'true';
isRelease = path.toLowerCase().indexOf('release') != -1;
loadFunction(body.dataset.name, tc, path, body.dataset.width,
body.dataset.height, attrs);
}
}
});

19
shell/nacl/example.js Normal file
View File

@ -0,0 +1,19 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function $(id) {
return document.getElementById(id);
}
// Add event listeners after the NaCl module has loaded. These listeners will
// forward messages to the NaCl module via postMessage()
function attachListeners() {
}
// Handle a message coming from the NaCl module.
function handleMessage(event) {
console.log(event.data);
$("status").textContent = event.data;
}

BIN
shell/nacl/icon128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

27
shell/nacl/index.html Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<!--
Copyright (c) 2012 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<head>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
<title>reicast nacl</title>
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript" src="example.js"></script>
<style>
.label { display: inline-block; width: 100px; }
</style>
</head>
<body data-width="640" data-height="480" data-name="reicast" data-tools="pnacl newlib glibc clang-newlib win" data-configs="Debug Release" data-path="{tc}/{config}">
<h1>reicast nacl</h1>
<h2 id="status">Status: <code id="statusField">NO-STATUS</code></h2>
<button onclick="document.querySelector('embed').postMessage('hello');"> START </button>
<!-- The NaCl plugin will be embedded inside the element with id "listener".
See common.js.-->
<div id="listener"></div>
<div id="log" style="display: none; white-space: pre-line;"></div>
</body>
</html>

124
shell/nacl_lin/Makefile Normal file
View File

@ -0,0 +1,124 @@
# nacl-simulating linux build
# for debugging
LOCAL_PATH := $(call my-dir)
FOR_LINUX :=1
#NOT_ARM := 1
#X64_REC := 1
CPP_REC :=1
#NO_REC := 1
NO_REND := 1
WEBUI :=1
USE_ALSA := 1
USE_OSS := 1
#USE_PULSEAUDIO := 1
RZDCY_SRC_DIR = ../../core
include $(RZDCY_SRC_DIR)/core.mk
RZDCY_FILES += $(RZDCY_SRC_DIR)/nacl/nacl_lin.cpp
CXX=${CC_PREFIX}g++
CC=${CC_PREFIX}gcc
AS=${CC_PREFIX}as
STRIP=${CC_PREFIX}strip
LD=${CC}
MFLAGS := #-m32
#-marm -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp -funroll-loops
ASFLAGS :=
#-march=armv7-a -mfpu=neon -mfloat-abi=softfp
LDFLAGS := -g -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common
CFLAGS := -g -O3 -D RELEASE -c -D TARGET_LINUX_x64 -D TARGET_NACL32 -D USES_HOMEDIR -D TARGET_NO_JIT -D NO_REND -std=c++11
CFLAGS += -frename-registers -fno-strict-aliasing #-fsingle-precision-constant
CFLAGS += -ffast-math -ftree-vectorize
#-fprefetch-loop-arrays
#-std=c++0x
CXXFLAGS += $(CFLAGS) $(MFLAGS) -fexceptions -fno-rtti -fpermissive
CXXFLAGS += -fno-operator-names
ifdef PGO_MAKE
CFLAGS += -fprofile-generate -pg
LDFLAGS += -fprofile-generate
else
CFLAGS += -fomit-frame-pointer
endif
ifdef PGO_USE
CFLAGS += -fprofile-use
endif
ifdef LTO_TEST
CFLAGS += -flto -fwhole-program
LDFLAGS +=-flto -fwhole-program
endif
INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos
LIBS := # use system libs
LIBS += -lm -lrt -ldl
LIBS += -lpthread #-lX11
ifdef USE_ALSA
CXXFLAGS += -D USE_ALSA
LIBS += -lasound
endif
ifdef USE_OSS
CXXFLAGS += -D USE_OSS
endif
ifdef USE_PULSEAUDIO
CXXFLAGS += -D USE_PULSEAUDIO
LIBS += -lpulse-simple
endif
ifdef USE_GLES
CXXFLAGS += -DGLES
LIBS += -lEGL -lGLESv2
else
LIBS += -ldl -lGL #for desktop gl
endif
OBJECTS=$(RZDCY_FILES:.cpp=.build_obj)
OBJECTS:=$(OBJECTS:.c=.build_obj)
OBJECTS:=$(OBJECTS:.S=.build_obj)
OBJECTS:=$(patsubst $(RZDCY_SRC_DIR)/%,obj/%,$(OBJECTS))
EXECUTABLE_STRIPPED=nosym-reicast.elf
EXECUTABLE=reicast.elf
PACKAGE_FILES=$(EXECUTABLE_STRIPPED) default.gcw0.desktop icon-32.png
all: $(CPPFILES) $(EXECUTABLE) $(EXECUTABLE_STRIPPED)
$(EXECUTABLE): $(OBJECTS)
$(CXX) $(MFLAGS) $(EXTRAFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
$(EXECUTABLE_STRIPPED): $(EXECUTABLE)
cp $< $@ && $(STRIP) $@
obj/%.build_obj : $(RZDCY_SRC_DIR)/%.cpp
mkdir -p $(dir $@)
$(CXX) $(EXTRAFLAGS) $(INCS) $(CFLAGS) $(CXXFLAGS) $< -o $@
obj/%.build_obj : $(RZDCY_SRC_DIR)/%.c
mkdir -p $(dir $@)
$(CC) $(EXTRAFLAGS) $(INCS) $(CFLAGS) $< -o $@
obj/%.build_obj : $(RZDCY_SRC_DIR)/%.S
mkdir -p $(dir $@)
$(AS) $(ASFLAGS) $(INCS) $< -o $@
clean:
rm $(OBJECTS) $(EXECUTABLE) -f