Monkey Amiga Targets
AmiMojo - The Beginning

Heute gibt es nichts zum downloaden, dafür aber ein Status-Update.
Das Target besitzt nun die Klasse "App". Diese Klasse ist der erste Schritt um dem AmigaTarget beizubringen jeden verfügbaren Monkey Code zu kompilieren. Um das zu erklären muss ich etwas ausholen:
Um mit Monkey ein Spiel schreiben zu können benötigt man das Modul "Mojo". Dieses importiert man einfach via "Import mojo". Nun werden zwei Dinge erwartet:
1. Es muss die Funktion "Main()" existieren. Sie ist der Einsprungpunkt für jedes Monkey-Programm.
2. Es muss eine Klasse existieren die von "App" abgeleitet ist und mindestens folgende Methoden definiert:
- OnCreate()
- OnUpdate()
- OnRender()
In der Funktion "Main()" erzeugt man nun eine neue Instanz dieser Klasse. Es wird dann automatisch die Methode "OnCreate()" aufgerufen. Ist diese Methode abgearbeitet springt Monkey abwechselnd in die Methoden "OnUpdate()" und "OnRender()" und führt den darin enthaltenen Code aus ... für immer.
Für immer?!? Ja, da Monkey für eine Reihe von Zielen kompiliert musste man sich auf den kleinsten gemeinsamen Nenner einigen und das sind Systeme auf denen eine App sich nicht selbst beenden muss, sondern vom System beendet wird: iOS, Android, WindowsPhone, XBox, Flash, HTML5. Das Einzige Ziel für das Mojo eine Abbruchbedingung vorsieht ist GLFW, dort wird die App beendet wenn das Fenster geschlossen wird.
Für das AmigaTarget habe ich die Methode "ExitApp()" implementiert damit der geneigte Programmierer selbst entscheiden kann wann sein Programm beendet wird. Es wird dann der Destructor aufgerufen der alle Libraries schliesst und den Speicher aufräumt.
Ein weiteres Merkmal von Mojo ist dass es dem Programmierer in Monkey nicht gestattet eine Bildschirmauflösung/Farbtiefe zu definieren, dies geschieht über die Templates die jedem Ziel zugeordnet sind. In Android ist es bspw. die "MonkeyApp.xml", unter GLFW muss die "config.h" geändert werden etc.
Damit das Amiga-Target dieses Verhalten nachahmt ruft das Modul automatisch die entsprechende Methode auf und erstellt ein Fenster auf der Workbench in der Grösse 600x400. Das ist notwendig damit die existierenden Monkey-Spiele auch auf dem Amiga kompiliert werden können.
Um zu unterbinden dass das geschieht ruft man den Konstruktor seiner App Klasse mit dem Wert "NOGRAPHICS" auf.
Will man irgendeinen Source kompilieren hat man natürlich das Problem dass der Author nicht wusste dass sein Spiel mal für Amiga kompiliert wird. Das heisst dass es sich nicht beenden lässt. Für diesen Fall habe ich IDCMP_CLOSEWINDOW an ExitApp() gehangen wenn "App" nicht mit "NOGRAPHICS" initialisiert wurde.
Einfach so kompilieren ist aber nicht. Das Problem ist dass ich kein weiteres "Mojo Target" programmieren darf. Ich müsste Mojo in weiten Teilen anpassen und diese Anpassungen mit dem Target mitliefern, das ist aber nicht gestattet. Wer also einen bestehenden Source für Amiga kompilieren will muss diesen leicht ändern. Man schaut einfach in den Kopf des entsprechenden Source und sucht die Zeile "import mojo". Diese ändert man dann in "#if TARGET = "aos3" ; Import amigaos3 ; #else ; Import mojo #endif". Danach kann man den Code dann einfach kompilieren.
Folgendes Bild zeigt ein einfaches Konsolenprogramm welches von 0 - 10 zählt. Links sieht man in welcher Methode die Ausgabe gemacht wurde. Die Steuerung der Methodenaufrufe ist durch das Modul "amigaos3" übernommen.
Hier der Source der die Ausgabe aus obigem Bild erzeugt:
Code: [AUSKLAPPEN]
Import amigaos3
Class myApp extends App
Field time:Int = 0
Method OnCreate()
Print "OnCreate : Los gehts... wir zählen von 0 - 10 und beenden dann das Programm"
End
Method OnUpdate()
Print "OnUpdate : time += 1"
time+= 1
if time > 10
Print "OnUpdate : time > 10 ... Ende!"
ExitApp()
EndIf
End
Method OnRender()
Print "OnRender : time = " + time
End
End
Function Main()
New myApp
End
Jetzt müssen alle Funktionen aus Mojo portiert werden. Viele davon werden einfach nichts tun weil sie mit dem Amiga NDK nicht zu realisieren sind, aber es werden genug Funktionen implementiert damit alle Monkey Spiele funktionieren.
Das Target besitzt nun die Klasse "App". Diese Klasse ist der erste Schritt um dem AmigaTarget beizubringen jeden verfügbaren Monkey Code zu kompilieren. Um das zu erklären muss ich etwas ausholen:
Um mit Monkey ein Spiel schreiben zu können benötigt man das Modul "Mojo". Dieses importiert man einfach via "Import mojo". Nun werden zwei Dinge erwartet:
1. Es muss die Funktion "Main()" existieren. Sie ist der Einsprungpunkt für jedes Monkey-Programm.
2. Es muss eine Klasse existieren die von "App" abgeleitet ist und mindestens folgende Methoden definiert:
- OnCreate()
- OnUpdate()
- OnRender()
In der Funktion "Main()" erzeugt man nun eine neue Instanz dieser Klasse. Es wird dann automatisch die Methode "OnCreate()" aufgerufen. Ist diese Methode abgearbeitet springt Monkey abwechselnd in die Methoden "OnUpdate()" und "OnRender()" und führt den darin enthaltenen Code aus ... für immer.
Für immer?!? Ja, da Monkey für eine Reihe von Zielen kompiliert musste man sich auf den kleinsten gemeinsamen Nenner einigen und das sind Systeme auf denen eine App sich nicht selbst beenden muss, sondern vom System beendet wird: iOS, Android, WindowsPhone, XBox, Flash, HTML5. Das Einzige Ziel für das Mojo eine Abbruchbedingung vorsieht ist GLFW, dort wird die App beendet wenn das Fenster geschlossen wird.
Für das AmigaTarget habe ich die Methode "ExitApp()" implementiert damit der geneigte Programmierer selbst entscheiden kann wann sein Programm beendet wird. Es wird dann der Destructor aufgerufen der alle Libraries schliesst und den Speicher aufräumt.
Ein weiteres Merkmal von Mojo ist dass es dem Programmierer in Monkey nicht gestattet eine Bildschirmauflösung/Farbtiefe zu definieren, dies geschieht über die Templates die jedem Ziel zugeordnet sind. In Android ist es bspw. die "MonkeyApp.xml", unter GLFW muss die "config.h" geändert werden etc.
Damit das Amiga-Target dieses Verhalten nachahmt ruft das Modul automatisch die entsprechende Methode auf und erstellt ein Fenster auf der Workbench in der Grösse 600x400. Das ist notwendig damit die existierenden Monkey-Spiele auch auf dem Amiga kompiliert werden können.
Um zu unterbinden dass das geschieht ruft man den Konstruktor seiner App Klasse mit dem Wert "NOGRAPHICS" auf.
Will man irgendeinen Source kompilieren hat man natürlich das Problem dass der Author nicht wusste dass sein Spiel mal für Amiga kompiliert wird. Das heisst dass es sich nicht beenden lässt. Für diesen Fall habe ich IDCMP_CLOSEWINDOW an ExitApp() gehangen wenn "App" nicht mit "NOGRAPHICS" initialisiert wurde.
Einfach so kompilieren ist aber nicht. Das Problem ist dass ich kein weiteres "Mojo Target" programmieren darf. Ich müsste Mojo in weiten Teilen anpassen und diese Anpassungen mit dem Target mitliefern, das ist aber nicht gestattet. Wer also einen bestehenden Source für Amiga kompilieren will muss diesen leicht ändern. Man schaut einfach in den Kopf des entsprechenden Source und sucht die Zeile "import mojo". Diese ändert man dann in "#if TARGET = "aos3" ; Import amigaos3 ; #else ; Import mojo #endif". Danach kann man den Code dann einfach kompilieren.
Folgendes Bild zeigt ein einfaches Konsolenprogramm welches von 0 - 10 zählt. Links sieht man in welcher Methode die Ausgabe gemacht wurde. Die Steuerung der Methodenaufrufe ist durch das Modul "amigaos3" übernommen.

Hier der Source der die Ausgabe aus obigem Bild erzeugt:
Code: [AUSKLAPPEN]
Import amigaos3
Class myApp extends App
Field time:Int = 0
Method OnCreate()
Print "OnCreate : Los gehts... wir zählen von 0 - 10 und beenden dann das Programm"
End
Method OnUpdate()
Print "OnUpdate : time += 1"
time+= 1
if time > 10
Print "OnUpdate : time > 10 ... Ende!"
ExitApp()
EndIf
End
Method OnRender()
Print "OnRender : time = " + time
End
End
Function Main()
New myApp
End
Jetzt müssen alle Funktionen aus Mojo portiert werden. Viele davon werden einfach nichts tun weil sie mit dem Amiga NDK nicht zu realisieren sind, aber es werden genug Funktionen implementiert damit alle Monkey Spiele funktionieren.
Update #3

Version 0.21 ist unter http://www.sedm.de/monkey/AmigaTarget.zip verfügbar.
Geändert hat sich dass ich ein paar Methoden überladen habe. Bislang hat SetColor() noch RGB Werte als Parameter genommen, man kann jetzt auch direkt die Stift Nummer übergeben. Neu hinzugekommen ist die Funktion "ClsColor()", auch diese ist überladen und kann sowohl Werte für Rot, Grün und Blau annehmen als auch eine Stift Nummer.
Der Fehler beim Build für Aros64 ist behoben, so dass jetzt auch AROS 64Bit User Monkey AmigaTarget verwenden können.
Der Versuch Mojo zu implementieren ist bisher fulminant fehlgeschlagen da AOS selbst bei einfachsten Klassen Operationen ohne lesbare Debug-Info ins Nirvana geht. Bin dort aber noch am Ball.
Ein ausführbares AOS3.x Executable für 0.21 liegt dem Archiv bei. Es ändert die Hintergrundfarbe auf ein freundliches Blau und malt mit gedrückter linker Maustaste nette rote Punkte in das erzeugte Fenster.
Das Example kann problemlos für AROS (egal ob i386, x86 oder x64) übersetzt werden.
Die Update Zyklen werden jetzt etwas länger weil ich ums Verrecken mein Mojo Derivat ans Laufen bekommen will. Endziel ist das Übersetzen aller verfügbaren Monkey Codes für AOS/Aros
Geändert hat sich dass ich ein paar Methoden überladen habe. Bislang hat SetColor() noch RGB Werte als Parameter genommen, man kann jetzt auch direkt die Stift Nummer übergeben. Neu hinzugekommen ist die Funktion "ClsColor()", auch diese ist überladen und kann sowohl Werte für Rot, Grün und Blau annehmen als auch eine Stift Nummer.
Der Fehler beim Build für Aros64 ist behoben, so dass jetzt auch AROS 64Bit User Monkey AmigaTarget verwenden können.
Der Versuch Mojo zu implementieren ist bisher fulminant fehlgeschlagen da AOS selbst bei einfachsten Klassen Operationen ohne lesbare Debug-Info ins Nirvana geht. Bin dort aber noch am Ball.
Ein ausführbares AOS3.x Executable für 0.21 liegt dem Archiv bei. Es ändert die Hintergrundfarbe auf ein freundliches Blau und malt mit gedrückter linker Maustaste nette rote Punkte in das erzeugte Fenster.
Das Example kann problemlos für AROS (egal ob i386, x86 oder x64) übersetzt werden.
Die Update Zyklen werden jetzt etwas länger weil ich ums Verrecken mein Mojo Derivat ans Laufen bekommen will. Endziel ist das Übersetzen aller verfügbaren Monkey Codes für AOS/Aros
Update #2

Neues Update
Der Monkey Code zum Bild:Code: [AUSKLAPPEN]
Changelog:Code: [AUSKLAPPEN]
12/01/2011 v0.2
added : Window.eventClass:Int()
added : Window.eventCode:Int()
added : Window.setColor:Void(r:Int, g:Int, b:Int)
added : Window.getBestPen:Int(r:Int, g:Int, b:Int)
added : Window.setAPen:Void(pen:Int)
added : Window.cls:Void()
added : Window.plot:Void(x:Int, y:Int)
added : Window.mouseX:Int()
added : Window.mouseY:Int()
added : Window.mouseDown:Int()
added : Window.mouseUp:Int()
added : EventClass:Int(win:Window)
added : EventCode:Int(win:Window)
added : SetColor:Void(win:Window, r:Int, g:Int, b:Int)
added : GetBestPen:Int(win:Window, r:Int, g:Int, b:Int)
added : SetAPen:Void(win:Window, pen:Int)
added : Cls:Void(win:Window)
added : Plot(win:Window, x:Int, y:Int)
added : MouseX:Int(win:Window)
added : MouseY:Int(win:Window)
added : MouseDown:Int(win:Window)
added : MouseUp:Int(win:Window)
changed : renamed Window.IntuiMessage:Int() to Window.WaitEvent:Int()
changed : renamed GetIntuiMessage:Int() to WaitEvent:Int()
fixed : windowtitle was not set
Download: http://www.sedm.de/monkey/AmigaTarget.zip
das AOS3 Executable liegt unter /bananas/Amiga/amiga.build/aos3/appAOS3
Viel Spass beim malen

Der Monkey Code zum Bild:Code: [AUSKLAPPEN]
Strict
Import amigaos3
Function Main:Int()
Local win:Window = CreateWindow("Hallo Amiga", 100, 100, 600, 400)
Local mx:Int = 0
Local my:Int = 0
Cls(win)
SetColor(win, 255, 0, 0)
Repeat
WaitEvent(win)
mx = MouseX(win)
my = MouseY(win)
If EventClass(win) = CLOSEWINDOW Then Exit
If MouseDown(win) then Plot(win, mx, my)
Forever
CloseWindow(win)
Return 0
End
Import amigaos3
Function Main:Int()
Local win:Window = CreateWindow("Hallo Amiga", 100, 100, 600, 400)
Local mx:Int = 0
Local my:Int = 0
Cls(win)
SetColor(win, 255, 0, 0)
Repeat
WaitEvent(win)
mx = MouseX(win)
my = MouseY(win)
If EventClass(win) = CLOSEWINDOW Then Exit
If MouseDown(win) then Plot(win, mx, my)
Forever
CloseWindow(win)
Return 0
End
Changelog:Code: [AUSKLAPPEN]
12/01/2011 v0.2
added : Window.eventClass:Int()
added : Window.eventCode:Int()
added : Window.setColor:Void(r:Int, g:Int, b:Int)
added : Window.getBestPen:Int(r:Int, g:Int, b:Int)
added : Window.setAPen:Void(pen:Int)
added : Window.cls:Void()
added : Window.plot:Void(x:Int, y:Int)
added : Window.mouseX:Int()
added : Window.mouseY:Int()
added : Window.mouseDown:Int()
added : Window.mouseUp:Int()
added : EventClass:Int(win:Window)
added : EventCode:Int(win:Window)
added : SetColor:Void(win:Window, r:Int, g:Int, b:Int)
added : GetBestPen:Int(win:Window, r:Int, g:Int, b:Int)
added : SetAPen:Void(win:Window, pen:Int)
added : Cls:Void(win:Window)
added : Plot(win:Window, x:Int, y:Int)
added : MouseX:Int(win:Window)
added : MouseY:Int(win:Window)
added : MouseDown:Int(win:Window)
added : MouseUp:Int(win:Window)
changed : renamed Window.IntuiMessage:Int() to Window.WaitEvent:Int()
changed : renamed GetIntuiMessage:Int() to WaitEvent:Int()
fixed : windowtitle was not set
Download: http://www.sedm.de/monkey/AmigaTarget.zip
das AOS3 Executable liegt unter /bananas/Amiga/amiga.build/aos3/appAOS3
Viel Spass beim malen

Update

Ich habe ein Update hochgeladen (gleiche URL) mit folgenden Änderungen:
AOS4 und MOS zicken noch rum da dort die Libraries anders geladen werden. Muss mich mal etwas einlesen wie dort der Ablauf ist. Wenn das alles gefixt ist kann man in Zukunft seine Programme mit einem Klick für AOS3, AOS4, MOS, AROSi386, AROSPPC und AROS64 kompilieren.
- steht in der config.winnt.txt AROS=1 werden Executables für Aros368, ArosPPC und Aros64 erzeugt
- es konnte für Aros nicht kompiliewrt werden weil dort USHORT nicht definiert war : behoben
- Das AmigaTarget funktioniert jetzt auch mit der Demo, es kann also jeder kostenlos nutzen
AOS4 und MOS zicken noch rum da dort die Libraries anders geladen werden. Muss mich mal etwas einlesen wie dort der Ablauf ist. Wenn das alles gefixt ist kann man in Zukunft seine Programme mit einem Klick für AOS3, AOS4, MOS, AROSi386, AROSPPC und AROS64 kompilieren.
1. Release

Das Amiga Target für AOS3 und AROS ist fertig: http://www.sedm.de/monkey/AmigaTarget.zip
1. Wichtig: Erstelle ein Backup von Deiner Monkey Instalklation!
2. Entpacke das Archiv und kopiere den Inhalt über Deine Monkey Installation
3. Installiere AmiDevCpp von http://amidevcpp.amiga-world.d...up.exe.php
4. füge den AmiDevCpp Bin Pfad ([AMIDEVCPP]\usr\local\amiga\bin) Deiner Windows "Path" Variable hinzu
5. Bearbeite [MonkeyDir]\bin\config.winnt.txt: Du kannst die Werte AOS3 und/oder AROS auf 1 setzen
6. lade /bananas/Amiga/amiga.monkey
7. Wähle "aos3" als Target
7.1. Wenn Du JungleIDE als IDE verwendest kannst Du neben dem Target auch die Kompilierungsart wählen. Wähle hier "Build". Die Standard-IDE versucht das Kompilat zu starten, was natürlich einen Fehler gibt. Keine Sorge, das Kompilat wurde dennoch erzeugt.
8. Kopiere das Executable auf das Zielsystem und starte es.
1. Wichtig: Erstelle ein Backup von Deiner Monkey Instalklation!
2. Entpacke das Archiv und kopiere den Inhalt über Deine Monkey Installation
3. Installiere AmiDevCpp von http://amidevcpp.amiga-world.d...up.exe.php
4. füge den AmiDevCpp Bin Pfad ([AMIDEVCPP]\usr\local\amiga\bin) Deiner Windows "Path" Variable hinzu
5. Bearbeite [MonkeyDir]\bin\config.winnt.txt: Du kannst die Werte AOS3 und/oder AROS auf 1 setzen
6. lade /bananas/Amiga/amiga.monkey
7. Wähle "aos3" als Target
7.1. Wenn Du JungleIDE als IDE verwendest kannst Du neben dem Target auch die Kompilierungsart wählen. Wähle hier "Build". Die Standard-IDE versucht das Kompilat zu starten, was natürlich einen Fehler gibt. Keine Sorge, das Kompilat wurde dennoch erzeugt.
8. Kopiere das Executable auf das Zielsystem und starte es.
Konfigurationen

Ich habe "Trans" ein paar Amiga spezifische Konfigurationen beigebracht. Man kann jetzt die Variablen AOS3, AOS4, MOS und AROS auf 1 setzen um ein Executable für diese Plattform zu erzeugen. Die Exes werden nacheinander erzeugt, so kann man in einem Rutsch für alle Targets kompilieren.
AOS4 und MOS werfen noch Exceptions, AROS funktioniert bereits. Das heißt dass man mit AOS3 = 1 und AROS = 1 jetzt mit einem Klick ein Kompilat für diese beiden Ziele erstellen kann wenn als Target "aos3" gewählt ist.
Es gibt grünes Licht für ein Release, also packe ich jetzt eine Distri zusammen und poste diese sobald alles nötige zusammen ist.
AOS4 und MOS werfen noch Exceptions, AROS funktioniert bereits. Das heißt dass man mit AOS3 = 1 und AROS = 1 jetzt mit einem Klick ein Kompilat für diese beiden Ziele erstellen kann wenn als Target "aos3" gewählt ist.
Es gibt grünes Licht für ein Release, also packe ich jetzt eine Distri zusammen und poste diese sobald alles nötige zusammen ist.
Es läuft!

Nach langem studieren und probieren ist es nun gelungen den M68K Crosscompiler von AmiDevC++ zu verwenden um Monkey-Code in ein Amiga Executable zu übersetzen.
Da das AmigaOS NDK einige Dinge definiert die Monkey auch für sich beansprucht musste ich eine alternative lang.cpp erstellen die die Klassen String und Object nach CString und CObject definiert so dass sie nicht mehr mit Definitionen des NDK kollidiert. Es mussten noch sehr viele andere Dinge an Monkey angepasst werden damit das funktioniert.
Ich habe noch kein grünes Licht von Mark Sibly dass das Target veröffentlicht werden kann da es sehr weite Teile von Monkey betrifft und mit jedem Update muss man ganz viele Sachen neu einrichten. Mark hat da halt ein wenig zuviel "gestreut" als er seine Targets implementiert hat.
Da dieses Target jetzt läuft wird der nächste Punkt sein die Targets AmigaOS4.x, MorphOS und AROS einzubinden. Das ist aber nur ein Switch des Compilers da alle Systeme Source-kompatibel sind.
Folgender Monkey Code wird anstandslos in ein Amiga (68k) Executable übersetzt:
Code: [AUSKLAPPEN]
Strict
Import amigaos3
Function Main:Int()
local myWin:Window = new Window()
myWin.Create("Hallo Amiga", 100, 100, 600, 300)
Local exitFlag:Bool = false
Repeat
Local msg:IntuiMessage = myWin.GetMessage()
Local cls:Int = msg.mClass
Local dta:Int = msg.mCode
Select cls
Case CLOSEWINDOW
Print "und tschuess"
exitFlag = True
Case VANILLAKEY
Print "Code: " + msg.mCode
End
Until exitFlag
myWin.Close()
Return 0
End
Auf dem Amiga wird dann ein Fenster geöffnet, wenn man eine Taste drückt wird der ASCII Code der Taste in der Shell ausgegeben und man kann das Fenster schliessen. Das sieht dann so aus:
Screenshot
Neben dem Einbinden der anderen Compiler steht nun die Portierung von Mojo auf dem Programm, so dass man dann einfach so ein weiteres Target bedienen kann.
Da das AmigaOS NDK einige Dinge definiert die Monkey auch für sich beansprucht musste ich eine alternative lang.cpp erstellen die die Klassen String und Object nach CString und CObject definiert so dass sie nicht mehr mit Definitionen des NDK kollidiert. Es mussten noch sehr viele andere Dinge an Monkey angepasst werden damit das funktioniert.
Ich habe noch kein grünes Licht von Mark Sibly dass das Target veröffentlicht werden kann da es sehr weite Teile von Monkey betrifft und mit jedem Update muss man ganz viele Sachen neu einrichten. Mark hat da halt ein wenig zuviel "gestreut" als er seine Targets implementiert hat.
Da dieses Target jetzt läuft wird der nächste Punkt sein die Targets AmigaOS4.x, MorphOS und AROS einzubinden. Das ist aber nur ein Switch des Compilers da alle Systeme Source-kompatibel sind.
Folgender Monkey Code wird anstandslos in ein Amiga (68k) Executable übersetzt:
Code: [AUSKLAPPEN]
Strict
Import amigaos3
Function Main:Int()
local myWin:Window = new Window()
myWin.Create("Hallo Amiga", 100, 100, 600, 300)
Local exitFlag:Bool = false
Repeat
Local msg:IntuiMessage = myWin.GetMessage()
Local cls:Int = msg.mClass
Local dta:Int = msg.mCode
Select cls
Case CLOSEWINDOW
Print "und tschuess"
exitFlag = True
Case VANILLAKEY
Print "Code: " + msg.mCode
End
Until exitFlag
myWin.Close()
Return 0
End
Auf dem Amiga wird dann ein Fenster geöffnet, wenn man eine Taste drückt wird der ASCII Code der Taste in der Shell ausgegeben und man kann das Fenster schliessen. Das sieht dann so aus:
Screenshot
Neben dem Einbinden der anderen Compiler steht nun die Portierung von Mojo auf dem Programm, so dass man dann einfach so ein weiteres Target bedienen kann.