Here's my fledgling class for a Console in OpenGL.
I've implemented it using NeHe tutorial#17 as a testbed.
I'll post that later if anyone wants to see the Console working.
It's a Quake style console, the strings are stored in a dynamic array (can resize itself during runtime), no support for anything cool yet.
Font is assumed to be from a 256x256x24bit bmp, as 16x16 tiles (256 printable characters), as per NeHe tutorial#17.

;Console class
;October 18, 2004
;Console Commands are
;Implemented console commands:
;List GLExtensions (or simply "list glx") - enlists all opengl extensions supported by the local hardware

class Console, ,C++ compatible
virtual SetConsoleSize:dwWidth, dwHeight ;Should be called whenever screensize changed
virtual Print:xpixel, ypixel, pString, Set ;Set=CharacterSet, we fit 2 of them in our fontbitmap
virtual Display:yDisplacement
virtual ScrollDown ;Scroll the display Down (by incrementing FirstLine)
virtual ScrollUp ;Scroll the display Up (by decrementing FirstLine)
virtual AddString:pString ;Add a String to the internal StringArray (mem will be allocated)
virtual Interpret:pCommandString ;Interpret an input command string
virtual Enlist:pCommandArgument ;Handles "list" command
long dwWidth ;<-- ScreenWidth
long dwHeight ;<-- ScreenHeight (from SetConsoleSize)
long pStrings ;ptr to instance of CVector, holding internal StringArray as array of ptrs to strings
long FirstLine ;=First Line to be displayed
long MaxLine ;=#Strings in StringArray

Console_SetConsoleSize proc dwWidth, dwHeight
m2m [ecx].Console.dwWidth, dwWidth
m2m [ecx].Console.dwHeight, dwHeight
Console_SetConsoleSize endp

Console_ScrollDown proc
mov eax,[ecx].Console.FirstLine
inc eax
.if eax<[ecx].Console.MaxLine
inc [ecx].Console.FirstLine
Console_ScrollDown endp

Console_ScrollUp proc
mov eax,[ecx].Console.FirstLine
.if eax>0
dec [ecx].Console.FirstLine
Console_ScrollUp endp

;else eax=ptr to first unprinted character in string (to be printed on a subsequent line?)
Console_Print proc xpixel:GLint, ypixel:GLint, pString:DWORD, Set:UINT
push ecx
invoke glPrint , xpixel, ypixel, pString, Set
invoke lstrlen, pString
pop ecx
shl eax,4 ;multiply by 16 (font width)
.if eax>[ecx].Console.dwWidth
sub eax,[ecx].Console.dwWidth
shr eax,4
add eax,pString
xor eax,eax
Console_Print endp

;Displays up to (Height/16) lines of text from internal stringarray
Console_Display proc yDisplacement
local iMaxLines
local iCurrentLine
local me
local CurrentX
local CurrentY
mov me,ecx
m2m iMaxLines, [ecx].Console.FirstLine
mov eax, [ecx].Console.FirstLine
mov iCurrentLine, eax
xor eax,eax
mov CurrentX,eax
mov eax,[ ecx].Console.dwHeight
sub eax,16
mov CurrentY,eax
shr eax,4 ;divide by 16
add iMaxLines,eax
mov ecx,iCurrentLine
.while ecx<iMaxLines
mov ebx,me
icall [ebx].Console.pStrings, CVector, getbyindex, iCurrentLine
.break .if eax==0
mov ebx,CurrentY
sub ebx,yDisplacement
icall me, Console, Print, CurrentX, ebx, eax, 0
inc iCurrentLine
mov eax,iCurrentLine
sub CurrentY,16
mov ecx,iCurrentLine
Console_Display endp

Console_AddString proc pString
invoke AllocString,pString
icall [ecx].Console.pStrings, CVector, push_back, eax
inc [ecx].Console.MaxLine
mov eax,[ecx].Console.dwHeight
shr eax,4
dec eax ;<== #lines that fit on the screen
.if eax<[ecx].Console.MaxLine
icall ecx, Console, ScrollDown
Console_AddString endp

Console_$Console proc
local count
icall [ecx].Console.pStrings, CVector, getcount
mov count,eax
.while count !=0
icall [ecx].Console.pStrings, CVector, pop_back
free eax
dec count
delete [ecx].Console.pStrings
Console_$Console endp

Console_Console proc
mov [ecx].Console.pStrings, new (CVector)
Console_Console endp

Console_Interpret proc uses ebx edi pCommandString
local me
local pSecondTerm
mov me,ecx
.if pCommandString==0
icall me,Console,AddString, addr ConsoleString
mov esi,pCommandString
.while byte ptr[esi]!=0 && byte ptr[esi]!=32
inc esi
.if byte ptr[esi]==32
mov byte ptr[esi],0
inc esi
mov pSecondTerm,esi
mov pSecondTerm,0

invoke lstrcmpi, pCommandString, CTEXT("list")
.if eax==0
icall me, Console, Enlist, pSecondTerm


Console_Interpret endp

Console_Enlist proc pListArgument
local me
mov me,ecx
.if pListArgument==0
invoke lstrcmpi, pListArgument, CTEXT("glextensions")
.if eax==0
jmp EnlistExtensions
invoke lstrcmpi, pListArgument, CTEXT("glx")
.if eax==0
jmp EnlistExtensions

invoke glGetString,GL_EXTENSIONS ;returns ptr to space-terminated array of strings as one large string
mov esi,eax
.while byte ptr[esi]!=0
push esi
.while byte ptr[esi]!=32 && byte ptr[esi]!=0
inc esi
.if byte ptr[esi]!=0 ;If we haven't found the array terminator
mov byte ptr[esi],0 ;Insert a string terminator
inc esi ;and inc stringpointer (skip stringterminator)
mov edi,esi
inc edi
pop esi ;Retrieve the start of the current string
push edi ;Stow the start of the Next string
.if byte ptr[esi]!=0
icall me, Console, AddString, esi ;Add the String to the Console
pop esi ;Retrieve the start of the Next string
Console_Enlist endp
Posted on 2004-10-19 01:08:33 by Homer
I've improved the Console class, added some very useful commands to it, and also written a "programmable keyboard manager" class which works closely with the Console class.

Here is a list of all the currently supported console commands:

List GLExtensions (or simply "list glx") - enlists all opengl extensions supported by the local hardware.

Quit (or "exit", same thing) posts a Quit message, same as hitting
ESCAPE (or hitting 'close window' , when windowed)

Time messes with the dwGameTime ,fGameTimeMultipler, GameTimePaused variables.

TimeBase sets fGameTimeMultiplier

Execute executes a textfile as a series of scripted commands :) (no good support for nesting yet)

SetKey binds a function to a keycode

And here is a list of all the "named functions" accessible via the SetKey command:

ModeToggle (toggles fullscreen/windowed)
TimeToggle (freezes/unfreezed GameTimer)
ConToggle (opens/closes Console)
Enter (why would you want to reprogram this? I don't know)
Backspace (for that matter, why would you change this one?)
Up (Cursor Up)
Down (Cursor Down)

If anyone is actually interested in this Quake-style Console, I will post the demo source in its current form and you can do what you like with it.
If you DO make extensions/improvements to it, I'd like to see them posted here in kind.

Thanks, have a nice day :)
Posted on 2004-10-29 02:36:31 by Homer
As an example of the SetKey command:

setkey togglecon 32

will reprogram the spacebar to open/close the console :)
Thus it's possible to bind any key to any named function, providing the function has an entry in my "KeyCommands" table:

KeyCommand struct
pCommandName dd ? ;ptr to string = Name of command as displayed on screen
pFunction dd ? ;ptr to handler function
KeyCode db ? ;Default Key
KeyCommand ends

KeyCommands KeyCommand <CTEXT("Quit"),offset DeadApp, VK_ESCAPE>
KeyCommand <CTEXT("ModeToggle"), offset F1, VK_F1>
KeyCommand <CTEXT("TimeToggle"), offset F2, VK_F2>
KeyCommand <CTEXT("ConToggle"), offset OnTilde, VK_TILDE>
KeyCommand <CTEXT("Enter"), offset OnEnter, VK_ENTER>
KeyCommand <CTEXT("BackSpace"), offset OnBackSpace, VK_BACK>
KeyCommand <CTEXT("Up"), offset OnCursorUp, VK_UP>
KeyCommand <CTEXT("Down"), offset OnCursorDown, VK_DOWN>
KeyCommand <0,0,0>
Posted on 2004-10-29 02:40:55 by Homer
I've added internally-managed lists of named Object and Group nodes.
That means you can create Objects using the command "Object " and you can create Groups with the command "Group ".
I also added the following command syntax for adding an existing Object to an existing Group: " Add "

You can create objects, and arrange them in groups, using commands in the console :)
I'll next add support for adding geometry to objects :)

The idea is to construct complex objects using predefined and / or freehand-defined geometry elements, and then have the added ability to keep these objects in named groups, possibly defining even more complex objects...
Posted on 2004-10-30 03:58:35 by Homer
Is anyone interested in helping to expand this "Command Line Interpreter" into a fully-fledged runtime language of some kind?
Posted on 2004-10-31 23:14:49 by Homer
bleargh - I fully endorse and support me.
Posted on 2004-11-02 01:15:37 by Homer
How about a scriptable pluggin interface?

- separate code from UI
- very modular (DLL for each object)
- UI can be generated automagically

I've been thinking about this for a 3D program but it has many uses. Let me give an example of what I mean above. Let us say we have a BOX.DLL:

box ; creates a box at orgin :)
box {height=10,width=30,length=40} ; still centered at orgin

The same DLL works for programmatical control. The shell will see that "box" is a public method that takes no parameters and the user can assign a button to this feature (default is the obvious). Additionally, the "box" has a group of private-UI parameters which could be displayed on an option dialog/tab (up to the program).

Another idea is to auto update global parameters - like ProjectName, FileName, etc -- based on whatever the current shell supports. But the object can't assume anything of the shell.

The key point being the UI is not assumed to be graphical, and graphical shells could be quite customizable based on the exposure of objects. Need to work out some bumps to make it more scalable.

What do you think? Stupid idea, huh :?:

I'm pointed in the DX direction right now, but will attempt to make the interfaces API independent. The front end of my checkers program will be replaced by a 3D version next year. I also want to make a DX version of Abalone -- yeah, kind of lame to convert a board game, but I gave mine away to some kids and am too cheap to buy another. :)
Posted on 2004-11-02 02:09:35 by bitRAKE
That's what I already have in terms of the GUI only receives output from the result of interpreted commands .. although at the moment the code for the interpreter is nested in the console code, it is logically separate, and I have expressed an interest inseparating it further to a 'CInterpreter' class which is fed active lines of script either from the console input or from a script file...

Glad to see some interest in this, it seems crazy to want to write yet another language, but if its a specialized oned and merely triggering our asm code, then afaics we can do no wrong.

I'm currently messing around with some iocp support classes in order to add iocp server support as a class based module...
Posted on 2004-11-02 02:16:40 by Homer
Blah, DX, OGL, I don't care anymore, I just want some action :(

All my support classes are ATC based, most are not DX or OGL specific, and moving from one to the other is not a problem for me.
I have more experience in DX as it stands, butI don't like a whole lot...
Posted on 2004-11-02 02:18:51 by Homer
Blah, DX, OGL, I don't care anymore, I just want some action :(
What, like 3D p0rn? :P
...there is much foreplay involved and still the possiblity of blue balls. :cry:
Posted on 2004-11-02 08:31:09 by bitRAKE
As far as enshrining stuff in DLL form, I certainly have no problem with that, but what is your solution for sharing the dll-owned data with the application? A shared BSS segment (special build DLL)? I mean I assume the DLL is responsible for resource allocation and release, absolving the caller executable from such duties means idiotproof programming..
Posted on 2004-11-03 00:54:27 by Homer
I haven't had a use for DLLs, yet. What I've read of them seem to indicate they run in the same address space. Wouldn't a DLL have access to memory of the parent process? If not, then I'd rather make a simple loader than use a DLL. So, much for enshrine.
Posted on 2004-11-03 11:50:23 by bitRAKE
I was thinking about a DLL shared by several concurrent processes, forming the core module of an engine.. I wrapped my existing ogl stuff in a DLL last night, now I'm unhappy with the flexibility of the initialisation procs eg fixed fov etc.. I'll post soon :)
Posted on 2004-11-03 16:34:09 by Homer