Ocaml code for 2d vectors

December 11th, 2008

The convex layers of a point set, a data struc...Image via WikipediaFlying Frog consultancy has some great Ocaml tutorials. They also sell a book and access to Ocaml journal. When I made games in c++ I praised the fact that I used 2d vectors for all 2d stuff instead of separate x, y floats. This made code much shorter and I could do tons of simulation with basic vector operations (like acceleration’s, forces, collisions, rotations..).

One of the examples on FF Consultancy includes a very compact set of 2d vector functions and operators also. A great start to begin a dive at Ocaml game-dev experiment.

(* This is a comment (* mine *). Multiline comments can be nested. *)

(* We define a new type vec2. Vec2 is a record, one of OCaml’s data structures *)
type vec2 = { x: float; y: float }

(* We define a constructor function for this type. { } is there because we are
    creating a record, they don’t wrap a function like in c like languages *)
let vec2 x y = {x=x; y=y}

(* This is a function that creates the zero vector, it uses previously
    defined function vec2. *)
let zero = vec2 0. 0.

(* Surprisingly to some, OCaml doesn’t have operator overloading
    These are operators over vec2, again { } are here because of record *)
let ( +| ) a b = {x = a.x +. b.x; y = a.y +. b.y}
let ( -| ) a b = {x = a.x -. b.x; y = a.y -. b.y}
let ( ~| ) a = {x = -. a.x; y = -. a.y}
let ( *| ) s r = {x = s *. r.x; y = s *. r.y}

(* And some basic functions for vectors. *)
let normal a = { x = a.y; y = -. a.x }
let dot a b = a.x *. b.x +. a.y *. b.y
let length2 r = dot r r
let length r = sqrt(length2 r)
let unitise r = 1. /. length r *| r

(* example: the distance between two points *)
let distance r t = length r -| t

You can see that OCaml code is very compact. OCaml has a strict static type system, but if you look at the code I declared just the 2 floats. This is because OCaml compiler figures out of what type something is!

Ocaml is known for it’s speed that comes close to c++, but it provides a much safer and higher level programming environment. OCaml is an unpure functional language which can also do imperative and object oriented programming.

It’s very interesting language, different in a lot of ways to your papa’s cup of java/python/perl/c++ . Mainly, because it’s a functional language !

I wrote more about OCaml in my previous posts. This post was basically one of the first ones I tried to write but didn’t finish it back then, so I am posting it now.

Reblog this post [with Zemanta]

Make a $400 app in 30 REBOL lines!?

December 4th, 2008

I said I won’t write about REBOL for a while but I must echo this. Yesterday near midnight my client called with a problem at hand. He needed a niche functionality that is not so typical for webapps and is better solved with a separate running process. We googled the net to dig out more info from RFC-s and found 3 such apps that were selling for $400 (the third was a .NET componenet selling for $320). Their descriptions seemed scary and complicated. But I knew that this is a task where rebol’s unique features would really shine. So I wrote something that roughly does what that $400 app does in 30 lines of REBOL.

Well but I won’t tell you what this is. I might develop it further and sell it for half of that price. This is vengeance for all the “wtf is rebol, meh, ignore..” moments. ;)

Reblog this post [with Zemanta]

Hello? Web Framework? You’re OK, ok?

December 1st, 2008

CodeIgniter - Open source PHP web application ...Image by guspim via FlickrNot that I hate/fear/don’t-use frameworks, but I was always bashing them and saying if I can choose between library vs. framework approach I will always prefer the library one. My philosophy didn’t change, but I will admit one thing.

I was helping out some Slovene start-up as an additional pair of hands to make sure they catch the deadline last week. They had project developed in PHP with CodeIgniter web-framework. All coding was done by outsourced programmers from ex-Russian countries. They used ODesk and switched quite a big number of programmers and ended up with two really great coders. It was very interesting experience to me to not be the project “leader” ( e.g. - the one who coded the most of it and also calls the shoots) and to work with them. I learned A LOT!

And I admit, concretely, the code of this project made in CI was probably more readable, easier to grasp than my code with the previous project of this company. Especially the front-end code. I could debate about the backend, but OK.

There are also some other very strong benefits of using a well known framework.

  • When you are searching for programmers, you don’t spend days with them looking at the code, explaining the conventions and fighting about programming styles. You say.. project is in XY framework, get people that already know XY and they already know 90% of rules/conventions of coding this project.
  • A lot of bulky boring code is already written so you get free cake sometimes, where you would otherwise not have time to bake it. For example the upload library had tons of checks for detecting image formats, sizes, XSS filters.

Ok, that’s it. This is not like I used a framework for the first time now and realized that I was “wrong all this time”. I used frameworks, not just of web kind, since I started programming… I think I relatively well know what benefits they have and what shortcomings, but for this case I admit it, my version of code would be more minimalistic in concepts but worse to get into for new programmers.

Reblog this post [with Zemanta]

Python: Talking to Star Micronics POS printer thrugh serial port (lib)

November 30th, 2008

The computer in some shop that uses my program broke this week. Program was written years ago in Python and uses wxPython for GUI. It needed to communicate to those little squeaky printers that print bills. The whole thing looked kind of cute back then and still does. Python talks to the printer directly via serial port (without printer drivers or something like that) and it’s very simple. I used pyserial module. So in case there is someone somewhere who wants to connect his python to one of those particular printers he can do that with this little library:

download here: posprinter.py

Library has two classes, SerialPrinter is for talking to the printer, and ConsolePrinter is for simulating the same thing in console (for when you don’t have a printer, testing, developing..)

Usage is simple:

s = ConsolePrinter(None, 42)
headers  = [["NAME", "SURNAME", "AGE"]]
data  = [["mojca", "baz", "25"],["jana", "foo", "29"],["janko", "foo", "101"]]
format = ('', '', 'align=right')
tabs = (0, 15, 30, 42)

s.write('LIST OF PEOPLE:')
s.feed()
s.writeTable(headers, tabs, format)
s.line()
s.writeTable(data, tabs, format)
s.line('=')

Will print:

LIST OF PEOPLE

NAME           SURNAME                 AGE
------------------------------------------
mojca          baz                      25
jana           foo                      29
janko          foo                     101
==========================================

The code works on Star Micronics printers that have a serial port. You get a book with them that describe the binary commands that you have to send.


Random REBOL snippets: Cookie reader, Closures

November 28th, 2008

I posted a read-ff-cookies function in previous post. So I got a function that does what I used REBOL’s native read function for usually. But this one would send a cookie and behave more like FF.

It was used like this:

my-cookies: [ [ "cookiename" "a%3A2%3A%7Bs%3A11 %3A%22autologin..." ] ]

read-ff-cookie http://theurl cookie-str my-cookies

I provide cookie data as a series and it uses this func to turn it into proper cookie string:

cookie-str: func [ cs ] [ r: "" foreach c cs [ append r join c/1 [ "=" c/2 ";" ] ] r ]

It turned out I needed to call this sort of read on multiple locations of my crawler script and making cookie data global and passing it in each time didn’t look that good. So I made a make-cookie-reader that produces my read function with a cookie already “embedded” / enclosed.

make-cookie-reader: func [ c ] [ func [ url ] [ read-ff-cookies url cookie-str c ] ]

This function returns a function that takes just one argument (url) and uses the c (cookie) argument from the time of creation of the function. We can create our own read function:

my-read: make-cookie-reader my-cookies

Now I can use my-read with just the url parameter anywhere in code that I need it. Basically I just replaced all calls to read with my-read.

This is called closure. It worked for my case but I found out that if I would make two read functions using the make-cookie-reader the second one would change the first one too, which is not what we want. I went googling a little and found out few things:

Rebol 3 (now in the making) will natively support closures:

make-cookie-reader: closure [ c ] [ func [ url ] [ read-ff-cookies url cookie-str reduce [ c ] ] ]

Even more interesting thing.. I found the page of Ladislav, where he posts some MEGA AWESOME rebol libs. Well libs that can do what your ordinary language libs can only dream of doing. Like support for closures with the same syntax you see above in R2, custom control structures (cfor, pif), tailfunctions, currying, function inheritance?!, to name just few!

cfor [num: 0] [num <= 30] [num: num + 1] [
    if num = 15 [recycle]
    print num
]

pif [
    negative? x [-1]
    zero? x [0]
    true [1]
]

f: tailfunc [x [integer!] y [integer!]] [
    print x
    either x >= y [y] [f x + 1 y]
]

There are also some extensive docs. I could take a week off to just explore that page and code on it! This will be probably my last post on REBOL for a while because the crawlers are mostly done now.

Reblog this post [with Zemanta]

Random REBOL snippets: TCP, Cookies, Series

November 19th, 2008

The James Bond 007 Gun SymbolImage via WikipediaWell this week I was again making some spider in REBOL and this time I needed to hold a cookie to be able to crawl some pages. REBOL’s read function has some refinement to set custom http headers where you can also set cookies, but somehow it didn’t work for me. Because I was in hurry I ran listening HttpProxy made a request to that server with FireFox copied the headers and made rebol do the same request with raw TCP. I quickly discovered I need to load more pages like that so some generalization was in order. I made read-ff-cookies function out of it (most of it is a string… {this is multiline string with “quotes” btw in Rebol}):

read-ff-cookies: func [ address cookies ] [
    host: get-host address
    print join "loading: " [ host " ..." ]
    port: open to-url ( join "tcp://" [ host ":80" ] )
    insert port join {GET } [ address { HTTP/1.1
Host: } host {
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en,sl;q=0.7,en-gb;q=0.3
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Cookie: } cookies {

} ]
    result: copy port
    close port
    result
]

Series

btw.. REBOL has this (core) notion of series. You can use series to read/write to files, TCP connections, Strings, data structures, and even REBOL CODE. Series have this bunch of interesting functions that you can then use everywhere. Look at these two examples:

; here we manipulate a string with series functions
>> a: "Hi, I am Janko Metelko"
>> insert find a "Janko" "Mr. " print a
Hi, I am Mr. Janko Metelko

; here we use series functions to generate and then even change
; a function at run time
>> a: copy []
>> insert a "HI!"
>> probe a
["HI!"]
>> insert a 'print
>> probe a
[print "HI!"]
>> do a
HI!
>> say: func [] a
>> probe :say
func [][print "HI!"]
>> say
HI!
>> change next second :say-hi "BYEBYE!"
>> say
BYEBYE!
>> probe :say
func [][print "BYEBYE!"]

An interesting tidbit that also uses series and I copied from some web example is get-host function that I needed in first examle. Definition is:

get-host: func [ url ] [ third parse url "/" ]

Raw TCP

So, to create a TCP client that sends some data and reads the response you do just this:

>> con: open tcp://localhost:5321
>> insert con join "007" newline
>> print copy con
James, James Bond

And if we are making a client, let’s make a simple blocking server too that will act as shown in above client example. You give it the number of agent and it returns your name:

REBOL []
print "secret MI5 server"
agents: [ 	"006" "Seinfeld"
		"007" "James, James Bond" ]
srv: open/lines tcp://:5321
forever [
	con: first srv
	wait con
	insert con ( second ( find agents ( first con ) ) )
	close con
]

This post had different title, but I totally strayed from my intent when writing it, so I changed the whole point of the post
Reblog this post [with Zemanta]

Embedding NekoVM with compiled Haxe code into C/C++ application

November 13th, 2008

C++ calls Neko

You can see how to embed NekoVM and make calls from C/C++ application to the Neko code on this page.

To reacap. You create a (exported) neko function like this:

$exports.add = function(a, b) { return a + b; }

And call it from c++ like this:

int n_add(value module)
{
    value n_add = val_field(module,val_id("add"));
    if( val_is_function(n_add, 2) )
    {
        value ret = val_call2(n_add, 3, 5);
        if(val_is_int(ret))
            return val_int(ret));
    }
    return 0;
}

I will show an example of doing the same if you are writing your code in Haxe language and compiling it to Neko. The whole logic is the same. Only the structure of compiled neko module is a little different.

C++ calls Haxe

So let’s say you write a class like this in Haxe:

class MyTest
{
	static function add(a:Float, b:Float) : Float
	{
            return a + b;
	}
}

You compile it… if you want to see what is happening add the –neko-source to the compiler call so you can see the neko source that get’s generated from your haxe class. After some degree of banging my head looking at this and asking on mailing list and irc I found out that this is the way to do it.

The compiled haxe class exposes the __classes field. And the haxe class you made is a neko object with static functions and variables being accessible throught it. So how do you call the above then:

int add(value module)
{
	value c = val_field(module,val_id("__classes"));
	if( val_is_object(c))
	{
		value o = val_field(c,val_id("MyTest "));
		if( val_is_object(o))
		{
			value f = val_field(o,val_id("add"));
			if( val_is_function(f))
			{
				value ret = val_call2(f, 3, 5);
                               if(val_is_int(ret))
                                   return val_int(ret));
			}
		}
	}
        return 0;
}

This is it. You can download, run and look at the haxe code where I used this (and reverse) in small example in my post Haxe & NekoVM meet PTK

.. about reverse. This post deals with calling functions from our c++ application into the embeded NekoVm only. If you are making something lika a game engine then you will probably need to call from the called neko functions back to c++ functions. I will post a tutorial about that too for Neko (but not Haxe - I haven’t figured clean way to do this with haxe, so I made sort of an ugly hack to get my stuff working).


Few observations regarding artists for games

November 5th, 2008

tween artImage by Homies In Heaven via FlickrI recently made a public request for offers, searching for an artist for our game BraveKid’s Summer Job in Outer Space. These are few facts that could be interesting to someone for some reason.

The request was relatively exact, with number of different sorts of drawings we need. I posted examples of them so artist could get an idea of size, detail and style of art we are looking for.

We got 14 offers, the last came roughly after a week.

We pinned down 6 of offers that we thought were all really good artists and have the style approximately to what we want.

With one exception the best 6 artists were also the cheapest 6.

The lowest price was 1/8 of the highest price, with lowest not being worse quality than the highest.

The location of the artist (cheap to live countries / expensive to live countries) didn’t seem to reflect in the prices of the offers in most cases.

The artist we decided to go with was from UK (one of the most expensive countries) and was almost 2x cheaper than offer from also good artist from here, Slovenia.

It was hard to decide of just one of them and at the end it falls more to subjective reasons than objective. We gained contacts of a lot of interesting and good artist that we might want to work with on another projects. We also now know for one Slovenian artist/company which can do good art at more or less accessible prices.

Reblog this post [with Zemanta]

Mochiads injection

November 4th, 2008

Thanks to relatively new feature of mochiads I could now inject their version control, pre-loader and ads into my flash games written in Haxe with F8 API without writing any code at all. Nice. I tested in on this game.

Too bad I couldn’t do this when I released it, as this game has already been distributed all around the web. So I have no other choice than to make a new one..

Interesting note maybe. Mochiads and their other services all run on Erlang and the company also open sourced their server/framework.. it called it.. well you know.. Mochiweb :) . So if you need to scale, just get Mochi!

Reblog this post [with Zemanta]

Factor goes to Hollywood

October 26th, 2008

Factor, one of the programming languages that intrigue me the most (I made server of not yet released Ask Robi with it and am starting another project), will recieve 3 talks in next days. One of them will be at Hollywood of geeks - Google. The good news is that the talk should be accessible on Google video (hopefully soon).

Link to the post

Reblog this post [with Zemanta]

Whack the dead: PTK on iPhone

October 14th, 2008

I was just mentioning PTK and certain rumors :) and today I saw the review of a game made in PTK for iPhone.


Comment on youtube:

You are killing the good guys too ! this is a big part of the game to not kill the good guys !

You can get the iPhone game here.

Reblog this post [with Zemanta]

Check webpages for text in REBOL

October 13th, 2008

A guy asked at some forum that I frequent where he can find some apps that test a list of webpages if some text exists on them. Well I don’t know for such programs but this shouted for few quick lines of REBOL so I posted them to him, and here too if I am already writing..

check: func [ url text ] [ if/else find read url text [ "ok" ] [ "OOPS!" ] ]
check-sites: func [ sites ] [ foreach site sites [ print join site/1 [ ": " check site/1 site/2 ] ] ]

so you go to rebol console and use it like this:

check-sites [ [ http://www.najdi.si "najdi.si" ] [ http://www.google.com "microsoft" ] ]

and console says:

connecting to: www.najdi.si
http://www.najdi.si : ok
connecting to: www.google.com
http://www.google.com : OOPS!

Of course this is very simple example script, but it can be a basis for adding logging, sending emails on errors, checking multiple strings per page .. whatever.

Reblog this post [with Zemanta]

Haxe & NekoVM meet PTK

October 12th, 2008

I have embedded nekoVM with Haxe compilation into a PTK based 2D game engine. It’s all still very early, but this is the first test app:

neko plus ptk

If you have windows you can download it and try it for yourself. You can see Haxe source in NekoPtkGame.hx inside zip. I will write few tutorials about embedding nekoVM/Haxe into c++ app soon. PTK is one of the most solid and tested 2D game libraries that work on Windows and Mac computers. Direct link here.

//edit: I added the missing link to zip

Reblog this post [with Zemanta]

BraveKid’s Summer Job in Outer Space #2

October 6th, 2008

Some progress has been made:

BK:SJOS

All graphics is just programmer’s art.. we are talking to / seeking the artists.


RIP ITM Metelko, k.d.

October 2nd, 2008

long live REFAKTOR d.o.o.