diff --git a/hGameTest/build.hxml b/hGameTest/build.hxml
index c51dbd63..555a5341 100644
--- a/hGameTest/build.hxml
+++ b/hGameTest/build.hxml
@@ -1,5 +1,11 @@
--main App
--js src/app.js
--cp node_modules/openfl/lib
+
+#-main App
+#-js src/app.js
+#-cp node_modules/openfl/lib
+#-cp src
+#-D buildhxml
+#-D source-map
+
+--main
+-hl exp/out.hl
-cp src
--D source-map
diff --git a/hGameTest/project.xml b/hGameTest/project.xml
index eaad2b00..17e79d3b 100644
--- a/hGameTest/project.xml
+++ b/hGameTest/project.xml
@@ -3,28 +3,27 @@
-
+
-
+
-
-
-
+
+
+
-
-
+
+
+
-
-
+
-
\ No newline at end of file
diff --git a/hGameTest/res/assets.manifest.json b/hGameTest/res/assets.manifest.json
new file mode 100644
index 00000000..c01c0254
--- /dev/null
+++ b/hGameTest/res/assets.manifest.json
@@ -0,0 +1,9 @@
+{
+ "datascheme": "assetmanifest",
+ "version": "1.0",
+ "type": "manifestmanifest",
+ "files": [
+ ""
+ ]
+
+}
\ No newline at end of file
diff --git a/hGameTest/res/fonts/Terminus.ttf b/hGameTest/res/fonts/Terminus.ttf
new file mode 100644
index 00000000..eafa3a6e
Binary files /dev/null and b/hGameTest/res/fonts/Terminus.ttf differ
diff --git a/hGameTest/src/App.hx b/hGameTest/src/App.hx
index f1302646..b9692eed 100644
--- a/hGameTest/src/App.hx
+++ b/hGameTest/src/App.hx
@@ -1,17 +1,25 @@
import openfl.display.Sprite;
import openfl.display.Stage;
import openfl.events.Event;
+import assets.Scanner;
+import openfl.utils.AssetManifest;
class App extends Sprite {
public function new () {
-
super ();
- var game:Game = new Game(stage);
- game.onInit();
- stage.addEventListener(Event.ENTER_FRAME, game.onEnterFrame);
+ Scanner.scanTextureDir();
+ trace("k");
+ #if buildhxml
+ var manifest = new AssetManifest ();
+
+
+ #end
+ //var game:Game = new Game(stage);
+ //game.onInit();
+ //stage.addEventListener(Event.ENTER_FRAME, game.onEnterFrame);
}
diff --git a/hGameTest/src/Main.hx b/hGameTest/src/Main.hx
index 2f3023dc..8a653ded 100644
--- a/hGameTest/src/Main.hx
+++ b/hGameTest/src/Main.hx
@@ -1,33 +1,35 @@
+import assets.Scanner;
+import game.video.Mode;
import openfl.events.KeyboardEvent;
import openfl.display.Sprite;
import openfl.display.Stage;
import openfl.events.Event;
+import game.Input;
import game.Game;
+import game.video.Mode;
class Main extends Sprite {
public function new () {
super ();
+ this.addEventListener(Event.ADDED_TO_STAGE, onInit);
+ //stage.application.window.resize(1920, 1080);
+ //stage.application.window.title = "Kanker";
+ }
+ private function onInit(e:Event)
+ {
+ //Scanner.scanTextureDir();
stage.frameRate = 1000;
var game:Game = new Game(stage);
- game.onInit();
stage.addEventListener(Event.ENTER_FRAME, game.onEnterFrame);
- stage.addEventListener(KeyboardEvent.KEY_DOWN,keyIsDown);
- stage.addEventListener(KeyboardEvent.KEY_UP,keyIsUp);
+ stage.addEventListener(KeyboardEvent.KEY_DOWN,Input.onKeyIsDown);
+ stage.addEventListener(KeyboardEvent.KEY_UP,Input.onKeyIsUp);
stage.addEventListener(Event.RESIZE,onResize);
- stage.application.window.resize(1920, 1080);
- stage.application.window.title = "Kanker";
-
- }
+ game.onInit();
+ //Mode.setVideoMode(1280, 960);
+ }
private function onResize (event:Event):Void {
//Here we can do shit with window scaling
//stage.stageWidth;
//stage.stageHeight;
}
-
- private function keyIsDown(e:KeyboardEvent){
- Game.keys[e.keyCode] = true;
- }
- private function keyIsUp(e:KeyboardEvent){
- Game.keys[e.keyCode] = false;
- }
}
\ No newline at end of file
diff --git a/hGameTest/src/assets/Fonts.hx b/hGameTest/src/assets/Fonts.hx
new file mode 100644
index 00000000..2ad4f32f
--- /dev/null
+++ b/hGameTest/src/assets/Fonts.hx
@@ -0,0 +1,8 @@
+package assets;
+
+import openfl.text.Font;
+import openfl.Assets;
+
+class Fonts{
+ //public static var terminus:Font = Assets.getFont("fonts/Terminus.ttf");
+}
\ No newline at end of file
diff --git a/hGameTest/src/assets/HTex.hx b/hGameTest/src/assets/HTex.hx
index 491af41f..01479cdb 100644
--- a/hGameTest/src/assets/HTex.hx
+++ b/hGameTest/src/assets/HTex.hx
@@ -31,7 +31,7 @@ class HTex{
var tileNames:Array = td.tilesetGeneric.tiles;
var atlas:TextureAtlas = new TextureAtlas(Assets.getBitmapData(baseTexturePath),width,height);
var tileSetGeneric = new TilesetGeneric(td.texName, atlas, tileNames);
- trace(tileSetGeneric);
+ //trace(tileSetGeneric);
}
}
}
diff --git a/hGameTest/src/assets/Scanner.hx b/hGameTest/src/assets/Scanner.hx
index f1ba4704..4441160c 100644
--- a/hGameTest/src/assets/Scanner.hx
+++ b/hGameTest/src/assets/Scanner.hx
@@ -1,7 +1,7 @@
package assets;
+#if sys
import sys.io.File;
import sys.FileSystem;
-
class Scanner{
public static function scanTextureDir(){
scanDirsRecursively("textures");
@@ -30,4 +30,16 @@ class Scanner{
trace(textures);
}
}
-}
\ No newline at end of file
+}
+#else
+import openfl.Assets;
+import openfl.utils.AssetType;
+class Scanner{
+ public static function scanTextureDir(){
+ trace(Assets.list(AssetType.TEXT));
+ for(str in Assets.list(AssetType.TEXT)){
+ trace(str);
+ }
+ }
+}
+#end
\ No newline at end of file
diff --git a/hGameTest/src/engine/CVar.hx b/hGameTest/src/engine/CVar.hx
new file mode 100644
index 00000000..de1f3555
--- /dev/null
+++ b/hGameTest/src/engine/CVar.hx
@@ -0,0 +1,9 @@
+package engine;
+
+
+typedef CVar = {
+ var name:String;
+ var type:CVarType;
+ var value:Dynamic;
+ @:optional var callback:Void -> Void;
+};
diff --git a/hGameTest/src/engine/ConVar.hx b/hGameTest/src/engine/ConVar.hx
new file mode 100644
index 00000000..22c5aa5b
--- /dev/null
+++ b/hGameTest/src/engine/ConVar.hx
@@ -0,0 +1,162 @@
+package engine;
+
+import haxe.Constraints.Function;
+import engine.typedefs.console.CVar;
+import engine.typedefs.console.CCmd;
+import engine.enums.console.CVarType;
+import engine.enums.console.CVarFlag;
+import game.ui.console.Console;
+
+
+class ConVar{
+ static var CVarMap:Map = [];
+ static var CCmdMap:Map = [];
+ /**
+ * Registers a new CVar
+ * @param _name The name of the CVar. This is the way it is called in the console or referred to in code.
+ * @param _type CVar type as defined in the CVarType enum.
+ * @param _value The default value for this CVar. This needs to be in line with its CVarType.
+ * @param _flags CVar flags as defined in the CVarFlags enum.
+ * @param _helpString Help string that gets printed out in console when no value is specified.
+ * @param _callback The function that gets called when the CVar is set. Calls empty Void when left undefined.
+ * @param _callOnCreate Whether the callback function gets called or not after registering.
+ * @param _bMin Specifies if the CVar has a minimum numeric value.
+ * @param _fMin Specifies the minimum numeric value.
+ * @param _fMax Specifies the maximum numeric value.
+ * @param _bMax Specifies if the CVar has a maximum numeric value.
+ */
+ public static inline function registerCVar(_name:String, _type:CVarType, _value:Dynamic, ?_flags:CVarFlag, ?_helpString:String = "", ?_callback:Void->Void, ?_callOnCreate:Bool=false, _bMin:Bool=false, _fMin:Float=0, _fMax:Float=0, _bMax:Bool = false):CVar
+ {
+ if(CVarMap[_name]!=null || CCmdMap[_name]!=null){
+ Console.devMsg("Tried setting already defined convar: " + _name + ", returning null instead");
+ return null;
+ }
+ if(_bMin && _value < _fMin) _value = _fMin;
+ if(_bMax && _value > _fMax) _value = _fMax;
+ var cvar:CVar = CVarMap[_name] = {
+ name : _name,
+ type : _type,
+ value : _value,
+ flags: _flags,
+ helpString: _helpString,
+ bMin : _bMin,
+ fMin : _fMin,
+ fMax : _fMax,
+ bMax : _bMax,
+ callback : _callback == null ? ()->{} : _callback
+ }
+ if(_callback != null && _callOnCreate){
+ _callback();
+ }
+ return cvar;
+ }
+ public static inline function registerCCmd(_name:String, ?_callback:Array->Void):CCmd
+ {
+ if(CVarMap[_name]!=null || CCmdMap[_name]!=null){
+ Console.devMsg("Tried setting already defined command: " + _name + ", returning null instead");
+ return null;
+ }
+ var cmd:CCmd = CCmdMap[_name] = {
+ name : _name,
+ callback : _callback
+ }
+ return cmd;
+ }
+ public static inline function setCVar(_name:String, _value:Dynamic):Void
+ {
+ var cv = getCVar(_name);
+ if(cv != null){
+ switch(cv.type){
+ case CInt,CFloat:
+ if(cv.bMax && _value > cv.fMax) _value = cv.fMax;
+ if(cv.bMin && _value < cv.fMin) _value = cv.fMin;
+ case CBool:
+ if(Std.isOfType(_value, String)){
+ var v:String = _value;
+ _value = v.toLowerCase();
+ if(_value == "true" || _value == "1"){
+ _value = true;
+ }
+ else{
+ _value = false;
+ }
+ }
+ else if(Std.isOfType(_value, Int) || Std.isOfType(_value, Float)){
+ if(_value %2 == 0){
+ _value = false;
+ }
+ else{
+ _value = true;
+ }
+ }
+ else if(Std.isOfType(_value, Bool)){
+ //do nothing
+ }
+ else{
+ _value = cv.value;
+ }
+ case CString:
+ _value = Std.string(_value);
+
+ }
+ cv.value = _value;
+ cv.callback();
+
+ }
+ else{
+ Console.devMsg("trying to set null convar '"+_name+"'");
+ }
+
+ }
+ public static inline function isCVar(_name:String){
+ return (CVarMap[_name] != null);
+
+ }
+ public static inline function isCmd(_name:String){
+ return (CCmdMap[_name] != null);
+ }
+ public static inline function runCmd(_name:String, _args:Array){
+ if(CCmdMap[_name] != null){
+ CCmdMap[_name].callback(_args);
+ }
+ }
+ public static inline function getCVarNames():Array
+ {
+ var keys:Array = [
+ for(iterator in [CCmdMap.keys(),CVarMap.keys()]){
+ for(key in iterator){
+ key;
+ }
+ }
+ ];
+ keys.sort(function(a:String, b:String):Int {
+ a = a.toUpperCase();
+ b = b.toUpperCase();
+ if (a < b) {
+ return -1;
+ }
+ else if (a > b) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ return keys;
+ }
+ public static var cmdList:CCmd = ConVar.registerCCmd("list", (cArgs:Array)->{
+ var keys:Array = getCVarNames();
+ for(key in keys){
+ if(CVarMap[key] != null){
+ Console.devMsg(key+" "+CVarMap[key].value);
+ }
+ else{
+ Console.devMsg(key);
+ }
+ }
+ });
+ public static inline function getCVar(_name:String):CVar
+ {
+ return CVarMap[_name];
+ }
+
+}
\ No newline at end of file
diff --git a/hGameTest/src/engine/HProfiler.hx b/hGameTest/src/engine/HProfiler.hx
new file mode 100644
index 00000000..21fe2fa2
--- /dev/null
+++ b/hGameTest/src/engine/HProfiler.hx
@@ -0,0 +1,48 @@
+package engine;
+
+import game.ui.console.Console;
+import Sys;
+
+#if sys
+class HProfiler{
+ public static var profilerList:Array = [];
+ public static var profilerMap:Map = [];
+ private var tStart:Float;
+ private var tEnd:Float;
+ public var tDelta:Float;
+ private var name:String;
+ private function new(_name:String){
+ name = _name;
+ profilerMap[_name] = this;
+ }
+ public function start(){
+ tStart = Sys.time() * 1000.0;
+ }
+ public function stop(){
+ tEnd = Sys.time() * 1000.0;
+ tDelta = (tEnd-tStart);
+ }
+ //public static var
+ public static function startProfiling(name:String):Void
+ {
+ if(profilerMap[name] == null)
+ profilerList.push(new HProfiler(name));
+ profilerMap[name].start();
+ }
+ public static function stopProfiling(name:String):Void
+ {
+ profilerMap[name].stop();
+ }
+
+ public static var ccmd_debug_tracetimes = ConVar.registerCCmd("debug_tracetimes", (args:Array) -> {
+ for(profiler in profilerList){
+ Console.devMsg(profiler.name + ": " + profiler.tDelta + "ms");
+ }
+ });
+}
+#else
+class HProfiler{
+ public static function startProfiling(name:String):Void{}
+ public static function stopProfiling(name:String):Void{}
+}
+#end
diff --git a/hGameTest/src/engine/enums/console/CVarFlag.hx b/hGameTest/src/engine/enums/console/CVarFlag.hx
new file mode 100644
index 00000000..56ee8e16
--- /dev/null
+++ b/hGameTest/src/engine/enums/console/CVarFlag.hx
@@ -0,0 +1,8 @@
+package engine.enums.console;
+
+enum CVarFlag{
+ FCVAR_ARCHIVE;
+ FCVAR_CHEAT;
+ FVCAR_REPLICATED;
+ FCVAR_NOTIFY;
+}
\ No newline at end of file
diff --git a/hGameTest/src/engine/enums/console/CVarType.hx b/hGameTest/src/engine/enums/console/CVarType.hx
new file mode 100644
index 00000000..82f21455
--- /dev/null
+++ b/hGameTest/src/engine/enums/console/CVarType.hx
@@ -0,0 +1,9 @@
+package engine.enums.console;
+
+enum CVarType {
+ CInt;
+ CFloat;
+ CString;
+ CBool;
+ //CCmd;
+}
\ No newline at end of file
diff --git a/hGameTest/src/engine/geom/Geom.hx b/hGameTest/src/engine/geom/Geom.hx
new file mode 100644
index 00000000..22cd7308
--- /dev/null
+++ b/hGameTest/src/engine/geom/Geom.hx
@@ -0,0 +1,7 @@
+package engine.geom;
+
+
+typedef P2d = {
+ x:Float,
+ y:Float
+}
\ No newline at end of file
diff --git a/hGameTest/src/engine/tools/HWindow.hx b/hGameTest/src/engine/tools/HWindow.hx
new file mode 100644
index 00000000..13d1bb43
--- /dev/null
+++ b/hGameTest/src/engine/tools/HWindow.hx
@@ -0,0 +1,34 @@
+package engine.tools;
+
+import lime.ui.WindowAttributes;
+import openfl.Lib;
+import openfl.display.Sprite;
+import openfl.display.Window;
+
+class HWindow extends Sprite{
+ public var window:Window;
+ public var attribs:WindowAttributes;
+ public static var windows:Array = [];
+ public function new(){
+ super();
+ window = Lib.application.createWindow(attribs);
+ windows.push(window);
+ }
+ public function initStage(spr:Sprite){
+ window.stage.addChild(this);
+ }
+ public function close(){
+ window.close();
+ }
+ public static function createEditorWindow()
+ {
+
+ }
+ //public function open()
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/hGameTest/src/engine/tools/ui/UITool.hx b/hGameTest/src/engine/tools/ui/UITool.hx
new file mode 100644
index 00000000..543f1eb9
--- /dev/null
+++ b/hGameTest/src/engine/tools/ui/UITool.hx
@@ -0,0 +1,105 @@
+package engine.tools.ui;
+
+import game.ui.text.TextFormats;
+import openfl.text.TextFormat;
+import openfl.text.TextField;
+import engine.ui.UIPane;
+import lime.app.Event;
+import openfl.display.Sprite;
+import openfl.Lib;
+import lime.ui.Window;
+import engine.ConVar;
+import game.ui.console.Console;
+//import Lib.application.
+
+
+typedef UINode = {
+ object:UIPane,
+ ?children:Array
+}
+
+
+class UITool{
+ public static var ccmd_dev_uitool = ConVar.registerCCmd("dev_uitool", (args:Array) -> { open();});
+ public static var uiEditorWindow:openfl.display.Window;
+ public static var uiEditorSprite:Sprite;
+ private static var tf:TextField;
+ public static function spawnUIEditorWindow(){
+ var secondWindow = Lib.application.createWindow({title: "UI Outliner"});
+ if(uiEditorSprite == null){
+ uiEditorSprite = new Sprite();
+ uiEditorSprite.graphics.beginFill(0x00ff00);
+ uiEditorSprite.graphics.drawRect(0,0,1280,960);
+ }
+ secondWindow.stage.addChild(uiEditorSprite);
+ uiEditorWindow = secondWindow;
+ secondWindow.onClose.add(()->{
+ uiEditorWindow = null;
+ });
+ tf = new TextField();
+ TextFormats.getFormats();
+ var tformat = TextFormats.formats.cInputFmt;
+ tf.setTextFormat(tformat);
+ tf.autoSize = LEFT;
+ uiEditorSprite.addChild(tf);
+ update([]);
+ }
+
+
+ public static var ccmd_dev_uitool_refresh = ConVar.registerCCmd("dev_uitool_refresh", update);
+
+ public static var uiNodes:Map = [];
+ public static var rootNodes:Array = [];
+ public static function collect(){
+ for(pane in UIPane.panelist){
+ var node:UINode = null;
+ if(uiNodes[pane] == null){
+ node = {
+ object: pane,
+ children: []
+ };
+ }
+ else{
+ node = uiNodes[pane];
+ }
+ var parentNode:UINode = null;
+ if(uiNodes[pane.parent] == null){
+ parentNode = {
+ object:pane.parent,
+ children: []
+ }
+ }
+ else{
+ parentNode = uiNodes[pane.parent];
+ }
+ parentNode.children.push(node);
+ if(pane.parent == null){
+ rootNodes.push(node);
+ }
+ }
+ }
+
+
+ public static function update(args:Array){
+ tf.text = "";
+ for(pane in UIPane.panelist){
+ //check if pane is toplevel
+ Console.devMsg("Pane: "+ pane.name);
+ //Get all Root UI Panes
+ if(pane.parent == null) {
+ tf.appendText("-");
+ tf.appendText(pane.name+"\n");
+ }
+ }
+ }
+
+ public static function open(){
+ if(uiEditorWindow == null){
+ spawnUIEditorWindow();
+ }
+
+ }
+ public static function close(){
+
+ }
+}
\ No newline at end of file
diff --git a/hGameTest/src/engine/typedefs/console/CCmd.hx b/hGameTest/src/engine/typedefs/console/CCmd.hx
new file mode 100644
index 00000000..34a599c8
--- /dev/null
+++ b/hGameTest/src/engine/typedefs/console/CCmd.hx
@@ -0,0 +1,9 @@
+package engine.typedefs.console;
+
+import engine.typedefs.console.CVar;
+
+
+typedef CCmd = {
+ var name:String;
+ @:optional var callback:Array -> Void;
+};
\ No newline at end of file
diff --git a/hGameTest/src/engine/typedefs/console/CVar.hx b/hGameTest/src/engine/typedefs/console/CVar.hx
new file mode 100644
index 00000000..269b524e
--- /dev/null
+++ b/hGameTest/src/engine/typedefs/console/CVar.hx
@@ -0,0 +1,17 @@
+package engine.typedefs.console;
+
+import engine.enums.console.CVarType;
+import engine.enums.console.CVarFlag;
+
+typedef CVar = {
+ var name:String;
+ var type:CVarType;
+ var value:Dynamic;
+ var flags:CVarFlag;
+ var helpString:String;
+ var bMin:Bool;
+ var fMin:Float;
+ var fMax:Float;
+ var bMax:Bool;
+ @:optional var callback:Void -> Void;
+};
\ No newline at end of file
diff --git a/hGameTest/src/engine/ui/UIElement.hx b/hGameTest/src/engine/ui/UIElement.hx
new file mode 100644
index 00000000..a95f9a4f
--- /dev/null
+++ b/hGameTest/src/engine/ui/UIElement.hx
@@ -0,0 +1,30 @@
+package engine.ui;
+
+import engine.geom.Geom.P2d;
+import engine.ui.UIPane.PaneDimensions;
+import openfl.display.DisplayObject;
+
+class UIElement extends UIPane
+{
+ public var dispObj:DisplayObject;
+ public var padding:P2d;
+ public function new(_name:String, _dimensions:PaneDimensions, _displayObject:DisplayObject)
+ {
+ super(_name, _dimensions);
+ dispObj = _displayObject;
+ sprite.addChild(dispObj);
+ }
+ override public function onResize(){
+ super.onResize();
+ resizeDisplayObject();
+ }
+ public function resizeDisplayObject(){
+ if(padding == null)
+ padding = {x:0,y:0};
+ dispObj.width = this.dimensions.width - padding.x;
+ dispObj.height = this.dimensions.height - padding.y;
+ dispObj.x = padding.x / 2;
+ dispObj.y = padding.y / 2;
+ }
+
+}
\ No newline at end of file
diff --git a/hGameTest/src/engine/ui/UIPane.hx b/hGameTest/src/engine/ui/UIPane.hx
new file mode 100644
index 00000000..791bc913
--- /dev/null
+++ b/hGameTest/src/engine/ui/UIPane.hx
@@ -0,0 +1,334 @@
+package engine.ui;
+
+// __ __ _____ ______
+// | | | | / ___ \ | ____|
+// | |____| | | / _\_| | |____
+// | ____ | | | |_ \ | ____|
+// | | | | | \__/ | | |____
+// |__| |__| \______/ |______|
+
+/*
+ / file: UIPane.hx
+ / author: and.schaafsma@gmail.com
+ / purpose: Class for resizable and scalable UI Panels
+ / My hope is that this code is so awful I'm never allowed to write UI code again.
+*/
+import game.ui.console.Console;
+import openfl.display.Sprite;
+import openfl.display.BitmapData;
+import openfl.display.DisplayObject;
+import openfl.text.TextField;
+import engine.ConVar;
+import engine.geom.Geom.P2d;
+
+@:enum abstract PaneLayout(Int) {
+ var HORIZONTAL = 0;
+ var VERTICAL = 1;
+}
+
+enum PaneAnchor {
+ LEFT;
+ TOPLEFT;
+ TOP;
+ TOPRIGHT;
+ RIGHT;
+ BOTTOMLEFT;
+ BOTTOM;
+ BOTTOMRIGHT;
+}
+
+enum ExpandBehavior {
+ // ABSOLUTE;
+ FACTOR(f:Float);
+ // CONTENT;
+ STRETCH;
+ // FILL;
+ // FIT;
+ NONE;
+}
+
+enum PaneAlign {
+ START;
+ END;
+}
+
+typedef PaneDimensions = {
+ var width:Float;
+ var height:Float;
+ @:optional var expandBehavior:ExpandBehavior;
+ @:optional var minWidth:Float;
+ @:optional var minHeight:Float;
+ @:optional var maxWidth:Float;
+ @:optional var maxHeight:Float;
+}
+
+typedef PaneProps = {
+ dimensions:PaneDimensions,
+ layout:PaneLayout
+}
+
+class UIPane {
+ public var name:String;
+ public var sprite:Sprite;
+ public var x(get, set):Float;
+ public var y(get, set):Float;
+
+ function get_x() {
+ return sprite.x;
+ }
+
+ function set_x(x) {
+ return sprite.x = x;
+ }
+
+ function get_y() {
+ return sprite.y;
+ }
+
+ function set_y(y) {
+ return sprite.y = y;
+ }
+
+ public var dimensions:PaneDimensions;
+ public var width(get, set):Float;
+
+ function get_width() {
+ return dimensions.width;
+ }
+
+ function set_width(width) {
+ dimensions.width = width;
+ onResize();
+ return width;
+ }
+
+ public var height(get, set):Float;
+
+ function get_height() {
+ return dimensions.height;
+ }
+
+ function set_height(height) {
+ dimensions.height = height;
+ onResize();
+ return height;
+ }
+
+ public var layout:PaneLayout;
+ public var autoArrange:Bool = true;
+ public var autoArrangeChildren = true;
+ public var expand:Bool;
+ public var children:Array = [];
+ public var parent:UIPane = null;
+ public var align:PaneAlign = START;
+ public var maskSprite:Sprite;
+
+ public static var panelist:Array = [];
+
+ public function new(_name:String, _dimensions:PaneDimensions) {
+ // Set name
+ name = _name;
+ // Set dimensions
+ if (_dimensions != null) {
+ dimensions = _dimensions;
+ } else {
+ dimensions = {
+ width: 0,
+ height: 0,
+ minWidth: 0,
+ minHeight: 0,
+ maxWidth: 0,
+ maxHeight: 0
+ };
+ }
+ if (name == null || name == "") {
+ Console.devMsg("UI Pane name init error");
+ }
+ // Initialize Sprite
+ initSprite();
+ // Draw debug pane for visualizing
+ drawDebugPane();
+ panelist.push(this);
+ }
+
+ public static var ccmd_ui_redraw = ConVar.registerCCmd("ui_redraw", (args:Array) -> {
+ redrawUIPanes();
+ });
+
+ public static function redrawUIPanes() {
+ for (pane in panelist) {
+ pane.redraw();
+ }
+ }
+
+ public function getAnchorOffset(anchor:PaneAnchor):P2d {
+ switch (anchor) {
+ case LEFT:
+ return {x: 0, y: (height / 2)};
+ case TOPLEFT:
+ return {x: 0, y: 0};
+ case TOP:
+ return {x: width / 2, y: 0};
+ case TOPRIGHT:
+ return {x: width, y: 0};
+ case RIGHT:
+ return {x: width, y: height / 2}
+ case BOTTOMRIGHT:
+ return {x: width, y: height};
+ case BOTTOM:
+ return {x: width / 2, y: height};
+ case BOTTOMLEFT:
+ return {x: 0, y: height};
+ }
+ }
+
+ public function initSprite():Void {
+ // Construct Sprite object
+ sprite = new Sprite();
+
+ // Draw mask
+ maskSprite = new Sprite();
+ drawMask();
+ sprite.addChild(maskSprite);
+ sprite.mask = maskSprite;
+ }
+
+ public function drawMask():Void {
+ maskSprite.graphics.clear();
+ maskSprite.graphics.beginFill(0xffffff);
+ maskSprite.graphics.drawRect(0, 0, width, height);
+ }
+
+ public function drawDebugPane() {
+ // Clear graphics
+ sprite.graphics.clear();
+ // Create objects we need to draw.
+ var label:TextField = new TextField();
+ var bmp = new BitmapData(Std.int(width), Std.int(height), true, 0x00000000);
+ // Set textfield text to the panel name
+ label.text = name;
+ // Draw textfield to bitmap
+ bmp.draw(label);
+ // Draw graphics
+ sprite.graphics.beginFill(Std.int(Math.random() * 0xffffff), 0.5);
+ sprite.graphics.drawRect(0, 0, dimensions.width, dimensions.height);
+ sprite.graphics.beginBitmapFill(bmp, null);
+ sprite.graphics.drawRect(0, 0, dimensions.width, dimensions.height);
+ // Visualize Anchor Points
+ if (false) {
+ sprite.graphics.beginFill(Std.int(Math.random() * 0xffffff), 0.5);
+ sprite.graphics.drawCircle(getAnchorOffset(TOPLEFT).x, getAnchorOffset(TOPLEFT).y, 5);
+ sprite.graphics.drawCircle(getAnchorOffset(TOP).x, getAnchorOffset(TOP).y, 5);
+ sprite.graphics.drawCircle(getAnchorOffset(TOPRIGHT).x, getAnchorOffset(TOPRIGHT).y, 5);
+ sprite.graphics.drawCircle(getAnchorOffset(RIGHT).x, getAnchorOffset(RIGHT).y, 5);
+ sprite.graphics.drawCircle(getAnchorOffset(BOTTOMRIGHT).x, getAnchorOffset(BOTTOMRIGHT).y, 5);
+ sprite.graphics.drawCircle(getAnchorOffset(BOTTOM).x, getAnchorOffset(BOTTOM).y, 5);
+ sprite.graphics.drawCircle(getAnchorOffset(BOTTOMLEFT).x, getAnchorOffset(BOTTOMLEFT).y, 5);
+ sprite.graphics.drawCircle(getAnchorOffset(LEFT).x, getAnchorOffset(LEFT).y, 5);
+ }
+ }
+
+ public var endOffset:Float = 0;
+ public var startOffset:Float = 0;
+
+ public function addChild(child:UIPane) {
+ if (child.parent != null)
+ throw "Attempting to attach child UIPane that already has a parent";
+ children.push(child);
+ sprite.addChild(child.sprite);
+ child.parent = this;
+ if (child.autoArrange && autoArrangeChildren) {
+ arrangeChild(child);
+ }
+ return child;
+ }
+
+ public function redraw():Void {
+ drawDebugPane();
+ drawMask();
+ }
+
+ public function onResize() {
+ redraw();
+ if (autoArrangeChildren) {
+ arrangeChildren();
+ }
+ }
+
+ private function arrangeChild(child:UIPane) {
+ // We do not arrange the
+ if (!child.autoArrange) {
+ return;
+ }
+ if (endOffset == 0) {
+ switch (layout) {
+ case HORIZONTAL:
+ endOffset = width;
+ case VERTICAL:
+ endOffset = height;
+ }
+ }
+ var offsetDiff:Float = endOffset - startOffset;
+ // Set child dimensions
+ switch (child.dimensions.expandBehavior) {
+ case STRETCH:
+ switch (layout) {
+ case HORIZONTAL:
+ child.width = offsetDiff;
+ child.height = height;
+ case VERTICAL:
+ child.width = width;
+ child.height = offsetDiff;
+ }
+ case FACTOR(f):
+ switch (layout) {
+ case HORIZONTAL:
+ child.width = width * f;
+ child.height = height;
+ case VERTICAL:
+ child.width = width;
+ child.height = height * f;
+ }
+ default:
+ switch (layout) {
+ case HORIZONTAL:
+ // do some shit
+ child.height = height;
+ case VERTICAL:
+ // do some other shit
+ child.width = width;
+ default:
+ child.height = child.height;
+ }
+ }
+ // Set child position
+ switch (child.align) {
+ case START:
+ switch (layout) {
+ case HORIZONTAL:
+ child.x = startOffset;
+ startOffset += child.width;
+ case VERTICAL:
+ child.y = startOffset;
+ startOffset += child.height;
+ }
+ case END:
+ switch (layout) {
+ case HORIZONTAL:
+ child.x = endOffset -= child.width;
+ case VERTICAL:
+ child.y = endOffset -= child.height;
+ }
+ }
+ }
+
+ public function arrangeChildren() {
+ // reset offsets
+ startOffset = 0;
+ endOffset = 0;
+ // arrance each child
+ for (child in children) {
+ arrangeChild(child);
+ }
+ }
+}
diff --git a/hGameTest/src/game/Bind.hx b/hGameTest/src/game/Bind.hx
deleted file mode 100644
index 854df82a..00000000
--- a/hGameTest/src/game/Bind.hx
+++ /dev/null
@@ -1,8 +0,0 @@
-package game;
-
-class Bind{
-
- public function new(){
-
- }
-}
\ No newline at end of file
diff --git a/hGameTest/src/game/Game.hx b/hGameTest/src/game/Game.hx
index 5c8eed6e..a6814009 100644
--- a/hGameTest/src/game/Game.hx
+++ b/hGameTest/src/game/Game.hx
@@ -1,63 +1,62 @@
package game;
-import game.entities.Player;
-import assets.tilesets.TilesetGeneric;
-import assets.tilesets.Tileset;
-import openfl.display.Bitmap;
import openfl.display.Stage;
-import openfl.display.Bitmap;
-import openfl.display.BitmapData;
import openfl.display.Sprite;
-import openfl.ui.Keyboard;
import openfl.events.Event;
-import openfl.Assets;
-import assets.Scanner;
+
+import engine.HProfiler;
+import engine.ConVar;
+import engine.ui.UIPane;
+import engine.typedefs.console.CVar;
+import engine.tools.ui.UITool;
+
+import game.ui.console.ConsolePane;
+import game.entities.Player;
+import game.ui.console.Console;
+
+
import assets.HTex;
-import openfl.Lib;
-import openfl.display.StageDisplayState;
+import assets.Scanner;
class Game
{
public var stage:Stage;
+ public var gameLayer:Sprite;
+ public var uiLayer:Sprite;
public function new(_stage:Stage){
stage = _stage;
+#if PRECACHE_ASSETS & sys
Scanner.scanTextureDir();
for(tex in Scanner.textures){
HTex.createTextureObjectFromJSON(tex);
}
+#end
+ gameLayer = new Sprite();
+ uiLayer = new Sprite();
+ trace("wattafak");
}
public var player:Player;
+ public var console:Console = new Console();
+ public function loadData():Void
+ {
+ new game.ui.text.TextFormats();
+ }
public function onInit():Void
{
-
- //player.graphics.lineStyle(2,0xFF0000);
- //player.graphics.drawRect(0,0,16,16);
- // var bitmapData:BitmapData = Assets.getBitmapData("textures/sprites/character.png");
- player = new Player();
- stage.addChild(player.sprite);
- //var sheet:SpriteSheet = new SpriteSheet(sheetData);
- //var playerBitmap:Bitmap = new Bitmap(Tileset.tilesetMap["testsheet"].tileMap["testTile5"]);
- //var someotherbitmap:Bitmap = new Bitmap(Tileset.tilesetMap["testsheet"].tileMap["testTile3"]);
- //playerBitmap.scaleX = playerBitmap.scaleY = 10;
- //player.addChild(playerBitmap);
- //TextureData.parseConfig();
- //Sys.
+ gameLayer = new Sprite();
+ uiLayer = new Sprite();
+ stage.addChild(gameLayer);
+ stage.addChild(uiLayer);
+ var console2:ConsolePane = new ConsolePane();
+ uiLayer.addChild(console2);
+ uiLayer.addChild(console);
+ HProfiler.startProfiling("frametime");
+ //UITool.spawnUIEditorWindow();
}
- public static var keys:Array = [];
- public static var keysLast:Array = [];
public function onEnterFrame(e:Event):Void
{
- trace(keys);
- if( keys[Keyboard.ALTERNATE] && keys[Keyboard.ENTER] && !keysLast[Keyboard.ALTERNATE] && !keysLast[Keyboard.ENTER] ){
- if(Lib.current.stage.displayState != StageDisplayState.FULL_SCREEN_INTERACTIVE){
- Lib.current.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
- }
- else{
- Lib.current.stage.displayState = StageDisplayState.NORMAL;
- }
- }
- keysLast = keys;
- //player.x++;
- //player.y++;
+ HProfiler.stopProfiling("frametime");
+ HProfiler.startProfiling("frametime");
+ Input.onEnterFrame();
}
}
\ No newline at end of file
diff --git a/hGameTest/src/game/Input.hx b/hGameTest/src/game/Input.hx
index 846c0c10..1e1cdf6c 100644
--- a/hGameTest/src/game/Input.hx
+++ b/hGameTest/src/game/Input.hx
@@ -1,20 +1,133 @@
package game;
+import openfl.text.TextField;
import openfl.events.KeyboardEvent;
+import openfl.ui.Keyboard in Kb;
+import openfl.Lib;
+import engine.enums.console.CVarFlag;
+import engine.enums.console.CVarType;
+import engine.typedefs.console.CCmd;
+import engine.typedefs.console.CVar;
+import engine.ConVar;
+
+import game.ui.console.Console;
+import game.video.Mode;
class Input{
- public static var keys:Array = [];
- public static var keysLast:Array = [];
+ public static var keys:Map = [];
+ public static var keysLast:Map = [];
+ public static var bindMap:Map = ["~" => "toggleconsole", "\\" => "toggleconsole", "1" => "echo kak", "2" => "+attack"];
+ public static var cv_debugKeys = ConVar.registerCVar("cl_debuginput", CInt, 0, null, "print debug messages related to input to console", null, false, true, 0, 0, false);
+ public static var keyNameMap:Map = [
+ Kb.HOME => "HOME", Kb.END => "END", Kb.INSERT => "INSERT", Kb.DELETE => "DELETE", Kb.PAGE_UP => "PGUP", Kb.PAGE_DOWN => "PGDN",
+ Kb.ESCAPE => "ESC", Kb.F1 => "F1", Kb.F2 => "F2", Kb.F3 => "F3", Kb.F4 => "F4", Kb.F5 => "F5",
+ Kb.F6 => "F6", Kb.F7 => "F7", Kb.F8 => "F8", Kb.F9 => "F9", Kb.F10 => "F10", Kb.F11 => "F11",
+ Kb.F12 => "F12",
+ Kb.BACKQUOTE => "~", Kb.NUMBER_1 => "1", Kb.NUMBER_2 => "2", Kb.NUMBER_3 => "3", Kb.NUMBER_4 => "4", Kb.NUMBER_5 => "5" ,
+ Kb.NUMBER_6 => "6", Kb.NUMBER_7 => "7", Kb.NUMBER_8 => "8", Kb.NUMBER_9 => "9", Kb.NUMBER_0 => "0",
+ Kb.TAB => "TAB", Kb.Q => "Q", Kb.W => "W", Kb.E => "E", Kb.R => "R", Kb.T => "T", Kb.Y => "Y",
+ Kb.U => "U", Kb.I => "I", Kb.O => "O", Kb.P => "P", Kb.LEFTBRACKET => "[", Kb.RIGHTBRACKET => "]", Kb.BACKSLASH => "\\",
+ Kb.CAPS_LOCK => "CAPSLOCK", Kb.A => "A", Kb.S => "S", Kb.D => "D", Kb.F => "F", Kb.G => "G" , Kb.H => "H",
+ Kb.J => "J", Kb.K => "K" , Kb.L => "L", Kb.SEMICOLON => "SEMICOLON", Kb.QUOTE => "'", Kb.ENTER => "ENTER",
+ Kb.SHIFT => "SHIFT", Kb.Z => "Z", Kb.X => "X", Kb.C => "C", Kb.V => "V", Kb.B => "B", Kb.N => "N",
+ Kb.M => "M", Kb.COMMA => "COMMA",Kb.PERIOD => "PERIOD", Kb.SLASH => "/" ,
+ Kb.CONTROL => "CTRL", Kb.ALTERNATE =>"ALT"
+ ];
+ public static var keyCodeMap:Map = [
+ for(key in keyNameMap.keys()){
+ keyNameMap[key] => key;
+ }
+ ];
+ public static var cCmdGetKeyCode = ConVar.registerCCmd("getkey", (cArgs:Array) -> {
+ var keycode:Int = keyCodeMap[cArgs[0]];
+ if(cArgs != null)
+ Console.devMsg(Std.string(keycode));
+ });
public static function onKeyIsDown(e:KeyboardEvent){
- keys[e.charCode] = true;
+ if(!Std.isOfType(Lib.current.stage.focus,TextField)){
+ // Check if not null so we don't end up cooming all over unallocated memory;
+ if(bindMap[keyNameMap[e.keyCode]] != null)
+ Console.consoleInstance.parseCmd(bindMap[keyNameMap[e.keyCode]]);
+ }
+ if(!keys[e.keyCode]){
+ if(cv_debugKeys.value == 1)
+ Console.devMsg("triggered key: "+keyNameMap[e.keyCode]);
+ else if(cv_debugKeys.value > 1 )
+ Console.devMsg(""+e.keyCode);
+ }
+ keys[e.keyCode] = true;
+ var key:String = keyNameMap[e.keyCode];
+ if(cv_debugKeys.value > 0) Console.devMsg(""+key);
+
}
public static function onKeyIsUp(e:KeyboardEvent){
- keys[e.charCode] = false;
+ if(!Std.isOfType(Lib.current.stage.focus,TextField)){
+ // Make sure we're not checking a null value (this can cause a crash)
+ if(bindMap[keyNameMap[e.keyCode]] != null){
+ if(bindMap[keyNameMap[e.keyCode]].indexOf("+") == 0){
+ Console.consoleInstance.parseCmd(StringTools.replace(bindMap[keyNameMap[e.keyCode]],"+","-"));
+ }
+ }
+ }
+ keys[e.keyCode] = false;
}
+ // public static function resolveKeyName(key:Int):String
+ // {
+ // return keyNameMap[key];
+ // }
+ public static function bindKey(input:String, action:String):Void
+ {
+ bindMap[input] = action;
+ }
+ private static var bind:CCmd = ConVar.registerCCmd("bind", (cArgs:Array)->{
+ cArgs[0] = cArgs[0].toUpperCase();
+ if(cArgs.length == 2){
+ if(keyCodeMap[cArgs[0]]!= null) {
+ if(cArgs[1].indexOf('"') == 0 && cArgs[1].lastIndexOf('"') == cArgs[1].length-1){
+ bindKey(cArgs[0], cArgs[1].substring(1,cArgs[1].length-1));
+ }
+ else{
+ bindKey(cArgs[0], cArgs[1]);
+ }
+
+ }
+ }
+ else if(cArgs.length == 1){
+ Console.devMsg(bindMap[cArgs[0]]);
+ }
+ else{
+ Console.devMsg("usage: bind ");
+ }
+ });
public static function onEnterFrame()
{
-
- keysLast = keys;
+ if( keys[Kb.BACKQUOTE]){
+ //Console.toggle();
+ if(cv_debugKeys.value > 0) Console.devMsg("toggle console");
+
+ }
+ if( keys[Kb.ALTERNATE] && keys[Kb.ENTER] && !keysLast[Kb.ALTERNATE] && !keysLast[Kb.ENTER] ){
+ Mode.switchFsMode();
+ }
+ // Console Input field is in focus
+ if(Lib.current.stage.focus == Console.consoleInstance.cIn){
+ if ( keys[Kb.ENTER] && !keysLast[Kb.ENTER] && !keysLast[Kb.ALTERNATE]){
+ Console.consoleInstance.submitInput();
+ }
+ if (keys[Kb.UP] && !keysLast[Kb.UP]){
+ Console.histPrev();
+ }
+ if (keys[Kb.DOWN] && !keysLast[Kb.DOWN]){
+ Console.histNext();
+ }
+
+ }
+ if(Console.consoleInstance.visible){
+ if (keys[Kb.ESCAPE]){
+ Console.toggle();
+ }
+ }
+ keysLast = keys.copy();
}
}
\ No newline at end of file
diff --git a/hGameTest/src/game/ui/UIContianer.hx b/hGameTest/src/game/ui/UIContianer.hx
new file mode 100644
index 00000000..35696022
--- /dev/null
+++ b/hGameTest/src/game/ui/UIContianer.hx
@@ -0,0 +1,27 @@
+package game.ui;
+
+import openfl.geom.Point;
+import openfl.display.Sprite;
+
+
+class UIContianer extends Sprite{
+ public static var UIDrawList:Array=[];
+ public var anchor:Point;
+ public function new(panchor,scale){
+ super();
+ }
+ public function onResize(){
+
+ }
+ public function hide(){
+
+ }
+ public function show(){
+
+ }
+ public function getParent()
+ {
+ return parent;
+ }
+
+}
diff --git a/hGameTest/src/game/ui/console/Console.hx b/hGameTest/src/game/ui/console/Console.hx
new file mode 100644
index 00000000..12b81676
--- /dev/null
+++ b/hGameTest/src/game/ui/console/Console.hx
@@ -0,0 +1,393 @@
+package game.ui.console;
+
+import game.ui.text.TextFormats;
+import assets.Fonts;
+import openfl.Lib;
+import openfl.events.Event;
+import openfl.text.TextFieldAutoSize;
+import openfl.text.TextField;
+import openfl.display.Sprite;
+import openfl.Assets;
+import openfl.text.TextFormat;
+import openfl.text.TextFieldType;
+import engine.ConVar;
+import engine.enums.console.CVarFlag;
+import engine.typedefs.console.CVar;
+import engine.typedefs.console.CCmd;
+import game.ui.console.elements.ConsoleInput;
+import engine.ui.UIPane;
+
+
+class Console extends Sprite{
+ public var textFormat:TextFormat;
+ public var cOut:TextField;
+ public var cIn:TextField;
+ public var cInput:ConsoleInput;
+ public var cAutoComp:TextField;
+ public static var consoleInstance:Console;
+ public var cvar_mat_consolebg:CVar;
+ public var ccmd_visible:CCmd = ConVar.registerCCmd("toggleconsole",(cArgs:Array)->{
+ toggle();
+ });
+ public function new(){
+ super();
+
+ consoleInstance = this;
+
+
+ var consolePane:UIPane = new UIPane("yeeto",{width:800, height:600});
+
+ this.addChild(consolePane.sprite);
+ consolePane.layout = VERTICAL;
+
+ //graphics.beginFill(0x555555);
+ //graphics.drawRect(0,0,800,600);
+
+ cInput = new ConsoleInput();
+ cIn = cInput.tf;
+
+ //cIn.setTextFormat(textFormat);
+ cInput.y = 600-cInput.height-12;
+ cInput.x = 12;
+
+ cvar_mat_consolebg = ConVar.registerCVar("mat_consolebg",CString,"0x222222",null,"console background color", ()->{
+ cOut.backgroundColor = Std.parseInt(cvar_mat_consolebg.value);
+ cIn.backgroundColor = Std.parseInt(cvar_mat_consolebg.value);
+ },false,false,0,0,false);
+
+ cOut = new TextField();
+ cAutoComp = new TextField();
+
+ drawFields(cOut, cAutoComp);
+
+
+ cOut.addEventListener(Event.CHANGE, onOutputTextChange);
+ cIn.addEventListener(Event.CHANGE, onInputTextChange);
+ this.addChild(cOut);
+ this.addChild(cInput);
+ this.addChild(cAutoComp);
+ ConVar.registerCCmd("echo", (args:Array) -> { Console.devMsg(args.join(" ").split('"').join(""));});
+ ConVar.registerCCmd("quit", (args:Array) -> { Lib.application.window.close();});
+ }
+ public function drawFields(cOut:TextField, cAutoComp:TextField){
+
+ cOut.text = "hConsole Initialized\n";
+ cOut.defaultTextFormat = TextFormats.getFormats().cOutputFmt;
+ cOut.wordWrap = true;
+ //cOut.autoSize = TextFieldAutoSize.LEFT;
+ cOut.multiline = true;
+ cOut.background = true;
+ cOut.backgroundColor = Std.parseInt(cvar_mat_consolebg.value);
+ cOut.width = 800 - 24;
+ cOut.height = 600 - cIn.height - 38;
+ cOut.y = 12;
+ cOut.x = 12;
+
+ cAutoComp.text = "";
+ cAutoComp.defaultTextFormat = TextFormats.getFormats().cInputFmt;
+ cAutoComp.wordWrap = false;
+ cAutoComp.multiline = true;
+ cAutoComp.background = true;
+ cAutoComp.backgroundColor = 0x11111100;
+ cAutoComp.border = true;
+ cAutoComp.borderColor = 0x55555500;
+ cAutoComp.selectable = false;
+ cAutoComp.width = 400;
+ cAutoComp.height = 32*5;
+ cAutoComp.visible = false;
+ cAutoComp.x = 0;
+ cAutoComp.y = 600;
+ }
+
+
+ public function parseCmd(cmd:String, bNoHist:Bool = false){
+ if(!bNoHist)
+ history.push(cmd);
+
+ cmd = cmd.split(";").join(" ; ");
+ var subStrings = [];
+ var startQuoteIndex:Int = cmd.indexOf('"');
+ var endQuoteIndex:Int;
+ if(startQuoteIndex != -1){
+ while((startQuoteIndex = cmd.indexOf('"')) > -1){
+ //push start of the cmd up until the quotes start
+ subStrings.push(cmd.substring(0,startQuoteIndex));
+ //find next quote
+ endQuoteIndex = cmd.indexOf('"',startQuoteIndex+1)+1;
+ if(endQuoteIndex == 0){
+ cmd+='"';
+ endQuoteIndex = cmd.length;
+
+ }
+ //push quote content
+ subStrings.push(cmd.substring(startQuoteIndex,endQuoteIndex));
+ cmd = cmd.substr(endQuoteIndex);
+ }
+ }
+ subStrings.push(cmd);
+ //Split args
+ var newSubStrings = [];
+ for(subString in subStrings){
+ if(subString.indexOf('"') == -1){
+ // split spaced args
+ for(str in subString.split(" ")){
+ //we want to discard empty strings
+ if(str != "")
+ newSubStrings.push(str);
+ }
+
+ }
+ else{
+ newSubStrings.push(subString);
+ }
+ }
+ var commands = [];
+ //split off additional commands
+ while(newSubStrings.length > 0){
+ for(i in 0...newSubStrings.length){
+ if(newSubStrings[i] == ";"){
+ commands.push(newSubStrings.splice(0,i));
+ newSubStrings.shift();
+ break;
+ }
+ if(newSubStrings.length-1 == i){
+ commands.push(newSubStrings);
+ newSubStrings = [];
+ }
+ }
+ }
+ trace(commands);
+ execCommands(commands);
+ }
+ public function execCommands(commands:Array>){
+ for(command in commands){
+ // Store command name, value and args
+ var cName:String = command[0];
+ var cValue:String = command[1];
+ var cArgs:Array = command.slice(1);
+ //Check if convar with that name actually exists
+ if(ConVar.isCVar(cName)){
+ //Get reference to convar object
+ var cv:CVar = ConVar.getCVar(command[0]);
+ //Check number of params
+ if(command.length == 1){
+ //No params after the cmd, print help string
+ devMsg(cv.name+" - "+cv.helpString);
+ devMsg(cv.name+" = "+cv.value);
+ }
+ else{
+ //Check for convar type and set value accordingly
+ switch(cv.type){
+ case CInt:
+ ConVar.setCVar(cName,Std.parseInt(cValue));
+ trace(cValue);
+ break;
+ case CFloat:
+ ConVar.setCVar(cName,Std.parseFloat(cValue));
+ break;
+ case CBool:
+ cValue = cValue.toLowerCase();
+ if(cValue == "1" || cValue == "true"){
+ ConVar.setCVar(cName,true);
+ }
+ else if(cValue == "0" || cValue == "false"){
+ ConVar.setCVar(cName,false);
+ }
+ break;
+ case CString:
+ ConVar.setCVar(cName,cValue);
+ break;
+ }
+
+ }
+
+ }
+ //convar is actually a command, run it.
+ else if(ConVar.isCmd(cName)){
+ ConVar.runCmd(cName,cArgs);
+ }
+ //convar doesn't exist
+ else{
+ devMsg("unkown command: "+command[0]);
+ }
+ }
+ }
+ public function submitInput(){
+ cOut.appendText(">"+cInput.getText()+"\n");
+ parseCmd(cInput.getText());
+ cInput.setText("");
+ cAutoComp.visible = false;
+ cOut.scrollV = cOut.maxScrollV;
+ histSelect = -1;
+ }
+ public function onOutputTextChange(e:Event){
+ cOut.scrollV = cOut.maxScrollV;
+ }
+ public function onInputTextChange(e:Event){
+ if(cInput.getText() != ""){
+ cAutoComp.text = "";
+ for(string in (autocompleteList = getCompList())){
+ cAutoComp.text += string+"\n";
+ trace(string);
+ }
+ cAutoComp.visible = true;
+ }
+ else{
+ cAutoComp.visible = false;
+ autocompleteList = history;
+ }
+ }
+ public static function toggle():Void
+ {
+ consoleInstance.visible = !consoleInstance.visible;
+ if(!consoleInstance.visible){
+ if(Lib.current.stage.focus == consoleInstance.cIn){
+ Lib.current.stage.focus = null;
+ }
+ }
+ else{
+ Lib.current.stage.focus = consoleInstance.cIn;
+ }
+ }
+ public static function devMsg(msg:String):Void
+ {
+ consoleInstance.cOut.appendText(msg+"\n");
+ consoleInstance.cOut.scrollV = consoleInstance.cOut.maxScrollV;
+ }
+ public static var history:Array = [];
+ public static var histSelect:Int = -1;
+ public static var tmpInput:String = "";
+ public static var autocompleteList:Array = [];
+ public static var compSelect:Int = -1;
+ public static function getCompList():Array
+ {
+ // Split words
+ var inp:Array = consoleInstance.cInput.getText().split(" ");
+ var inpStripped:Array = [
+ for(word in inp){
+ if(word != "" && word != " "){
+ word;
+ }
+ }
+ ];
+ // Stop if input is empty
+ if(inp.length == 0) return [];
+
+ var cVars:Array = ConVar.getCVarNames();
+ var cVarFiltered:Array = [];
+ // Loop through convars
+ for(cVar in cVars){
+ //if there's one word just check if the convar starts with the input string
+ if(inp.length == 1)
+ {
+ // Check if the cvar starts with the input
+ if(cVar.indexOf(inp[0]) == 0){
+ cVarFiltered.push(cVar);
+ }
+ }
+ // User pressed space at least once but entered no other words. Check if first word occurs at any position
+ else if(inpStripped.length == 1 && inp.length > 1){
+ if(cVar.indexOf(inp[0]) > -1){
+ cVarFiltered.push(cVar);
+ }
+ }
+ // Multiple words, check for cvars that contain all of them
+ else if(inpStripped.length > 1)
+ {
+ var bWordNotPresent:Bool = false;
+ for(word in inpStripped){
+ if(cVar.indexOf(word) == -1){
+ bWordNotPresent = true;
+ }
+ }
+ if(!bWordNotPresent)
+ cVarFiltered.push(cVar);
+ }
+ }
+ return cVarFiltered;
+ }
+ public static function histPrev():Void
+ {
+ // Only complete if input field is empty or scrolling through hist
+ if(consoleInstance.cInput.getText() == "" || histSelect != -1){
+ // Store current input in tmpInput
+ if(histSelect == -1) tmpInput = consoleInstance.cInput.getText();
+ // Only go through history if history is not empty
+ if(history.length != 0){
+ // Check if currently selecting a history entry
+ if(histSelect >= 0){
+ histSelect--;
+ }
+ // Not currently selecting a history entry
+ else{
+ // Put selector to the newest
+ histSelect = history.length -1;
+ }
+ if(histSelect != -1){
+ // Put correct history entry in the input field
+ consoleInstance.cInput.setText(history[histSelect]);
+ }
+ else{
+ // Restore tmp input
+ consoleInstance.cInput.setText(tmpInput);
+ }
+ }
+ // History is empty
+ else{
+ // Do nothing
+ return;
+ }
+ }
+ // Now we need to descend through the autocomplete list
+ else{
+ if(autocompleteList.length == 0){
+ return;
+ }
+ else{
+ // Check if currently selecting an autocomplete entry
+ if(compSelect > -1){
+
+ }
+ // Not currently selecting an autocomplete entry
+ else{
+
+ }
+ }
+
+
+ }
+ }
+ public static function histNext():Void
+ {
+ // Only complete if input field is empty or scrolling through hist
+ if(consoleInstance.cIn.text == "" || histSelect != -1){
+ // Store current input in tmpInput
+ if(histSelect == -1) tmpInput = consoleInstance.cIn.text;
+ // Only go through history if history is not empty
+ if(history.length != 0){
+ // Check if currently selecting a history entry
+ if(histSelect < history.length -1){
+ histSelect++;
+ }
+ // Otherwise wrap around
+ else{
+ // Put selector to no selection
+ histSelect = -1;
+ }
+ if(histSelect != -1){
+ // Put correct history entry in the input field
+ consoleInstance.cIn.text = history[histSelect];
+ }
+ else{
+ // Restore tmp input
+ consoleInstance.cIn.text = tmpInput;
+ }
+ }
+ // History is empty
+ else{
+ // Do nothing
+ return;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/hGameTest/src/game/ui/console/ConsolePane.hx b/hGameTest/src/game/ui/console/ConsolePane.hx
new file mode 100644
index 00000000..99fe5910
--- /dev/null
+++ b/hGameTest/src/game/ui/console/ConsolePane.hx
@@ -0,0 +1,65 @@
+package game.ui.console;
+
+import engine.HProfiler;
+import engine.ui.UIPane;
+import engine.ui.UIElement;
+import openfl.text.TextField;
+import openfl.display3D.textures.Texture;
+import openfl.display.Sprite;
+
+class ConsolePane extends Sprite{
+ public function new(){
+ super();
+ var testPane:UIPane = new UIPane("test",{height:800,width:600});
+ testPane.layout = VERTICAL;
+
+ var titlebarPane:UIPane = new UIPane("titlebar", {height:32, width: 600});
+ titlebarPane.align = START;
+ titlebarPane.layout = HORIZONTAL;
+
+ var inputPane:UIPane = new UIPane("inputbar", {height:32, width: 600});
+ inputPane.align = END;
+ inputPane.layout = HORIZONTAL;
+
+ var outputPane:UIPane = new UIPane("output pane", {height: 32, width: 600});
+ outputPane.align = START;
+ outputPane.dimensions.expandBehavior = STRETCH;
+ HProfiler.startProfiling("ui_resize");
+ testPane.width = 1000;
+ HProfiler.stopProfiling("ui_resize");
+
+ testPane.addChild(titlebarPane);
+ testPane.addChild(inputPane);
+ testPane.addChild(outputPane);
+
+
+
+ var textField:TextField = new TextField();
+ textField.background = true;
+ textField.backgroundColor = 0x00ff00;
+
+ var testInputElement:UIElement = new UIElement("inputelem", {height: 32, width: 300},textField);
+ testInputElement.dimensions.expandBehavior = STRETCH;
+ testInputElement.padding = {x: 8, y: 8};
+
+ var inputButtonPane:UIPane = new UIPane("submit button", {height: 32, width: 32});
+ inputButtonPane.align = END;
+
+ var inputFieldPane:UIPane = new UIPane("input field", {height: 32, width: 3});
+ inputFieldPane.align = START;
+ inputFieldPane.dimensions.expandBehavior = STRETCH;
+
+ inputPane.addChild(inputButtonPane);
+ inputPane.addChild(inputFieldPane);
+ //inputFieldPane.addChild(testInputElement);
+
+
+
+
+
+
+ addChild(testPane.sprite);
+ }
+}
+
+
diff --git a/hGameTest/src/game/ui/console/elements/ConsoleInput.hx b/hGameTest/src/game/ui/console/elements/ConsoleInput.hx
new file mode 100644
index 00000000..2c34565f
--- /dev/null
+++ b/hGameTest/src/game/ui/console/elements/ConsoleInput.hx
@@ -0,0 +1,51 @@
+package game.ui.console.elements;
+
+import openfl.events.Event;
+import openfl.display.Sprite;
+import openfl.text.TextField;
+import openfl.text.TextFieldType;
+import openfl.text.TextFormat;
+import openfl.Assets;
+import game.ui.text.TextFormats;
+
+class ConsoleInput extends Sprite
+{
+ public var tf:TextField;
+ public function new(){
+ super();
+ tf = new TextField();
+ tf.defaultTextFormat = TextFormats.getFormats().cInputFmt;
+ tf.text = "";
+ //tf.setTextFormat(new TextFormat(Assets.getFont("fonts/Terminus.ttf").fontName, 24, 0x00ff00));
+ trace(tf.getTextFormat().color);
+ trace(tf.getTextFormat().font);
+ tf.type = TextFieldType.INPUT;
+ tf.multiline = false;
+ //tf.autoSize = TextFieldAutoSize.LEFT;
+ tf.width = 800-24;
+ tf.height = tf.textHeight+2;
+ tf.background = true;
+ tf.backgroundColor = 0x222222;
+ tf.selectable = true;
+ this.addChild(tf);
+ this.addEventListener(Event.RESIZE,onResize);
+ tf.addEventListener(Event.CHANGE, onTextChange);
+ }
+ public function onResize(e:Event){
+ tf.width = this.width;
+ }
+ public function onTextChange(e:Event){
+
+ }
+ public function clearText(){
+ tf.text = "";
+ }
+ public function getText():String
+ {
+ return tf.text;
+ }
+ public function setText(t:String){
+ tf.text = t;
+ }
+
+}
\ No newline at end of file
diff --git a/hGameTest/src/game/ui/text/TextFormats.hx b/hGameTest/src/game/ui/text/TextFormats.hx
new file mode 100644
index 00000000..d87a6570
--- /dev/null
+++ b/hGameTest/src/game/ui/text/TextFormats.hx
@@ -0,0 +1,24 @@
+package game.ui.text;
+
+
+import openfl.text.TextFormat;
+import openfl.Assets;
+import assets.Fonts;
+
+class TextFormats{
+ public static var formats:TextFormats;
+ public var cInputFmt:TextFormat;
+ public var cOutputFmt:TextFormat;
+ public function new(){
+ cInputFmt = new TextFormat(Assets.getFont("fonts/Terminus.ttf").fontName, 24, 0xffffff);
+ cOutputFmt = new TextFormat(Assets.getFont("fonts/Terminus.ttf").fontName, 24, 0xffffff);
+ }
+ public static function getFormats():TextFormats
+ {
+ if(formats == null){
+ formats = new TextFormats();
+ }
+ return formats;
+ }
+
+}
\ No newline at end of file
diff --git a/hGameTest/src/game/video/Mode.hx b/hGameTest/src/game/video/Mode.hx
new file mode 100644
index 00000000..65c0b772
--- /dev/null
+++ b/hGameTest/src/game/video/Mode.hx
@@ -0,0 +1,36 @@
+package game.video;
+
+import engine.ConVar;
+import engine.typedefs.console.CCmd;
+import openfl.Lib;
+import openfl.display.StageDisplayState;
+
+class Mode
+{
+ public static function getWindow():lime.ui.Window
+ {
+ return Lib.application.window;
+ }
+ public static function setVideoMode(width:Int, height:Int, fs:Int = null){
+ getWindow().resize(width,height);
+ if(fs != null){
+ switchFsMode(fs);
+ }
+ }
+ public static var cvMatSetVideoMode:CCmd = ConVar.registerCCmd("mat_setvideomode",(args:Array)->{
+ setVideoMode(Std.parseInt(args[0]), Std.parseInt(args[1]), Std.parseInt(args[2]));
+ });
+ public static function switchFsMode(toState:Int = 0){
+ if(toState == 0){
+ if(Lib.current.stage.displayState != StageDisplayState.FULL_SCREEN_INTERACTIVE){
+ Lib.current.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
+ }
+ else{
+ Lib.current.stage.displayState = StageDisplayState.NORMAL;
+ }
+ }
+ else{
+
+ }
+ }
+}
\ No newline at end of file