Page 1 of 2
Fast Console Rendering
Posted: Fri Feb 23, 2007 2:09 pm
by quickie
Hello, this is my first post.
I have a question:
Is there any faster way to render the Console window compared to Printing each character by to Fors and ConsoleLocations.
This is how it is done now.
Code: Select all
Protected X.c, Y.c
For Y.c = 0 To #Console_Height
For X.c = 0 To #Console_Width
ConsoleLocate(X.c, Y.c)
ConsoleColor(Console(X.c, Y.c)\Color.c, 0)
Print(Chr(Console(X.c, Y.c)\Char.c))
Next
Next
It works fine but is very slow.
Any ideas?
Thanks!
Posted: Tue Feb 27, 2007 2:23 pm
by quickie
Hi,
please let me bump up this post.
I found out that I can use WriteConsoleData() like the code below to achive the effect I want, but only in "Non-graphical" mode.
Would there be a similar way to do this? Because the current method above(First post) is way too slow for a Roguelike.
Thanks.
Code: Select all
OpenConsole()
#Console_Size = 2000
Global *Buffer = AllocateMemory(#Console_Size)
Repeat
For i = 0 To #Console_Size
PokeB(*Buffer + i, Random(93) + 33)
Next
ClearConsole()
WriteConsoleData(*Buffer, #Console_Size)
Until Input() <>""
CloseConsole()
Posted: Tue Feb 27, 2007 2:41 pm
by Derek
Have you considered using a graphics screen and printing to that instead of using a console window?
Posted: Tue Feb 27, 2007 2:49 pm
by Kaeru Gaman
- afaik the "non-graphical" mode of the console has only additional shell-functions,
there is no difference in the display.
I wonder, why the buffer-access shouldn't work in graphical mode.
- your first code could be speeded up by two changes:
- - locate only in the outer loop, also concides not to locate but to print a newline at the end of the inner loop.
- - only call ConsoleColor, if the color really changed.
- think about Derek's suggestion.
with only a little effort you can develop a similar look of the surface,
with every conveniences of a 2D-Grafix-surface.
Posted: Tue Feb 27, 2007 3:46 pm
by dracflamloc
You're approaching this from the wrong angle anyway.
What you need to do with a console and plotting characters is different than the way you're used to with graphical screens.
For instance your 2d-gfx rendering loop would be like so:
Code: Select all
Repeat
flipbuffers()
clearscreen()
;loop through and draw everything
drawtext(....
drawsprite(...
delay(5)
Forever
But with a console thats very inefficient and pointless. What you do is if you need a change, track those changes and immediately draw that change. You have no 'rendering loop' persay.
You just clear the character you need to update by locating, then printing a space. Or you just print the character that it needs to be changed to if its not being cleared.
Example:
Code: Select all
Repeat
if inkey()="J" ;move left
consolelocate(playerx,playery)
print(" ") ;clear old position
playerx - 1
consolelocate(playerx,playery)
print("P") ;draw new pos
elseif inkey()="L" ;move right
consolelocate(playerx,playery)
print(" ") ;clear old position
playerx + 1
consolelocate(playerx,playery)
print("P") ;draw new pos
endif
delay(5)
Forever
[edit]
Also, if you really need to draw the way you are thinking then you should buffer the drawing. For example:
Code: Select all
Protected X.c, Y.c
For Y.c = 0 To #Console_Height
buf.s=""
For X.c = 0 To #Console_Width
if X = #Console_Width
buf + Console(X.c, Y.c)\Char
ConsoleLocate(0, Y.c)
Print(Chr(Console(X.c, Y.c)\Char.c))
else
buf + Console(X.c, Y.c)\Char
endif
Next
Next
This would need more consideration to handle colors but should be a similar piece of code. You should not run this code in a 'rendering loop' either. You still will want to track changes.
Also consider making a macro to handle color changes and location and printing all in one step. You may want to add code to see if the color needs changing and only call ConsoleColor if the color is different:
Code: Select all
Macro PrintChar(string,x,y,color)
ConsoleColor(color)
ConsoleLocate(x,y)
Print(string)
EndMacro
Macro PrintCharAndClear(string,x,y,color,oldx,oldy)
ConsoleColor(color)
Consolelocate(oldx,oldy)
print(" ")
ConsoleLocate(x,y)
Print(string)
EndMacro
Posted: Tue Feb 27, 2007 5:51 pm
by quickie
Thanks everybody for all the advice!
Derek:
I was thinking of that as a last resort, since I wanted the atmosphere of an "authentic" console

!
Kaeru Gaman:
I don't know why either but the manual says it can't, and so does the compiler
Thanks, I'll try a bit more before considering a 2D solution.
dracflamloc:
Thanks for the examples!
About the approach thing, I was thinking of having the whole map scroll if needed, which is why I wanted to redraw the whole console screen. I've seen some games that do this, so figured that it should be possible.
Oh and about the buffer idea, I thought of that as well but wouldn't that be a problem with color? The reason I think so is because each "print" prints out a whole string of letters, there isn't any way to specify the color of each character.
Ohhh, the irony of having to speed up text mode drawing to get decent game play! heheh
Posted: Tue Feb 27, 2007 6:43 pm
by dracflamloc
You probably can use the buffering thing with colors, the loop will just be a bit more complex and will have to compare the previous character's color with the current one. If they aren't the same, print the buffer,clear it and set the new color, and continue with the loop.
Even with a scrolling map you won't need to reprint everything. I'd have a 'current' and 'changed' array. Loop through the changed array when you print everything to screen, but only actually call print if current(x,y)\char is not equal to changed(x,y)\char
Posted: Tue Feb 27, 2007 7:47 pm
by Kaeru Gaman
fine so far.
just one more remark:
quickie wrote:I wanted the atmosphere of an "authentic" console

!
it is absolutely possible with a 2D screen, pixel by pixel identically,
and it is not that much work as it sounds,
but you have really more convenience in displaying and calculating.
it will no longer be the output, that slows your program down.
Posted: Tue Feb 27, 2007 8:57 pm
by dracflamloc
Well if hes in graphical mode coloring the reasons for using the traditional console window kind of go out the window anyway.
The benefits of using a normal console window are basically limited to its simplicity and piping output through other programs and interfaces.
Posted: Wed Feb 28, 2007 6:15 am
by quickie
Thanks again for all the advice.
When I was coding in QBasic, I *think* I was able to POKE in the characters as well as the colors.
For example:
Code: Select all
DEF SEG where ever the console vram is
POKE 0, 14
POKE 1, 65
something like the above displaying a bright yellow A on the left top corner of the screen.
Fiddling around with ConsoleWriteMem, it seems as if the console video memory isn't constructed in that way(Color, Char, Color, Char and so on)...
dracflamloc:
Ah, I see, yeah that could speed it up alot, especially with Roguelikes

Thanks!
Kaeru Gaman:
Yeah, I know it's possible to make it pixel perfectly the same, but I want to start off with a completely console mode, and then work up to graphics if the project goes well, and be able to switch between the 2, or have 2 separate versions.
For example:
http://www.santiagoz.com/web/news.php
this Roguelike has 2 modes, console mode and graphical mode, which works surprisingly well(I think it uses a generic RL engine though).
I've uploaded what I've done so far, in case anyone is interested
http://wing2.jp/~upploader/cgi-bin/up/src/up3670.zip
Thanks again.
Posted: Wed Feb 28, 2007 10:59 am
by Derek
Looks quite good, keep us posted.

Posted: Wed Feb 28, 2007 1:39 pm
by Kaeru Gaman
> When I was coding in QBasic, I *think* I was able to POKE in the characters as well as the colors.
in those times the "console" was a real video ram in the graphics card that ran in textmode.
means, you wrote chars and colors into the mem on the GraCa,
like you write color-values into one of the two buffers today.
today a console is some allocated mem of an application that is translated
into bitmap information wich is passed to the GraCa to display.
It's a totally different hardware-approach.
Posted: Wed Feb 28, 2007 2:46 pm
by dracflamloc
Quickie, looks cool. I can't wait to try it when its done =)
I love console games
Posted: Wed Feb 28, 2007 5:17 pm
by quickie
Derek:
Thanks
Kaeru Gaman:
Hmm, I see, yeah I understand that but if I ran the QB program on modern hardware, it'd probably work. I still think that copying a whole gob of info into the console is possible given the right knowledge.
Just tried, and the following QB code works in WinXP:
Code: Select all
DEF SEG = &HA000
POKE 0, 1
POKE 0, 14
So yeah, I think with the console "screen mode", it's still possible to fast update it.
dracflamloc:
Thanks

Can't wait to work on the map generator.
Posted: Wed Feb 28, 2007 6:30 pm
by JCV
phew I remember the game I played when I was in highschool. Its really a good game.
Adom - Ancient Domains of Mystery
http://www.adom.de/