Skip to content

Commit

Permalink
add contrib directory for Google Native Client
Browse files Browse the repository at this point in the history
Native Client lets you port C/C++ programs to run in the Chrome browser. The
various other files included in this commit support uploading Load81 to Google
App Engine and publishing it in the Chrome Web Store.

The major feature still missing from this port is file IO. The initial program
is hardcoded.
  • Loading branch information
rlane committed Mar 13, 2012
1 parent ad9e442 commit 5327065
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 0 deletions.
1 change: 1 addition & 0 deletions contrib/nacl/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.nexe
38 changes: 38 additions & 0 deletions contrib/nacl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Load81 Port to Google Native Client

## Requirements

* Google Chrome 15 or higher.
* Google App Engine Python SDK.
* Native Client SDK.
* NaclPorts with SDL and SDL_gfx built for i686 and x86\_64.
* NACL\_SDK\_ROOT environment variable set.

## Building

Ensure the above requirements are met, then run contrib/nacl/build.sh.

## Testing

Run dev_appserver.py contrib/nacl to start an HTTP server on port 8080. Follow
the instructions in the [Native Client documentation][1] to enable Native
Client in Chrome 15+. Now, open http://localhost:8080/ in Chrome and Load81
should start.

[1]: https://developers.google.com/native-client/pepper16/devguide/devcycle/running#Local

## Publishing

You will need to create a Google App Engine application first. Then:

appcfg.py -A $YOUR_APP_NAME update contrib/nacl

Now you need to create a Chrome application. Follow the instructions at the
[Chrome Developer's Guide][2], using contrib/nacl/chrome-app/manifest.json as
a template.

[2]: http://code.google.com/chrome/apps/docs/developers_guide.html

## TODO

* Support loading and saving local files.
19 changes: 19 additions & 0 deletions contrib/nacl/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
application: load81
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /
static_files: load81.html
upload: load81.html
- url: /load81.nmf
static_files: load81.nmf
upload: load81.nmf
- url: /load81-i686-nacl.nexe
static_files: load81-i686-nacl.nexe
upload: load81-i686-nacl.nexe
- url: /load81-x86_64-nacl.nexe
static_files: load81-x86_64-nacl.nexe
upload: load81-x86_64-nacl.nexe
44 changes: 44 additions & 0 deletions contrib/nacl/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh
# TODO use the common Makfile instead of duplicating it.
set -ex

if [ -z $NACL_SDK_ROOT ]
then
echo "NACL_SDK_ROOT must be set."
echo "example: NACL_SDK_ROOT=$HOME/nacl-sdk-update/pepper_15"
exit 1
fi

TOOLCHAIN=$NACL_SDK_ROOT/toolchain/linux_x86_newlib
NACL_ROOT=$(dirname $(which $0))
ROOT=$(readlink -f $NACL_ROOT/../..)
PKGS="sdl SDL_gfx"
EXAMPLE=asteroids.lua

for HOST in i686-nacl x86_64-nacl
do
cd $NACL_ROOT
export PKG_CONFIG_PATH=$TOOLCHAIN/$HOST/usr/lib/pkgconfig
export CC=$HOST-gcc
BFDARCH=i386
if [ $HOST == i686-nacl ]; then
BFDNAME=elf32-nacl
else
BFDNAME=elf64-nacl
fi
cp $ROOT/examples/$EXAMPLE example.lua
$HOST-objcopy -I binary -O $BFDNAME -B $BFDARCH example.lua example.o
rm example.lua
CFLAGS="-O2 -Wall -W -D main=load81_main `pkg-config --cflags $PKGS`"
LDFLAGS=""
for X in read write open close seek mount; do
LDFLAGS="$LDFLAGS -Xlinker --wrap -Xlinker $X"
done
LIBS="`pkg-config --libs $PKGS` -llua -lm -lppapi -lppapi_cpp -lnacl-mounts -lstdc++ -lnosys"
SRCS="$ROOT/load81.c $ROOT/editor.c $ROOT/framebuffer.c nacl.cc example.o"
$CC $CFLAGS $LDFLAGS $SRCS $LIBS -o load81-$HOST.nexe
rm example.o
$HOST-strip load81-$HOST.nexe
done

echo Built successfully
Binary file added contrib/nacl/chrome-app/icon_128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions contrib/nacl/chrome-app/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "rlane-load81",
"description": "Lua programming environment for kids similar to Codea",
"version": "0.0.0.1",
"icons": {
"128": "icon_128.png"
},
"app": {
"urls": [
"http://rlane-load81.appspot.com/"
],
"launch": {
"web_url": "http://rlane-load81.appspot.com/"
}
}
}
23 changes: 23 additions & 0 deletions contrib/nacl/load81.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<!-- Copyright 2011 Google Inc. All rights reserved. -->
<head>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache" />
<META HTTP-EQUIV="Expires" CONTENT="-1" />
<meta name="google-site-verification" content="F0mRaV3fORLaK_pqgwStp-jjrbVOw0-GIqgtKIQuBNc" />
<title>Load81</title>
</head>

<body>

<embed name="nacl_module"
id="nacl_module"
src="load81.nmf"
type="application/x-nacl"
width="800"
height="600"
tabindex="-1" />

</body>
</html>
6 changes: 6 additions & 0 deletions contrib/nacl/load81.nmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"program": {
"x86-64": {"url": "load81-x86_64-nacl.nexe"},
"x86-32": {"url": "load81-i686-nacl.nexe"}
}
}
143 changes: 143 additions & 0 deletions contrib/nacl/nacl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdexcept>

#include <ppapi/cpp/instance.h>
#include <ppapi/cpp/module.h>
#include <ppapi/cpp/rect.h>
#include <ppapi/cpp/size.h>
#include <ppapi/cpp/input_event.h>
#include <nacl-mounts/memory/MemMount.h>

#include <SDL_video.h>
#include <SDL.h>
#include <SDL_nacl.h>

extern "C" {
extern int load81_main(int argc, char *argv[]);
extern int mount(const char *type, const char *dir, int flags, void *data);
extern char _binary_example_lua_start[];
extern int _binary_example_lua_size;
}

/*
* Copied from earth sample in naclports.
*/
class Load81Instance : public pp::Instance {
public:
explicit Load81Instance(PP_Instance instance)
: pp::Instance(instance),
sdl_main_thread_(0),
width_(0),
height_(0) {
printf("PluginInstance\n");
}

~Load81Instance() {
if (sdl_main_thread_) {
pthread_join(sdl_main_thread_, NULL);
}
}

virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
printf("did change view, new %dx%d, old %dx%d\n",
position.size().width(), position.size().height(),
width_, height_);

if (position.size().width() == width_ &&
position.size().height() == height_)
return; // Size didn't change, no need to update anything.

if (sdl_thread_started_ == false) {
width_ = position.size().width();
height_ = position.size().height();

SDL_NACL_SetInstance(pp_instance(), width_, height_);
// It seems this call to SDL_Init is required. Calling from
// sdl_main() isn't good enough.
// Perhaps it must be called from the main thread?
int lval = SDL_Init(SDL_INIT_VIDEO);
assert(lval >= 0);
if (0 == pthread_create(&sdl_main_thread_, NULL, sdl_thread, this)) {
sdl_thread_started_ = true;
}
}
}

bool HandleInputEvent(const pp::InputEvent& event) {
SDL_NACL_PushEvent(event);
return true;
}

bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
if (RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD|PP_INPUTEVENT_CLASS_WHEEL)) {
throw std::runtime_error("failed to request filtering input events");
}

if (RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE)) {
throw std::runtime_error("failed to request input events");
}

/*
* The example Lua program is embedded in an object file by the NaCl build
* script.
* TODO: support loading local files.
*/
int fd = open("example.lua", O_CREAT | O_WRONLY);
if (fd < 0) {
perror("open");
return false;
}

if (write(fd, _binary_example_lua_start, (int)&_binary_example_lua_size) < 0) {
perror("write");
return false;
}

if (close(fd) < 0) {
perror("close");
return false;
}

return true;
}

private:
bool sdl_thread_started_;
pthread_t sdl_main_thread_;
int width_;
int height_;

static void* sdl_thread(void* param) {
char argv0[] = "load81";
char argv1[] = "example.lua";
char argv2[] = "--fps";
char *argv[] = { argv0, argv1, argv2, NULL };
load81_main(3, argv);
return NULL;
}
};

class Load81Module : public pp::Module {
public:
Load81Module() : pp::Module() {}

virtual ~Load81Module() {
}

virtual bool Init() {
return true;
}

virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new Load81Instance(instance);
}
};

namespace pp {
Module* CreateModule() {
return new Load81Module();
}
}

0 comments on commit 5327065

Please sign in to comment.