Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Nov 23, 2024 10:42

Foren-Übersicht » Sonstiges » Projekte
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: BroodTech Game Engine
BeitragVerfasst: Mi Apr 03, 2013 09:32 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
BroodTech Game Engine

Die BTGE ist eine Grafik Engine und Script Interpreter, speziell für klassische Textspiele. Den Kern bildet dabei eine "Konsole" für die Text Aus- und Eingaben. Diese "Konsolenanwendung" wird in der hauseigenen Scriptsprache geschrieben und diktiert den gesamten Programmablauf.

Ueber den "draw"-Befehl kann das Bild auf verschiedene Weise geteilt werden um einen Bereich für grafische Ausgabe zu schaffen. Hierfür koennen Sprites aus Bild- oder 3D-Daten geladen und animiert werden.

Bisher Implementiert:
- TextScript
- Dark Radiant .map loading
- Texture loading
- Garbage Collection
- Midi loading \m/

Noch zu erledigen:
- Radiosity Shader (~30%)
- Animationen (~20%)
- Erweiterung von TextScript (never ending story :) )

zum Schluss noch ein Screenshot vom CSG System


Dateianhänge:
screenshot1.PNG [149.65 KiB]
Noch nie heruntergeladen

_________________
Meine Homepage
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Mo Apr 08, 2013 14:45 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Mal ein kleines Update vom Wochenende:

Scripte

- Neben normaler Texteingabe steht nun auch die "bind {key} {Funktion}" Anweisung zur Verfügung. Auf diese Weise kann man zum Beispiel auch die Cursor Tasten verarbeiten.

Renderer

- GLSL support

- Deferred Sharing wurde eingebaut.

- Dazu noch: Ich habe begonnen einen Raytracer zu implementieren. Dieser soll dann die Lichtpunkt für Instant Radiosity erzeugen.

- Frame Updates prüfen nun das Datum von verwendeten Dateien, und lädt diese bei Aktualisierungen neu.

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Di Apr 16, 2013 19:56 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Renderer
Die Präzision der Texturen vom Render-To-Texture wurde erhöht. Dadurch können nun auch größere Maps gut dargestellt werden.

Radiosity wurde rausgeschmissen da es zu crappy aussah und zu viel Performance gefressen hat. Dafür gibts nun hübsche Spotlichter :)

Scripte
Der Befehl "move" (Variablen Zuweisung) kann nun auch Terme verarbeiten.

Der Befehl "free" (Bildschirm löschen) hat nun noch einen optionalen Boolean Parameter. Über diesen kann man bestimmen ob Grafik oder Text gelöscht wird. Default ist sozusagen "jein", also beides.


Dateianhänge:
btge1.PNG [134.33 KiB]
Noch nie heruntergeladen

_________________
Meine Homepage
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Do Apr 18, 2013 20:21 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
hab gerade einen Compiler für eine einfachere Form der Scripte geschrieben. Dieser übersetzt die C ähnlichen Scripte in die
11 Textbefehle der Engine.



Code:
  1.  
  2. // c-style comments
  3. /*      .____          .____    
  4.  *      |    |    ____ |    |    
  5.  *      |    |   /  _ \|    |    
  6.  *      |    |__(  <_> )    |___
  7.  *      |_______ \____/|_______ \
  8.  *              \/             \/
  9.  */
  10.  
  11. portrait("throne.map");
  12.  
  13. //Funktionen
  14. void guessHallo(number counter) {
  15.     string test = readln();
  16.     //if statements
  17.     when(counter,"^0")
  18.         return;
  19.     //blöcke
  20.     when(test,"^hallo") {              
  21.         print("thats right!");
  22.         return;
  23.     }
  24.     print("thats wrong, please try again.");
  25.     //operatoren (gibts auch für strings ;))
  26.     guessHallo(counter - 1);
  27. }
  28. guessHallo(5);
  29. print("press any key to close");
  30. readkey();
  31.  


Die Library umfasst derzeit folgende Funktionen:
print(string, ... of string)
==>Textausgabe
sleep(number)
==>N-Millisekunden warten
when(string,string)
==>Eine Regex über den ersten String matchen
landscape(string)
==>.map Datei laden und im vertikalen Modus ausgeben
portrait(string)
==>.map Datei laden und im horizontalen Modus ausgeben
clrscr();
==>Grafische Ausgabe löschen
clrtxt();
==>Textausgabe löschen
string readkey();
==>Taste auslesen
string readln();
==>Zeile auslesen
string read(number);
==>N-Tasten auslesen

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Do Mai 16, 2013 17:49 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Die letzten Tage habe ich an einen Nachfolger für eine meiner Bibliotheken, namens libcrpt, gearbeitet. Diese woche ist nun die libcrpt2 fertig geworden und die letzten beiden Tage habe damit verbracht sie in die Engine einzubauen. Dadurch können nun der bisherige Interpreter, Mapparser und die kommenden Scripte endlich vereinheitlich werden. Der Mapparser ist schon erledigt und die Gamescripte umfassen schon jetzt:

Schleifen (while,do-while,for,foreach)
Branching (if,else,switch,goto,return,label,usw. )
Funktionen
Variablen
Blockstatments
alle möglichen Expressions
Storageclass (static, ref, const, extern)
Ellipsen
Anonyme Funktionen
Garbage Collection
Fiber

Void
Bool
Integer
Float
String
Delegaten (\m/)


Try
Catch
When (wie bei VB)
Fault
Throw

blah blah blah ... typedefs fehlen leider noch um die wirklich coolen Dinge zu machen

naja stellt euch einfach vor C# wäre mehr C als Java....

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Fr Jul 19, 2013 17:13 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
So der Prototyp ist fertig und wird nun nach Objective-C (gnu-runtime) uebertragen. Die letzten Tage habe ich erst einmal massive bug-fixes und refactoring an der general obj-c lib vorgenommen (release kommt) bald und den boehm-gc compeliert (koennen diese Linuxpunker nicht mal nen funktionierenden installer oder sowas schreiben?). Ansonsten ist von der Engine selbst schon ein sehr grosser Teil konvertiert worden.

So pi mal Daumen fehlen also nur noch:
-die objective-c runtime
-der script-interpreter
-der 3D-Modus

achja und das Projekt wird Open Source (Schnapps Lizenz) :P

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Mi Jul 31, 2013 09:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Update Time *wuuuuuush* :mrgreen: :

Ich habe die letzten Tage damit begonnen die Objective-C Runtime zu implementieren und libobjc rausgeschmissen. Zur Zeit unterstuetzt meine Version die grundlegenden OOP Features wie Klassen, Instanzen und Vererbung (voll geil das man den Kram selbst schreiben kann :mrgreen: ). Des Weiteren ist die Speicherverwaltung auch etwas einfacher da alle nicht-konstanten Pointer zusammen mit der Instanz selbst freigegeben werden. Grob gesagt kann man also schon ziehmlich gut damit arbeiten. Fuers erste fehlen noch Kategorien, Protokolle und Properties.

Achja bei einen kleinen Experiment hat sich uebrigens eine meiner Vermutungen bestaetigt. Es ist naemlich moeglich waerend der Laufzeit einen Wrapper um jeden Funktionsaufruf (innerhalb der Runtime) zu legen. Ich bin mir noch nicht ganz sicher ob ich das wirklich nutzen will (ellipse nach ellipse halt -.-), aber es koennte zu ein paar wirklich coolen Features fuehren.

[edit]
achja wer will kann Zugang zum GIT bekommen, einfach PM an mich dann.

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Do Sep 19, 2013 12:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Ok ich war in letzter Zeit etwas knapp mit Updates (zuviel Mechwarrior :)), das soll sich aber nun ändern.

Ich habe mich nun doch gegen den Garbage Collector entschieden. Es wäre einfach zuviel Arbeit für ein mehr oder weniger instabiles Feature gewesen. Dafür gibt es aber nun eine einheitliche Speicherverwaltung für Objective C und normale C Typen. Das tolle daran ist dass hier auch gleich alle inneren Referenzen freigegeben werden wenn ein Objekt gelöscht wird, außer wenn der Compiler oder Programmierer diese als Strong-Pointer gekennzeichnet hat.

Des Weiteren sind die Funktion "strex" und der "heap" Datentyp nun fertig. "strex" ist für die Evaluation von Ausdrücken in String-Form zuständig und somit der wohl wichtigste Bestandteil des Interpreters. Beim Design habe ich mir folgende Regeln aufgestellt:
-Alles ist eine Zahl vom Typ Double,Long Integer oder Boolean.
-Alle Nicht-Zahlen und nicht Operatoren sind externe Funktionen die Zahlen zurückgeben.
-Alle unären Operatoren stehen vor dem Operanden, also z.B. nur ++i und kein i++
Wenn nun z.B. ein String-Literal kommt dann muss dieser von einer, zuvor registrierten Funktion, in eine Addresse umgewandelt werden.

Mindestens genauso wichtig wie die "strex" Funktion ist die Heap Struktur. Diese dient vor allen dazu Addressen zu verwalten und orientiert sich von der Funktionsweise an das gute alte "malloc" und "free". Einen Wrapper wie bei der normalen Speicherverwaltung sollte ohne Probleme möglich sein (man muss ja so oder so Reflection einbauen).

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Mi Aug 13, 2014 22:02 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Lange ist es her das sich hier mal was getan hatte. Heute habe ich endlich mal wieder etwas Zeit gefunden. Und wie das so ist fand ich meinen Code mittlerweile eher suboptimal :)

Für die neue "Version" habe ich erst einmal das Projekt in Netbeans, statt DevCpp aufgesetzt. Für Objective-C ist es zwar genauso gut, dafür ist aber der normale C Code wesentlich besser. Und im Gegensatz zu Eclipse muss man keine große Magic zum Verwalten der Code-Dateien machen. Nachdem das in 2h erledigt war (fragt lieber nicht), habe ich nun erst einmal die Runtime ins neue Projekt geholt. Dabei habe ich auch gleich einmal etwas aufgeräumt und so weiter.

Morgen nach der Arbeit geht es dann weiter mit der Allgemeinen Basis-Klasse. Dabei will ich vor allen Speicherverwaltung etwas aufpolieren um mehr als brutale dynamische Allokation zu machen.

Zum Schluss noch der Quellcode der neuen Runtime:


Code:
  1.  
  2.  
  3. /*
  4.    BroodTech Objective-C Runtime
  5.    Created by Alex 'YunHarla' Schmidt
  6.  
  7. The following provides a more lightweight version of the objective-c
  8. runtime I found with my MINGW installation. Since I'm no lawyer I just
  9. include the original copyright, I found with it's source. If stuff
  10. needs to be changed or if you have improvements / bug reports you can
  11. send me an email at <info@broodtech.de>
  12.  
  13.    GNU Objective-C Runtime API - Modern API
  14.    Copyright (C) 2010 Free Software Foundation, Inc.
  15.    Contributed by Nicola Pero <nicola.pero@meta-innovation.com>
  16.  
  17. This file is part of GCC.
  18.  
  19. GCC is free software; you can redistribute it and/or modify it
  20. under the terms of the GNU General Public License as published by the
  21. Free Software Foundation; either version 3, or (at your option) any
  22. later version.
  23.  
  24. GCC is distributed in the hope that it will be useful, but WITHOUT
  25. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  26. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  27. License for more details.
  28.  
  29. Under Section 7 of GPL version 3, you are granted additional
  30. permissions described in the GCC Runtime Library Exception, version
  31. 3.1, as published by the Free Software Foundation.
  32.  
  33. You should have received a copy of the GNU General Public License and
  34. a copy of the GCC Runtime Library Exception along with this program;
  35. see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  36. <http://www.gnu.org/licenses/>.  */
  37.  
  38. #include <string.h>
  39. #include <objc/runtime.h>
  40.  
  41. //the following types and definitions are taken directly from the
  42. //original source... just with typedefs instead of just struct
  43. //because most people i know may mistake it for a local variable otherwise.
  44. #define __CLS_INFO(cls) ((cls)->info)
  45. #define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask)
  46. #define _CLS_META 0x2L
  47. #define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META))
  48. #define _CLS_CLASS 0x1L
  49. #define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS))
  50.  
  51. typedef struct objc_list {
  52.     void *head;
  53.     struct objc_list *tail;
  54. } objc_list_t;
  55.  
  56. //because this stuff only is done ONCE during initialization i don't really
  57. //care about deallocation here. You might want to use the original objc-list
  58. //header (<objc/objc-list.h>) instead.
  59. static objc_list_t objc_lists[0xFFFFF];
  60. static objc_list_t* cur_objc_list_head = &(objc_lists[0]);
  61.  
  62. struct objc_list* objc_list_cons(void* head, struct objc_list* tail) {
  63.     struct objc_list* cell;
  64.     cell = cur_objc_list_head++;
  65.     cell->head = head;
  66.     cell->tail = tail;
  67.     return cell;
  68. }
  69.  
  70. typedef struct objc_symtab {
  71.     unsigned long sel_ref_cnt;
  72.     struct objc_selector *refs;
  73.     unsigned short cls_def_cnt;
  74.     unsigned short cat_def_cnt;
  75.     void *defs[1];
  76. } objc_symtab_t;
  77.  
  78. typedef struct objc_module {
  79.     unsigned long version;
  80.     unsigned long size;
  81.     const char* name;
  82.     struct objc_symtab *symtab;
  83. } objc_module_t;
  84.  
  85. typedef struct objc_static_instances {
  86.     char *class_name;
  87. #ifdef __cplusplus
  88.     id instances[1];
  89. #else
  90.     id instances[0];
  91. #endif
  92. } objc_static_instances_t;
  93.  
  94. typedef struct objc_method {
  95.     char* method_name;
  96.     const char* method_types;
  97.     IMP method_imp;
  98. } objc_method_t;
  99.  
  100. typedef struct objc_method_list {
  101.     struct objc_method_list* method_next;
  102.     int method_count;
  103.     struct objc_method method_list[1];
  104. } objc_method_list_t;
  105.  
  106. typedef struct objc_ivar {
  107.     const char* ivar_name;
  108.     const char* ivar_type;
  109.     int ivar_offset;
  110. } objc_ivar_t;
  111.  
  112. typedef struct objc_ivar_list {
  113.     int ivar_count;
  114.     struct objc_ivar ivar_list[1];
  115. } objc_ivar_list_t;
  116.  
  117. struct objc_super {
  118.     id self;
  119.     Class super_class;
  120. } objc_super_t;
  121.  
  122. //this is my replacement for the original hash tables
  123. //because a tree was slightly of faster for me
  124. typedef struct objc_cls_tab_node {
  125.     char key;
  126.     Class value;
  127.     struct objc_cls_tab_node * next;
  128.     struct objc_cls_tab_node * first;
  129. } objc_cls_tab_node_t;
  130. static objc_cls_tab_node_t cls_tab[0xFFFF];
  131. static objc_cls_tab_node_t * cur_cls_tab_head = &(cls_tab[0]);
  132. static objc_list_t *uninitialized_statics = 0;
  133.  
  134. //NOTE:
  135. //the following two methods are the great bottlenecks
  136. //of objective-c. They are called in almost any case
  137. //and you cannot use the designated fields because
  138. //a pointer to a name or selector or class may change.
  139.  
  140. //Returns the class associated with the c-string pointed
  141. //to by name. The compiler automatically inserts this
  142. //in numerous occasions. For example when the code calls
  143. //a static method
  144. Class objc_get_class(const char *name) {
  145.     objc_cls_tab_node_t * tab = &(cls_tab[0]);
  146.     while (*name && tab->first) {
  147.         tab = tab->first;
  148.         while (tab->key != *name) {
  149.             tab = tab->next;
  150.         }
  151.         name++;
  152.     }
  153.     return tab->value; //if we return null it will crash anyway, so let's ignore error handling
  154. }
  155.  
  156.  
  157.  
  158. //Return a method with the signature pointed to by op
  159. //from the class pointed to by cls. This is called
  160. //EVERYTIME objective-c does calls some class or instance
  161. //method.
  162. IMP get_imp(Class cls, SEL op) {
  163.     if (cls) {
  164.         if (CLS_ISCLASS(cls) || CLS_ISMETA(cls)) {
  165.             objc_method_list_t * method_list = cls->methods;
  166.             while (method_list) {
  167.                 for (int i = 0; i < method_list->method_count; i++) {
  168.                     objc_method_t * m = &(method_list->method_list[i]);
  169.                     if (strcmp(op->sel_id, m->method_name)) {
  170.                         continue;
  171.                     }
  172.                     if (op->sel_types) {
  173.                         if (strcmp(op->sel_types, m->method_types)) {
  174.                             continue;
  175.                         }
  176.                     }
  177.                     return m->method_imp;
  178.                 }
  179.                 method_list = method_list->method_next;
  180.             }
  181.            
  182.             const char * superclass = (char *) cls->super_class;
  183.             if (superclass) {
  184.                 if (CLS_ISMETA(cls))
  185.                     return get_imp(objc_get_class(superclass)->class_pointer, op);
  186.                 else
  187.                     return get_imp(objc_get_class(superclass), op);
  188.             }
  189.         }
  190.  
  191.     }
  192.     return NULL;
  193. }
  194.  
  195. //This automatically gets inserted by the compiler and
  196. //initializes all classes and statics of a module
  197. //(source file). It's guaranteed to be called before
  198. //a class is used, however most compilers will use
  199. //this right before the "main" method is invoked.
  200. void __objc_exec_class(struct objc_module *module) {
  201.     static unsigned char init = 1;
  202.     if (init) {
  203.         memset(cls_tab, 0, sizeof (cls_tab));
  204.         init = 0;
  205.     }
  206.     objc_symtab_t * symtab = module->symtab;
  207.     void ** defs = symtab->defs;
  208.     int i = 0;
  209.     int num_classes = symtab->cls_def_cnt;
  210.     for (; i < num_classes; i++) {
  211.         objc_cls_tab_node_t * tab = &(cls_tab[0]);
  212.         Class cls = (Class) defs[i];
  213.         const char * name = cls->name;
  214.         //insert a name into our class tree
  215.         while (*name) {
  216.             //move to and maybe create the next level of our tree
  217.             //each level stores every possible character for the current
  218.             //position
  219.             if (tab->first) {
  220.                 tab = tab->first;
  221.             } else { //no node for this length so create and assign a new one
  222.                 tab = tab->first = cur_cls_tab_head++;
  223.                 tab->key = *name;
  224.             }
  225.             //check each added character of the current level
  226.             while (tab->key != *name) {
  227.                 if (tab->next) {
  228.                     tab = tab->next;
  229.                 } else {
  230.                     //no node for this character so create an assign a new one
  231.                     tab = tab->next = cur_cls_tab_head++;
  232.                     tab->key = *name;
  233.                 }
  234.             }
  235.             name++;
  236.         }
  237.         tab->value = cls;
  238.     }
  239.     //initialize static instances (if any) or resume initializing
  240.     //all previous uninitialized statics. Statics are stuff like
  241.     //constant strings (which store the LENGTH!!!!).
  242.     objc_static_instances_t ** statics = defs[i + symtab->cat_def_cnt];
  243.     if (statics) {
  244.         uninitialized_statics = objc_list_cons(statics, uninitialized_statics);
  245.     }
  246.     if (uninitialized_statics) {
  247.         objc_list_t **cell = &uninitialized_statics;
  248.         struct objc_static_instances **statics_in_module;
  249.         while (*cell) {
  250.             unsigned char module_initialized = 1;
  251.             Class cls;
  252.             for (statics_in_module = (*cell)->head;
  253.                     *statics_in_module;
  254.                     statics_in_module++) {
  255.                 objc_static_instances_t *mod_statics = *statics_in_module;
  256.                 cls = objc_get_class(mod_statics->class_name);
  257.                 if (cls) {
  258.                     id * inst;
  259.                     //ignore any protocol
  260.                     if (strcmp(mod_statics->class_name, "Protocol")) {
  261.                         for (inst = &(mod_statics->instances[0]); *inst; inst++) {
  262.                             (*inst)->class_pointer = cls;
  263.                         }
  264.                     }
  265.                 } else {
  266.                     module_initialized = 0;
  267.                 }
  268.             }
  269.             if (module_initialized) {
  270.                 cell = &((*cell)->tail);
  271.             } else {
  272.                 break;  //we don't have all classes yet so hopefully resume this
  273.                         //when the next module is loaded.
  274.             }
  275.         }
  276.     }
  277. }
  278.  
  279.  
  280. Class objc_get_superclass(Class cls) {
  281.     if (CLS_ISMETA(cls) || CLS_ISCLASS(cls)) {
  282.         const char * superclass = (char *) cls->super_class;
  283.         Class supercls = objc_get_class(superclass);
  284.         if (CLS_ISMETA(cls))
  285.             return supercls->class_pointer;
  286.         return supercls;
  287.     }
  288.     return NULL;
  289. }
  290.  
  291.  
  292. IMP objc_msg_lookup(id receiver, SEL op) {
  293.     if (receiver) {
  294.         return get_imp(receiver->class_pointer, op);
  295.     }
  296.     return NULL;
  297. }
  298.  
  299. IMP objc_msg_lookup_super(struct objc_super *super, SEL op) {
  300.     if (super->self) {
  301.         const char * superclass = (char *) super->self->class_pointer->super_class;
  302.         Class supercls = objc_get_class(superclass);
  303.         if (CLS_ISMETA(super->self->class_pointer))
  304.             return get_imp(supercls->class_pointer, op);
  305.         else
  306.             return get_imp(supercls, op);
  307.     }
  308.     return NULL;
  309. }
  310.  

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Do Aug 14, 2014 22:22 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Ok habe jetzt die "Object"-Klasse fertig. Ich habe mich hier dazu entschieden die Speicherverwaltung komplett von "Außen" abzuwickeln. Sprich die Klasse selbst übernimmt keinerlei Allokation bzw. Deallokation. Stattdessen gibt es nur Funktionen zum (De-)Initialisieren von Puffern. Das hat den großen Vorteil das man zum Beispiel Objekte auf den Stack legen kann.

Code:
  1.  
  2. @interface Object {
  3.     Class class_pointer;
  4. }
  5. //sets the class pointer to the memory pointed to by buffer
  6. //a class pointer must exist in order to class instance methods.
  7. //This function has an overload with bound checks.
  8. +(id) Init: (void*) buffer;
  9. +(id) Init: (void*) buffer With: (size_t) size;
  10. //Returns the objective-c class structure that is used to
  11. //by class pointers in objects
  12. +(Class) Class;
  13. -(Class) Class;
  14. //Returns the number of bytes an object
  15. //requires to store the class pointer and all
  16. //additional instance variables
  17. +(size_t) Size;
  18. -(size_t) Size;
  19. //Checks if the current object is assignable to
  20. //the class pointed to by cls
  21. -(BOOL) IsKindOf:(Class) cls;
  22. //Sets all bytes occupied to Zero. You may
  23. //override this to do additional before the object
  24. //gets destroyed.
  25. -(void) Uninit;
  26. @end
  27.  

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Sa Aug 16, 2014 22:02 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
So noch mal kurz ein kleiner Nachtrag zur Speicherverwaltung. Ich habe mich nun dazu entschlossen das ganze Projekt per semi funktionaler Programmierung umzusetzen. Sprich alle Objekte existieren nur solange wie der aktuelle, oder der vorherige bei "return", Stack-Frame einer Funktion:

Zuerst habe ich mir einmal die "alloca" Implementierung von "libiberty" angeschaut. Hier wird zuerst ermittelt in welche Richtung sich der Stack ausbreitet. Basierend auf der Stack-Richtung, kann der Allokator jetzt ein Offset zum "root"-Frame ermitteln. Alle vorherigen Allokationen die ein größeres Offset haben können dabei freigegeben werden.

Jetzt braucht man nur noch einen Mechanismus der ein Objekt zurückgibt. Dazu muss man einfach die jeweilige "Variablen" zum nächst höheren Offset verschieben.


Code:
  1.  
  2.  
  3. typedef struct objc_var_s objc_var_t;
  4. struct objc_var_s {
  5.     size_t size;
  6.     BOOL is_free;
  7.     objc_var_t * next;
  8.     objc_var_t * prev;
  9. };
  10.  
  11. static int STACK_DIR = -1;
  12. #define STACK_DEPTH 0xFFFF
  13. static size_t objc_stack[STACK_DEPTH ];
  14. static void * objc_mem_ptr[STACK_DEPTH ];
  15. static unsigned short objc_stack_head = 0;
  16.  
  17. static byte objc_memory[SYSTEM_MEMORY_SIZE + sizeof(objc_var_t)];
  18. static objc_var_t * objc_mem_var = NULL;  
  19. static size_t objc_used_memory = 0;
  20.  
  21. void objc_make_stack_dir(void) {
  22.     static char * addr = NULL;
  23.     auto char tmp; //some variable on the current stack-frame
  24.     if(addr) {
  25.         if(&tmp < addr) {
  26.             STACK_DIR = 1; //stack frame uses forward growth
  27.         } else {
  28.             STACK_DIR = 0; //stack frame uses backward growth
  29.         }
  30.     } else {
  31.         addr = &tmp; //assign a pointer to memory on the current stack-frame
  32.         objc_make_stack_dir(); //increase the stack-frame
  33.     }
  34. }
  35.  
  36. //initialize the memory ring-buffer
  37. void objc_init_memory(void) {
  38.     objc_mem_var = (objc_var_t*)&(objc_memory[0]);
  39.     objc_mem_var->size = SYSTEM_MEMORY_SIZE;
  40.     objc_mem_var->next = objc_mem_var;
  41.     objc_mem_var->prev = objc_mem_var;
  42.     objc_mem_var->is_free = YES;
  43.     objc_used_memory = 0;
  44. }
  45.  
  46. //allow memory pointed to by ptr to be reused by the system
  47. void objc_dealloc(void * ptr) {
  48.     objc_var_t * block = (objc_var_t*)((byte*)ptr - sizeof(objc_var_t));
  49.     objc_var_t * start = block;
  50.     if(block->is_free) {
  51.         return;
  52.     }
  53.     objc_used_memory -= block->size;
  54.     block->is_free = YES;
  55.     //join previous squential free buffer items
  56.     while(block->prev->is_free && block->prev != start) {
  57.         block = block->prev;
  58.     }
  59.     objc_mem_var = block;
  60.     //join next squential free buffer items
  61.     while(block->next->is_free && block->next != start) {
  62.         block->size += block->next->size;
  63.         block->next = block->next->next;
  64.         block->next->prev = block;
  65.     }
  66. }
  67.  
  68. void * objc_alloc(size_t size) {
  69.     objc_var_t * base = objc_mem_var;
  70.     objc_var_t * start = base;
  71.     size += sizeof(objc_var_t); //add space for the buffer item
  72.     size = (size + 7) & ~7; //align memory
  73.     while(base) { //search any free buffer with enough space
  74.         if(base->is_free) {
  75.             if(base->size > size) {
  76.                 break;
  77.             }
  78.         }
  79.         base = base->next;
  80.         if(base == start) {
  81.             return NULL;
  82.         }
  83.     }
  84.     //split our buffer if we have a good amoun of memory left
  85.     if ((base->size - size) >= 64) {
  86.         objc_var_t * next = (objc_var_t*)((byte*)base + size);
  87.         next->size = base->size - size;
  88.         next->is_free = YES;
  89.         next->prev = base;
  90.         next->next = base->next;
  91.         base->next = next;
  92.         base->size = size;
  93.     }
  94.     //mark a non-free and return a pointer to the first byte after the buffer item
  95.     base->is_free = NO;
  96.     objc_mem_var = base->next;
  97.     objc_used_memory+= base->size;
  98.     return (void*) ((byte*)base + sizeof(objc_var_t));
  99. }
  100.  
  101.  
  102. void * objc_stack_alloc(size_t size) {
  103.     static char * root = NULL;
  104.     auto char tmp;
  105.     register char * level = &(tmp);
  106.     if(STACK_DIR == -1) {
  107.         objc_make_stack_dir();
  108.     }
  109.     if(root == NULL) {
  110.         root = level; //this is the first stack-allocation so lets set a good size
  111.         objc_init_memory();
  112.     }
  113.     ptrdiff_t offset = 0;
  114.     if (STACK_DIR) {
  115.         offset = level - root;
  116.     } else {
  117.         offset = root - level;
  118.     }
  119.     while(offset < objc_stack[objc_stack_head]) { //collect garbage
  120.         objc_dealloc(objc_mem_ptr[objc_stack_head]);
  121.         objc_stack_head--;
  122.     }
  123.     void * out = objc_mem_ptr[++objc_stack_head] = objc_alloc(size);
  124.     objc_stack[objc_stack_head] = offset;
  125.     return out;
  126. }
  127.  
  128.  
  129. void * objc_stack_retain(void * ptr) {
  130.     //todo
  131.     return ptr;
  132. }
  133.  
  134.  

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Do Aug 28, 2014 07:54 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Gestern Abend habe ich mal wieder mit dem Boehm Garbage Collector rumgespielt. Und siehe da, das Ganze laeuft jetzt stabil (muss wohl ein Fehler im alten Code gewesen sein). Noch dazu ist die Speicherverwaltung fast genauso schnell wie die vorher beschriebene Stack-Variante. Also habe ich kurzer Hand die Stack-Version rausgeschmissen und durch den GC ersetzt. :)

Das Ganze funktioniert jetzt ungefaehr wie folgt:

alloc (Klasse, extra_size)
-klassen GC-type laden fuer Klasse-Name
--Wenn GC-type NULL ist, dann erstelle einen neuen GC-type fuer die Klasse
-GC_malloc_typed(Klasse->instance_size,extra_size,GC-type)
-memset auf 0
-Klassen Zeiger setzen

und fertig :-)

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Di Sep 16, 2014 20:16 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Und mal wieder ein paar kleinere Updates:

- "Static" Klasse für statische Klassen
- Superklassen werden jetzt direkt in der Klasse gespeichert statt nur der Name.
- Kategorien
[edit]
achja ganz vergessen:

Code:
  1.  
  2.  
  3. @interface Handle {
  4.     @private
  5.     Class class_pointer;
  6. }
  7. +(Class) Type; //gets the type of the current class
  8. -(Class) Type; //gets the type of the current object
  9. -(bool) Is:(Class) cls; //checks if the object is assignable to the given class
  10. @end
  11.  
  12. @interface Dynamic {
  13. }
  14. +(id) Alloc; //allocates and returns an instance of a garbage collected object
  15. -(void) Dispose; //automatically called when the object will be deallocated by the garbage collector or Dealloc method.
  16. -(void) Dealloc; //manually deallocate the current object
  17. @end
  18.  
  19. @interface Static {
  20.     bool isLoaded;
  21. }
  22. +(id) Current; //returns the instance for the static class
  23. -(id) Load; //automatically called by the Current method and when the object is not loaded
  24. -(void) Unload; //automatically called when the process terminates and marks the object as unloaded
  25.  
  26. @end

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Do Okt 09, 2014 20:50 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Mal wieder ein kleines Update:

ich nutze jetzt meinen Mini Collector zur automatischen Speicherbereinigung. Im Gegensatz zur der im Thread geposteten Version hat meine Version einige zusätzliche Features:

-Range Checks um zum Beispiel Pointer Arithmetik zu unterstützen.
-De- und Initialisierung finden in den Startup Funktionen statt. Also zum Beispiel WinMainCRTStartup.
-Finalizer und Class Finalizer
-OpenMP Beschleunigung
-Der GC-thread wird jetzt über ein "Join" beendet statt nur terminiert
-C++,C und Objective-C Support

Die Static-Klasse ist jetzt die Module-Klasse. Die Module rufen bei Benutzung automatisch die
Load-Methode auf und registrieren Unload als Class-Finalizer. Dies erlaubt mir jetzt relativ entspannt das Fenster-System und dynamische Bibliothek (wie OpenGL) zu laden. Außerdem fliegt die Dynamic Klasse raus, da auch Module Instanzen brauchen (z.B. für GL-Extensions).

Außerdem habe ich jetzt meine Objective-C Toolchain auf C11 und 64bit geupdated :)

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: BroodTech Game Engine
BeitragVerfasst: Do Dez 18, 2014 00:04 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Hallo Allerseits,

Es ist mal wieder Urlaub- /Ferienzeit und das bedeutet natürlich endlich mal wieder Zeit für die wichtigen Dinge im Leben: OpenGL :)

Die letzten Tage habe ich damit verbracht die gesamte Engine mal wieder komplett umzuschreiben. Herausgekommen ist nun eine solide Basis welche die, meiner Meinung nach, besten Elemente der bisherigen Arbeit vereint. Der wohl wichtigste Punkt dabei ist der neue Multithreading Support und damit verbunden der Umstieg von Objective-C auf C++. Oder besser gesagt den Syntax-Sugar durch Objective-C, denn vieles funktioniert tatsächlich noch genauso. Sprich Objekte erhalten Nachrichten anstelle von direkten Funktionsaufrufen.

Der Große Unterschied liegt nun darin das ich den kompletten "Aufruf" in einer Queue zwischenspeichere. Der Dispatcher entscheidet dann automatisch, ob die Queue sofort (z.B. wenn eine Rückgabe erwartet wird) oder zu einen späteren Zeitpunkt abgearbeitet wird. Auf diese Weise kann ein Objekt sehr leicht von mehreren Threads benutzt werden ohne das man sich große Gedanken um die Synchronisation machen muss.

Würde man ein ähnliches Verhalten mit Objective-C erziehlen wollen müsste man auf Asm zurückgreifen oder den Compiler nachbearbeiten. Beides war für mich keine Option, also Umstieg.

Das neue Macro-Design der Engine sieht nun wie folgt aus:
Abstract Thread
- Send Message
- Process Message

Main-Thread
-Alles Starten und Beenden.
-Schleife für den Input und co.
->Events an den Client senden.
Client-Thread
- Interaktion mit der Szene
->Commands an den Renderer senden.
->Events an den Server senden.
Renderer-Thread
-Commands verarbeiten
Server-Thread
-Aufbau / Update der Szene
->Events an den Client senden.
GC-Thread
-Speicher scannen und aufräumen.

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Sonstiges » Projekte


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.026s | 17 Queries | GZIP : On ]