Tuesday, April 15, 2014

C on Android

Quick notes about C on Android:

Makefile:
CC=/opt/arm-2009q1/bin/arm-none-linux-gnueabi-gcc
CFLAGS=-static

all: hello
hello.c:
#include <stdio.h>

int main(int argc, char** argv) {
   printf("hello world\n");
   return 0;
}
Build and run:
ctest$ make hello
/opt/arm-2009q1/bin/arm-none-linux-gnueabi-gcc -static    hello.c   -o hello
ctest$ adb push hello /sdcard/
282 KB/s (587310 bytes in 2.029s)
ctest$ adb shell /sdcard/hello
/system/bin/sh: /sdcard/hello: can't execute: Permission denied
Needs exec permission on sdcard, so create tmpfs with that permission, and group id (sdcard_rw)
ctest$ adb shell id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0
ctest$ adb shell
shell@msm8974:/ $ su
shell@msm8974:/ # mkdir /sdcard/bin
shell@msm8974:/ # mount -t tmpfs -o gid=1015 none /sdcard/bin
shell@msm8974:/ # mount
rootfs / rootfs ro,relatime 0 0
tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,size=956332k,nr_inodes=177623,mode=755 0 0
devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,seclabel,relatime 0 0
selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0
debugfs /sys/kernel/debug debugfs rw,relatime 0 0
none /acct cgroup rw,relatime,cpuacct 0 0
tmpfs /mnt/secure tmpfs rw,seclabel,relatime,size=956332k,nr_inodes=177623,mode=700 0 0
tmpfs /mnt/asec tmpfs rw,seclabel,relatime,size=956332k,nr_inodes=177623,mode=755,gid=1000 0 0
tmpfs /mnt/obb tmpfs rw,seclabel,relatime,size=956332k,nr_inodes=177623,mode=755,gid=1000 0 0
none /dev/cpuctl cgroup rw,relatime,cpu 0 0
/dev/block/platform/msm_sdcc.1/by-name/system /system ext4 rw,seclabel,relatime,discard,data=ordered 0 0
/dev/block/platform/msm_sdcc.1/by-name/userdata /data ext4 rw,seclabel,nosuid,nodev,relatime,discard,noauto_da_alloc,data=ordered 0 0
/dev/block/platform/msm_sdcc.1/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/block/platform/msm_sdcc.1/by-name/persist /persist ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/block/platform/msm_sdcc.1/by-name/modem /firmware vfat ro,relatime,uid=1000,gid=1000,fmask=0337,dmask=0227,codepage=cp437,iocharset=iso8859-1,shortname=lower,errors=remount-ro 0 0
/dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /storage/emulated/legacy fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
none /storage/emulated/legacy/bin tmpfs rw,seclabel,relatime,gid=1015 0 0
none /mnt/shell/emulated/0/bin tmpfs rw,seclabel,relatime,gid=1015 0 0
shell@msm8974:/ # ^D
shell@msm8974:/ $ ^D                                                          
Try running again
ctest$ adb push hello /sdcard/bin
128 KB/s (587310 bytes in 4.476s)
ctest$ adb shell /sdcard/bin/hello
hello world

Monday, April 22, 2013

DFDL good. XML bad.

I have just recently discovered DFDL, how could I have missed it for the past 10 years?  But why does it have to be based on XML schemas?!  Maybe I can write a conversion function that takes BNF/PEG grammar and outputs DFDL.

Tuesday, August 21, 2012

Final Fantasy VII

Best game for $10
http://na.square-enix.com/finalfantasyvii

Original Soundtrack music (better than converted MIDI)
http://forums.qhimm.com/index.php?topic=12787.msg187399#msg187399

Directshow Filters for OGG and WebM (to watch movies and listen to music outside the game)
http://xiph.org/dshow/

Friday, June 15, 2012

Word-aligned bytecode

Thinking about bytecode interpreters again... specifically variable-size instruction sets, and the detail that bugs me is that full-size words are often not word-aligned. In some cases (x86), the cpu will read an unaligned word, no problem. Otherwise the word needs to read byte-by-byte, and this inefficiency bothers me.

So here's an idea for a bytecode format that keeps all words aligned, separate from the instructions, but still interleaved with them. Assume a 32-bit word machine, 4 byte-sized instructions per word.


+--+--+--+--+ +-+-+-+-+ +-+-+-+-+ +--+--+--+--+
|i1|i2|i3|i4| | w1    | | w2    | |i5|i6|i7|i8|
+--+--+--+--+ +-+-+-+-+ +-+-+-+-+ +--+--+--+--+

Of the first four instructions, i2 and i4 require a word-sized argument. Each word argument moves the program counter after it is used.  When the word-sized batch of instructions are complete, the pc should point to the next batch of instructions. Here's the general idea for the interpreter loop:

while (...) {
  u32 ins = word[pc++];
  while (ins) {
    switch(ins & 0xff) {
      case 0: break; //noop
      case i2: arg = word[pc++]; break;
      case i4: arg = word[pc++]; break;
      case branch: pc = word[pc]; ins = word[pc++]; continue;
      ...
    }
    ins >>= 8;
  }
}

Friday, July 15, 2011

Euphoria dot-notation

I was reading this OpenEuphoria forum thread and I wondered,
what if we could use the Euphoria type mechanism to create aggregates with  dot-notation - using functions and procedures for getters and setters:


type foo (object o)
  return atom(o)
end type

function foo.id (atom this)
  return peek4u(this)
end function

procedure foo.id (atom this, atom value)
  poke4(this, value)
end procedure

foo ptr = allocate(4)
ptr.id = 3  -- implicitly calls foo.id(ptr, 3)
? ptr.id -- prints 3 -- implicitly calls foo.id(ptr)


This seems to be simple yet flexible and fits the spirit of Euphoria. It's also dang ugly and not as concise as C struct declarations. The same name for the procedure and functions could be confusing, but the interpreter will know to call the function or procedure based on context. Also, the type of the object is static - it doesn't get passed to functions or inside sequences.


What about nested aggregates? And pointers?

-- point { int x, int y }

type point (object this)  return atom(this)  end type
function point.x (atom this)  return peek4s(this)  end function
procedure point.x (atom this, atom x)  poke4(this, x)  end procedure
function point.y (atom this)  return peek4s(this+4)  end function
procedure point.y (atom this, atom y)  poke4(this+4, y)  end procedure
procedure point.init (atom this, sequence xy)  poke4(this, xy)  end procedure

-- line { point p1, point p2 }

type line (object this)  return atom(this)  end type
function line.p1 (atom this)  return this  end function
procedure line.p1 (atom this, point p)
  if p != this then
    memcpy(this, p, 8)
  end if
end function
function line.p2 (atom this)  return this+8  end function
procedure line.p2  (atom this, point p)
  if p != this+8 then
    memcpy(this+8, p, 8)
  end if
end procedure
procedure line.init (line this, sequence a, sequence b)
  this.p1.init(a)
  this.p2.init(b)
end procedure

line l1 = allocate(16)
l1.init({10, 15}, {20,25})
? {{l1.p1.x, l1.p1.y}, {l1.p2.x, l1.p2.y}} -- prints {{10, 15}, {20, 25}}

The only knowledge we have the type of line.p1 is the second argument in the setter procedure.  I hope that's enough.

I've also introduced method procedures in the above example, and I think it would be fine for functions too.

What about pointers?

-- line2 { pointer-to-point p1, pointer-to-point p2 }

type line2 (object o)  return 1  end type
function line2.p1 (atom this)  return peek4u(this)  end function
procedure line2.p1 (atom this, point p)  poke4(this, p)  end procedure
function line2.p2 (atom this)  return peek4u(this+4)  end function
procedure line2.p2 (atom this, point p)  poke4(this+4, p)  end procedure

line2 l2 = allocate(8)

l2.p1 = l1.p2  -- l2.p1 points to l1.p2
l2.p2 = l1.p1  -- l2.p2 points to l1.p1
? {{l2.p1.x, l2.p1.y}, {l2.p2.x, l2.p2.y}} -- prints {{20, 25}, {10, 15}}

Keeping track of the size of the aggregate gets to be a pain. A sizeof function might be nice.

Would this work for sequences too?

type bar (object o)
  return sequence(o)
end type

function bar.first (sequence this)
  return this[1]
end function

-- this must have special calling conventions where this is passed by reference
procedure bar.first (sequence this, object o)
  this[1] = o
end procedure

function bar.last (sequence this)
  return this[length(this)]
end function

-- this must have special calling conventions where this is passed by reference
procedure bar.last (sequence this, object o)
  this[length(this)] = o
end procedure

bar seq = {1, 2, 3}
seq.first = 5
? seq -- prints {5, 2, 3}
seq.last = 10
? seq -- prints {5, 2, 10}

This requires special casing the first argument of the setter procedures to be passed by reference.




Instead of an init procedure, what if we could use C99-like dot-notation in initialization:

foo ptr = { .id = 3 }

Wait, that doesn't make sense: the ptr hasn't been allocated before initialization.  What if we were to add constructors and destructors?

function foo._init ()
  return allocate(4)
end function

procedure foo._fini (object this)
  free(this)
end procedure

foo ptr = { .id = 3 }

The ._init function only gets called when ptr is created without an initializer.  The ._fini procedure gets called automatically when ptr refcount goes to zero (when it gets assigned a new value). Hopefully the existing refcount free mechanism can be modified to call the _fini function.

Wednesday, June 15, 2011

User content

Suppose there was a web site that allowed users to create games by simply drawing levels as you would draw using a paint program. Suppose this site allowed you to share created levels and search for levels created by others. I suspect the site would quickly become the penis-game site in no time. When I showed a prototype of such a site to my wife, I kid you not, the first thing she did was draw a penis made up of 1-up mushrooms.

Moderation or a rating system to prevent inappropriate images would be advisable.