Conio module (WIN32)

BlitzMax Forums/BlitzMax Programming/Conio module (WIN32)

Heres a module wrapper for the Conio library (Console IO) for WIN32.

Functions to print colored text anywhere in a console window.

The library just wraps the relevant Win32API calls but its a much nicer interface ;)

I also added some handy utility functions.

Enjoy!

EDIT: updated, added functions to resize the window & buffer

Download

Heres screenshot for the lazy.. hehe


I think people might show more/any interest if they knew what it was/what its useful for.

hmm.. i suppose your right, although its realy nothing special.

Its just some functions that allows you to print colored text anywhere in a console/terminal.

With a few helper functions for making boxes,lists,etc and convert an attributed string into something that can be printed

example:
' $00-15 = background color
' #00-15 = foreground color
PutString( 1,1, "$09#14Press any key to exit...")

I needed this for a console based vm debugger im working on,
and i thought others might have use for it as well.

Thanks! I don't know if I will do something with it but anyhow it's cool ;)

I have a bug. Running Windows Vista Home Basic, fully updated.

hmm.. thats wierd, seems like vista is using a font that doesnt handle extended characters properly.
It could also be your language set (if any) that has rearranged the table (unlikely).

Open the console properties and check the font tab, and post what font its using.

And could you post a screen of the chartab.exe example also?
It should be similar to the screenshot i posted above.

Also test the included example exe's to see if they do this too.

Sorry i dont have vista to test myself :/

Yeah, I'll try to work out a fix for you. It doesn't seem to be a big issue.
EDIT: Ran chartab.exe and there does seem to be missing characters. I changed the font and same result. I'll see what I can do to patch this.

Thanks, much appreciated =)

I added 2 new functions to resize the console window and set its buffer (removes the ugly scrollbars ;)

Its done automatically by InitConio() & FreeConio() (they just handle common start/end stuff you can do manually if needed)

Hmm..useless except for a ZZT clone or a BBS. LOL

Hmm..useless except for a ZZT clone or a BBS. LOL

Heh, most of the things i code are in console mode. So i wouldn't call it useless.

I'm sorry, it is probably very useful for other things too. I remember once I made a complete GUI system with ASCII characters.

This is very cool :-)

A lot of people/companies still use console mode for their UIs (generally it's much faster to navigate a text-only UI than it is to move the mouse and click stuff)

Reminds me of curses and stuff on Unix... (now.. there's an idea.....)

remember me on a old powerbasic gui
cool

I suppose it would be handy for some stuff... When I did a fruit machine simulator it all started out on a console, mostly running millions of spins and seeing if the odds were running correctly when lines would drop in.

Using this would of tarted it up nicely! :D

Is there anyway to get this working when run from the IDE?

I guess not. The IDE is not a console terminal.

Looks great. Who's going to write the first BlitzMax Dwarf Fortress clone with it then? :)

I'm doing a small roguelike.
The best choice for the interface would be this C library

But sadly, my C skills are not enough to create the interface.
Without a reliable curses lib for Bmax, i'm writing my own.

Anyone know how to clear the keyboard buffer in grb.conio.mod?

Anyone know how to clear the keyboard buffer in grb.conio.mod?

I dont know if blitz uses the right security bits, but this should work:
Extern "Win32"
	Const STD_INPUT_HANDLE:Int = -10
	Const STD_OUTPUT_HANDLE:Int = -11
	Const STD_ERROR_HANDLE:Int = -12
	Function GetStdHandle:Int( stdh:Int)
	Function FlushConsoleInputBuffer:Int( console:Int)
EndExtern

Function FlushInput()
	FlushConsoleInputBuffer( GetStdHandle( STD_INPUT_HANDLE))
EndFunction


Cheers, I'll give that a go.

EDIT: Looks good! I had a little Millisecs() based hack in place that has been duly relegated to a fallback.
Const FLUSHKEYS_WITH_GRABLE_CODE:Int = True
:D

Windows changes so much that I finally decided to make my roguelikes cross compatible by making all my characters and extended characters tiled images that look like text :)

Sorry, resurrecting an old topic, and posting a slightly OT response...

For those with MaxGui, you could probably create a decent cross-platform technique based on the HTML gadget, for use in Roguelike games. Eg:

SuperStrict

Framework MaxGUI.Drivers
Import BRL.Timer
Import BRL.Retro

SeedRnd MilliSecs()

Global Terminal:THTMLTerm = THTMLTerm.Create("Roguelike Experiment", -1, -1, 800, 600, 60, 20)

AddHook EmitEventHook, ProcessEvent

Repeat

	WaitSystem

Forever


End


Function ProcessEvent:Object(id:Int, data:Object, context:Object)

	Local ev:TEvent = TEvent(data)

	Return Terminal.CheckEvent(ev)

EndFunction


Type THTMLTerm


	Function Create:THTMLTerm(title:String = Null, x:Int = -1, y:Int = -1, ..
		w:Int = 640, h:Int = 400, ccols:Int = 70, crows:Int = 25)
	
		Local term:THTMLTerm = New THTMLTerm

		If Not title Then title = AppArgs[0]

		Local flags:Int = WINDOW_TITLEBAR | WINDOW_RESIZABLE
		If x < 0 And y < 0 Then flags = WINDOW_TITLEBAR | WINDOW_CENTER | WINDOW_RESIZABLE

		term.Window = CreateWindow(title, x, y, w, h, Null, flags)
		term.HTMLView = CreateHTMLView(0, 0, ClientWidth(term.Window), ClientHeight(term.Window), ..
			term.Window, HTMLVIEW_NOCONTEXTMENU | HTMLVIEW_NONAVIGATE)
		term.Panel = CreatePanel(0, 0, ClientWidth(term.Window), ClientHeight(term.Window), ..
			term.Window, PANEL_ACTIVE)
		term.Timer = CreateTimer(60)

		HideGadget term.panel
		
		term.URL = AppDir + "/temp.html"
		
		term.CharTable = TCharTable.Create(ccols, crows)
				
		term.CharTable.exportHTML term.URL

		HtmlViewGo term.HTMLView, term.URL
		
		Return term
	
	EndFunction


	Field URL:String

	Field Window:TGadget
	Field HTMLView:TGadget
	Field Panel:TGadget
	Field Timer:TTimer
	
	Field CharTable:TCharTable
	
	
	Method CheckEvent:TEvent(ev:TEvent)
	
		Select ev.id
	
			Case EVENT_TIMERTICK
				If ev.Source = Timer Then ActivateGadget Panel
	
			Case EVENT_KEYDOWN
				If ev.Source = Panel
				
					Select ev.data
					
						Case KEY_ESCAPE 
							EmitEvent CreateEvent(EVENT_APPTERMINATE)
							
						Case KEY_SPACE
							CharTable.test URL
							HtmlViewRun HTMLView, "window.location.reload();"
							
					EndSelect
				EndIf
	
			Case EVENT_WINDOWSIZE
				resize
	
			Case EVENT_WINDOWCLOSE
				If ev.Source = Window Then EmitEvent CreateEvent(EVENT_APPTERMINATE)

			Case EVENT_APPTERMINATE
				End

		EndSelect
		
		Return ev
	
	EndMethod

	
	Method resize()
	
		SetGadgetShape HTMLView, 0, 0, ClientWidth(Window), ClientHeight(Window)
		SetGadgetShape Panel, 0, 0, ClientWidth(Window), ClientHeight(Window)
	
	EndMethod
	

EndType


Const STYLE_NORMAL:Byte = 0
Const STYLE_ITALIC:Byte = 1
Const STYLE_OBLIQUE:Byte = 2
	
Const WEIGHT_NORMAL:Byte = 0
Const WEIGHT_BOLD:Byte = 1

Const DECOR_NONE:Byte = 0
Const DECOR_UNDERLINE:Byte = 1
Const DECOR_OVERLINE:Byte = 2
Const DECOR_LINETHROUGH:Byte = 3


Type TCharTable


	Field FFamily:String			'Any valid CSS text applicable to "font-family"
	Field FSize:String				'Any valid CSS text applicable to "font-size"
	Field BodyBGColor:String			'Any valid CSS text applicable to "background-color"
	
	Field Cells:TCharCell[,]
	Field Cols:Int, Rows:Int
	
	
	Function Create:TCharTable(cs:Int, rs:Int, url:String = "temp.html")
	
		Local tbl:TCharTable = New TCharTable
	
		tbl.Cols = cs
		tbl.Rows = rs
		
		tbl.Cells = New TCharCell[tbl.Cols, tbl.Rows]
		
		For Local r:Int = 0 To tbl.Rows - 1
			For Local c:Int = 0 To tbl.Cols - 1
				tbl.Cells[c, r] = New TCharCell
			Next
		Next
			
		tbl.setCSSFont "courier, monospace", "1.5em"

		tbl.setBodyBGColor $000000, True
		
		'tbl.initAllCells Asc("."), $FFFFFF, $000000, STYLE_NORMAL, WEIGHT_NORMAL, DECOR_NONE

		tbl.test url

		'tbl.exportHTML url

		Return tbl
	
	EndFunction


	Method setCSSFont(family:String = "courier, monospace", size:String = "1em")
	
		FFamily = family
		FSize = size
		
	EndMethod


	Method setBodyBGColor(color:Int, allchars:Int = False)
	
		BodyBGColor = "#" + Right(Hex(color), 6) + ";"
		
		If allchars
			For Local c:Int = 0 To Cols - 1
				For Local r:Int= 0 To Rows - 1
					Cells[c, r].setBGColor color
				Next
			Next
		EndIf
	
	EndMethod


	Method setCellChar(col:Int, row:Int, ch:Int)
	
		Cells[col, row].setChar ch	
	
	EndMethod


	Method setCellFGColor(col:Int, row:Int, fgc:Int)
	
		Cells[col, row].setFGColor fgc	
	
	EndMethod

	
	Method setCellBGColor(col:Int, row:Int, bgc:Int)
	
		Cells[col, row].setBGColor bgc	
	
	EndMethod

	
	Method setCellWeight(col:Int, row:Int, wgt:Int)
	
		Cells[col, row].setWeight wgt	
	
	EndMethod
	
	
	Method setCellStyle(col:Int, row:Int, styl:Int)
	
		Cells[col, row].setStyle styl	
	
	EndMethod

	
	Method setCellDecor(col:Int, row:Int, dec:Int)
	
		Cells[col, row].setDecor dec	
	
	EndMethod
	
	
	Method initAllCells(ch:Byte, bgc:Int= $000000, fgc:Int= $FFFFFF, ..
		styl:Byte = STYLE_NORMAL, wgt:Byte = WEIGHT_NORMAL, dec:Byte = DECOR_NONE)
	
		For Local c:Int = 0 To Cols - 1
			For Local r:Int = 0 To Rows - 1
				Cells[c, r].setBGColor bgc
				Cells[c, r].setFGColor fgc
				Cells[c, r].setChar ch
				Cells[c, r].setStyle styl
				Cells[c, r].setWeight wgt
				Cells[c, r].setDecor dec
			Next
		Next
	
	EndMethod


	Method writeText(txt:String, col:Int, row:Int, bgc:Int = $000000, fgc:Int = $FFFFFF)

		For Local n:Int = 0 To txt.length - 1
			If (col + n) < Cols
				setCellChar col + n, row, txt[n]
				setCellBGColor col + n, row, bgc
				setCellFGColor col + n, row, fgc
			EndIf
		Next
		
	EndMethod
	

	Method exportHTML(url:String)
	
		If Not CreateFile(url) 
			Notify "Could not create HTML file."
			End
		EndIf
		
		Local fh:TStream = OpenFile(url)
		
		WriteLine fh, "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/Strict.dtd'>"
		
		WriteLine fh, "<html><head><style type='text/css'>body{background-color: " + BodyBGColor + ..
			"; font-family: " + FFamily + "; font-size: " + FSize + ";} " + ..
			"}</style><title>Roguelike Experiment</title></head><body>" + .. 
			"<code>"
				
		For Local r:Int = 0 To Rows - 1
			Local row:String = ""
			For Local c:Int = 0 To Cols - 1
				row :+ Cells[c, r].getCSS()
			Next
			WriteLine fh, (row + "<br>")
		Next

		WriteLine fh, "</code></body></html>"

		CloseFile fh
	
	EndMethod


'***************** DEBUG ************************

	Method test(URL:String)
	
		Local ch:Int = Rand(32, 255)
		
		For Local r:Int = 0 To Rows - 1
			For Local c:Int = 0 To Cols - 1
				
				setCellChar c, r, ch
				
				setCellFGColor c, r, Int((Rand(0, 255) Shl 16) | (Rand(0, 255) Shl 8) | Rand(0, 255)) 
				
				If Not Rand(0, 32)
					setCellBGColor c, r, Int((Rand(0, 255) Shl 16) | (Rand(0, 255) Shl 8) | Rand(0, 255)) 
				Else
					setCellBGColor c, r, $000000
				EndIf
					
				If Not Rand(0, 32)	
					setCellWeight c, r, Rand(WEIGHT_NORMAL, WEIGHT_BOLD)
					setCellDecor c, r, Rand(DECOR_NONE, DECOR_LINETHROUGH)
					setCellStyle c, r, Rand(STYLE_NORMAL, STYLE_OBLIQUE)
				EndIf
				
			Next
		Next

		exportHTML URL

	EndMethod


'************************************************


EndType


Type TCharCell


	Function Create:TCharCell()
		
		Local cell:TCharCell = New TCharCell
		
		cell.Char = 32
		cell.FGColor = $FFFFFF
		cell.BGColor = $000000
		cell.Style = STYLE_NORMAL
		cell.Weight = WEIGHT_NORMAL
		cell.Decor = DECOR_NONE
				
		Return cell
		
	EndFunction


	'###### FIELDS ######

	Field Char:Byte
	Field FGColor:Int, BGColor:Int
	Field Style:Byte, Weight:Byte, Decor:Byte


	'###### SETTERS ######

	Method setChar(ch:Byte)
	
		Char = ch
		
	EndMethod
	
	Method setFGColor(clr:Int)
	
		FGColor = clr
		
	EndMethod

	Method setFGColorRGB(r:Byte, g:Byte, b:Byte)
	
		FGColor = Int((r Shl 16) | (g Shl 8) | b)
		
	EndMethod

	Method setBGColor(clr:Int)
	
		BGColor = clr
		
	EndMethod

	Method setBGColorRGB(r:Byte, g:Byte, b:Byte)
	
		BGColor = Int((r Shl 16) | (g Shl 8) | b)
		
	EndMethod

	Method setStyle(styl:Byte)
	
		Style = styl	
	
	EndMethod
	
	Method setWeight(wgt:Byte)
	
		Weight = wgt	
	
	EndMethod
	
	Method setDecor(dec:Byte)
	
		Decor = dec	
	
	EndMethod


	'###### GETTERS ######

	Method getCSS:String()

		Local str:String

		str :+ "<span style='background-color:#" + Right(Hex(BGColor), 6) + ..
		"; color:#" + Right(Hex(FGColor), 6) + "; "
				
		Select Style
									
			Case STYLE_NORMAL
				str :+ "font-style: normal; "
					
			Case STYLE_ITALIC
				str :+ "font-style: italic; "
					
			Case STYLE_OBLIQUE
				str :+ "font-style: oblique; "

		EndSelect
				
		If Weight = WEIGHT_NORMAL Then str :+ "font-weight: normal;" Else ..
			str :+ "font-weight: bold;"

		Select Decor
				
			Case DECOR_NONE
				str :+ "text-decoration: none; "	
					
			Case DECOR_UNDERLINE
				str:+ "text-decoration: underline; "	

			Case DECOR_OVERLINE
				str:+ "text-decoration: overline; "	

			Case DECOR_LINETHROUGH
				str:+ "text-decoration: line-through; "
						
		EndSelect

		str :+ "'>" 
		
		If Char = 32 Then str :+ "&ensp;" Else str :+ Chr(Char)
		
		str :+ "</span>"

		Return str
		
	EndMethod

	
EndType



Seems to work okay on WindowsXP and Mac OS10.5.4..