I've been playing about over the last few hours and have created the beginnings of (what I believe to be) a useful tool.
OpenConsole(tm)(c)(R)(ASAP)
What it is:
What it isn't:
My hope is that people will add and post useful fixes/additions to it so everyone can benefit from it.
It took me two lines of code to add this to rockout.bmx so it's definitely easy to implement.
Comments and feedback welcome.
OpenConsole(tm)(c)(R)(ASAP)
What it is:
A command console for adding to your apps.
Useable
pretty easy to plug in to an app
probably riddled with bugs and memory leaks
Useable
pretty easy to plug in to an app
probably riddled with bugs and memory leaks
What it isn't:
anywhere near finished
attractive
a banana
related to Bob Monkhouse
riddled with spiders and leeks
perfect
properly commented
attractive
a banana
related to Bob Monkhouse
riddled with spiders and leeks
perfect
properly commented
My hope is that people will add and post useful fixes/additions to it so everyone can benefit from it.
It took me two lines of code to add this to rockout.bmx so it's definitely easy to implement.
Rem Openconsole Version 0.1.0 created by Kris Kelly (Perturbatio) (C) 2005 TODO: Add text wrapping Add output scrolling Use TAB to autocomplete a command Perhaps turn it into a module? EndRem Strict Function SplitString:TList(inString:String, Delim:String) Local tempList : TList = New TList Local currentChar : String = "" Local count : Int = 0 Local TokenStart : Int = 0 If Len(Delim)<>1 Then Return Null inString = Trim(inString) For count = 0 Until Len(inString) If inString[count..count+1] = delim Then tempList.AddLast(inString[TokenStart..Count]) TokenStart = count + 1 End If FlushMem Next tempList.AddLast(inString[TokenStart..Count]) Return tempList End Function Function GetKey:Int() Const RepeatRate : Int = 100 'ms Global LastTime:Long = MilliSecs() Global LastKey:Int = 0 Local key:Int = 0 While Key <= 226 If KeyDown(key) Then Exit Key:+ 1 Wend FlushMem If Key = 227 Then Return 0 If Key = LastKey Then If MilliSecs()-LastTime < RepeatRate Then Return 0 EndIf LastTime = MilliSecs() LastKey = Key If Key < 227 Then Return Key Else Return 0 End Function Type TRGB Field Red : Int 'could use byte but int is faster Field Green : Int Field Blue : Int Field Alpha : Int Method AsInt:Int() Return ( Red| (Green Shl 8) | (Blue Shl 16)) End Method Method FromInt(col:Int) Red = col Shr 16 & $FF Green = col Shr 8 & $FF Blue = col & $FF End Method Method SetCol() SetColor Red, Green, Blue End Method End Type Type TOpenConsole Field _Visible : Int Field _X : Float Field _Y : Float Field _Width : Float Field _Height : Float Field _FontCol : TRGB Field _BGCol : TRGB Field CmdProcessor : TCommandProcessor Field _BorderWidth : Int = 4 Field HotKey : Int = KEY_TAB Field HotCtrlKey : Int = KEY_CONTROL Field Alpha : Float = 0.75 Field TextAlpha : Float = 1.0 Field History : TList Field HistoryPos : Int = -1 'represents the position in the History List (-1 means no position) Field InputBuffer : String Field CursorPos : Int = 0 Field OutList : TList Field OutListPos : Int = 0 'Get Field Methods Method Visible:Int() Return _Visible End Method Method X:Float() Return _X End Method Method Y:Float() Return _Y End Method Method Width:Float() Return _Width End Method Method Height:Float() Return _Height End Method 'Set Field Methods Method SetVisible(val:Int) _Visible = val End Method Method SetX(val:Float) _X = val End Method Method SetY(val:Float) _Y = val End Method Method SetWidth(val:Float) _Width = val End Method Method SetHeight(val:Float) _Height = val End Method Method Draw() Local LineHeight:Int = (TextHeight(InputBuffer)+2) 'Draw BG SetBlend(AlphaBlend) SetAlpha(Alpha) _BGCol.SetCol() DrawRect(X(), Y(), Width(), Height()) 'Draw Text SetAlpha(TextAlpha) _FontCol.SetCol() SetViewport(X() + _BorderWidth, Y() + _BorderWidth, Width() - (_BorderWidth Shl 1), Height() - (_BorderWidth Shl 1)) SetOrigin(X() + _BorderWidth, Y() + _BorderWidth) DrawText(InputBuffer, 0, 0) 'Draw Cursor DrawText("_", TextWidth(InputBuffer[..CursorPos]), 0) DrawText("_", TextWidth(InputBuffer[..CursorPos]), 1) DrawText("_", TextWidth(InputBuffer[..CursorPos]), 2) 'Draw Command Output If OutList.Count() > 0 Then For Local count:Int = OutListPos To OutList.Count()-1 DrawText(String(OutList.ValueAtIndex(count)), 0, LineHeight+(LineHeight * count)) FlushMem Next EndIf 'restore viewport and origin SetViewport(0,0,GraphicsWidth(), GraphicsHeight()) SetOrigin(0,0) SetAlpha(1.0) End Method Method Update() If Visible() Then Draw() CheckInput() End Method Method CheckInput() Local ch:Int 'visibility of console If Not Visible() Then If KeyHit(HotKey) And KeyDown(HotCtrlKey) Then SetVisible(True) FlushKeys() EndIf Return EndIf If KeyHit(HotKey) And KeyDown(HotCtrlKey) Then SetVisible(False) EndIf 'Main input section ch = GetChar() If (ch > 31) And (ch < 126) Then InputBuffer = InputBuffer[..CursorPos]+Chr(ch)+InputBuffer[CursorPos..]':+Chr(ch) CursorPos:+1 EndIf Select ch Case 8 'Backspace If CursorPos > 0 Then InputBuffer = InputBuffer[..CursorPos-1]+InputBuffer[CursorPos..] 'backspace CursorPos:-1 EndIf Case 13 'Return If Len(InputBuffer)>0 Then History.AddFirst(InputBuffer) CmdProcessor.Execute(InputBuffer) EndIf InputBuffer = "" 'return CursorPos = 0 HistoryPos = -1 Case 27 'Escape InputBuffer = "" 'escape CursorPos = 0 HistoryPos = -1 End Select Local SpecialKey = GetKey() Select SpecialKey Case KEY_LEFT If CursorPos>0 Then CursorPos:- 1 Case KEY_RIGHT If CursorPos < Len(InputBuffer) Then CursorPos:+ 1 Case KEY_UP If History.Count() > 0 Then If HistoryPos < History.Count()-1 Then HistoryPos:+ 1 InputBuffer = String(History.ValueAtIndex(HistoryPos)) CursorPos = Len(InputBuffer) EndIf Case KEY_DOWN If History.Count() > 0 Then If HistoryPos > -1 Then HistoryPos:- 1 If HistoryPos < 0 Then InputBuffer = "" Else InputBuffer = String(History.ValueAtIndex(HistoryPos)) EndIf CursorPos = Len(InputBuffer) EndIf Case KEY_DELETE If CursorPos < Len(InputBuffer) Then InputBuffer = InputBuffer[..CursorPos]+InputBuffer[CursorPos+1..] EndIf Case KEY_END CursorPos = Len(InputBuffer) Case KEY_HOME CursorPos = 0 Case KEY_TAB 'find next command that begins with the current InputBuffer text (i.e. if the user has typed "Cle" then show Clear) 'NEED TO IMPLEMENT LATER End Select End Method Method Out(outString:String) OutList.AddFirst(outString) End Method Function Create:TOpenConsole(Visible:Int, X:Float, Y:Float, Width:Float, Height:Float, FontCol:Int = $FFFFFF, BGCol:Int = $000000) Local tempConsole:TOpenConsole = New TOpenConsole tempConsole.CmdProcessor = TCommandProcessor.Create() tempConsole.CmdProcessor.Parent = tempConsole tempConsole.SetVisible(Visible) tempConsole.SetX(X) tempConsole.SetY(Y) tempConsole.SetWidth(Width) tempConsole.SetHeight(Height) tempConsole._FontCol:TRGB = New TRGB tempConsole._FontCol.FromInt(FontCol) tempConsole._BGCol:TRGB = New TRGB tempConsole._BGCol.FromInt(BGCol) tempConsole.History:TList = New TList tempConsole.OutList:TList = New TList Return tempConsole End Function End Type 'Parameter Types Const ptByte : Int = 0 Const ptInteger : Int = 1 Const ptFloat : Int = 2 Const ptString : Int = 3 Type TCommand Field Command : String Field Action(Owner:TOpenConsole Var, params:TList Var) Field HelpText : String Function Create:TCommand(cmd:String, Action(Owner:TOpenConsole Var, params:TList Var), HelpTxt:String) If Len(cmd)=0 Then Return Null Local tempCommand:TCommand = New TCommand tempCommand.Command = cmd tempCommand.Action = Action tempCommand.HelpText = HelpTxt Return tempCommand End Function End Type Type TCommandProcessor Field CommandList : TList Field Parent:TOpenConsole Method Execute(cmd:String) ?Debug Print "Command String: " + cmd Print "Command List Count: " + CommandList.Count() ? Local cmdList:TList = SplitString(cmd, " ") ?Debug Print "cmdList val 0: " + String(cmdList.ValueAtIndex(0)) Print "Command List Val 0 String:" + String(TCommand(CommandList.ValueAtIndex(0)).Command).ToUpper() ? Local command:TCommand = GetCommand(String(cmdList.ValueAtIndex(0))) If command <> Null Then ?Debug Print "Command: "+command.command Print "Help: " + command.HelpText ? command.Action(Parent, cmdList) Else Parent.Out("Command not found: " + String(cmdList.ValueAtIndex(0))) EndIf End Method Method RegisterCommand(cmd:TCommand) If Not GetCommand(cmd.command) Then ListAddLast(CommandList, cmd) EndIf End Method Method GetCommand:TCommand(cmd:String) ?Debug Print "Entered GetCommand with " + cmd ? 'iterate through command list and check each TCommand entry for cmd$ If CommandList.Count() < 1 Then Return Null ?Debug Print "commandList cound greater than 0" ? For Local tempCommand:TCommand = EachIn CommandList ?Debug Print "Iterating through CommandList" Print tempCommand.Command.ToUpper() + " ------ " + cmd.ToUpper() ? If tempCommand.Command.ToUpper() = cmd.ToUpper() Then Return tempCommand EndIf FlushMem Next Return Null End Method Function Create:TCommandProcessor() Local tempCommandProcessor:TCommandProcessor = New TCommandProcessor tempCommandProcessor.CommandList:TList = New TList Return tempCommandProcessor End Function End Type '''''''''''''''''''' '''''''''''''''''''' ''''''' TEST ''''''' '''''''''''''''''''' '''''''''''''''''''' Graphics 640,480,0,0 Global con:TOpenConsole = TOpenConsole.Create(False, 0,0,640,200, $99FF99, $006600) con.OutList.AddLast("Press CTRL+TAB to show/hide console") 'COMMAND SetConsoleAlpha Global cmdSetConsoleAlpha:TCommand = TCommand.Create("SetConsoleAlpha", cmdSetConsoleAlpha_Action, "Set the alpha value of the console") Function cmdSetConsoleAlpha_Action(Owner:TOpenConsole Var, params:TList Var) Local val:Float If params.Count() >1 Then val = String(params.ValueAtIndex(1)).ToFloat() If val => 0.1 And val <= 1.0 Then owner.Alpha = val Else Owner.Out("Error: alpha value range from 0.1 to 1.0") EndIf Else Owner.Out("Error: alpha value is not optional") EndIf End Function con.cmdProcessor.RegisterCommand(cmdSetConsoleAlpha) 'COMMAND Quit Global cmdQuit:TCommand = TCommand.Create("Quit", cmdQuit_Action, "Quit the program") Function cmdQuit_Action(Owner:TOpenConsole Var, params:TList Var) End End Function con.cmdProcessor.RegisterCommand(cmdQuit) 'COMMAND ListCommands Global cmdListCommands:TCommand = TCommand.Create("ListCommands", cmdListCommands_Action, "List all the commands") Function cmdListCommands_Action(Owner:TOpenConsole Var, params:TList Var) For Local tempCommand:TCommand = EachIn Owner.cmdProcessor.CommandList Owner.Out(tempCommand.Command + " - " + tempCommand.HelpText) FlushMem Next End Function con.cmdProcessor.RegisterCommand(cmdListCommands) 'COMMAND Help Global cmdHelp:TCommand = TCommand.Create("Help", cmdHelp_Action, "Provides help on the specified command (USAGE: Help <command>)") Function cmdHelp_Action(Owner:TOpenConsole Var, params:TList Var) 'if too many parameters passed If params.Count() > 2 Then Owner.Out(cmdHelp.HelpText) Owner.Out("Maximum of one parameter allowed") EndIf 'if one parameter passed then look it up If Params.Count()>1 Then Local paramString:String = String(Params.ValueAtIndex(1)) Local tempCommand:TCommand = Owner.cmdProcessor.GetCommand(ParamString) If tempCommand <> Null Then If Len(tempCommand.HelpText)>0 Then owner.out(tempCommand.HelpText) Else owner.out("No help found for " + ParamString) EndIf Else owner.out("Command not found: " + ParamString) EndIf Else 'if no parameters passed, return the Help for cmdHelp Owner.Out("Type ListCommands for a full list of all commands") Owner.Out(cmdHelp.HelpText) EndIf End Function con.cmdProcessor.RegisterCommand(cmdHelp) 'COMMAND ClearHistory Global cmdClearHistoryList:TCommand = TCommand.Create("ClearHistory", cmdClearHistoryList_Action, "Clears the command history.") Function cmdClearHistoryList_Action(Owner:TOpenConsole Var, params:TList Var) If Params.Count()>1 Then If String(Params.ValueAtIndex(1)) = "/?" Then Owner.Out(cmdClearHistoryList.HelpText) Return EndIf EndIf Owner.History.Clear() Owner.HistoryPos = -1 Owner.Out("History cleared.") End Function con.cmdProcessor.RegisterCommand(cmdClearHistoryList) 'COMMAND Cls Global cmdClearOutList:TCommand = TCommand.Create("Cls", cmdClearOutList_Action, "Clears the output buffer.") Function cmdClearOutList_Action(Owner:TOpenConsole Var, params:TList Var) Owner.OutList.Clear() Owner.OutListPos = 0 End Function con.cmdProcessor.RegisterCommand(cmdClearOutList) Global CurrentMem:Int Global LastMem : Int While Not (KeyDown(KEY_ESCAPE) And KeyDown(KEY_SHIFT)) CurrentMem = MemAlloced() If CurrentMem <> LastMem Then 'SetAppTitle is in AppFuncs.mod ( <a href="http://www.blitzbasic.com/Community/posts.php?topic=43341" target="_blank">http://www.blitzbasic.com/Community/posts.php?topic=43341</a> ) 'just comment this part out If you don't have it SetAppTitle("Open Console test - Press Shift+Escape to Quit " + CurrentMem) LastMem = CurrentMem EndIf Cls 'DRAW A BLOCK TO SHOW THE ALPHA SetColor(255,0,0) DrawRect(10,10,600,250) con.Update() FlushMem() Flip Wend End
Comments and feedback welcome.