News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Calling API WriteConsoleOutput

Started by frktons, August 02, 2010, 10:31:27 PM

Previous topic - Next topic

sinsi

Why?

;set structure values

        mov word ptr SizCord.x,BufWdth
        mov word ptr SizCord.y,BufHght

        mov word ptr LocCord.x,0
        mov word ptr LocCord.y,0

        mov word ptr WrRgn.Left,0
        mov word ptr WrRgn.Top,0
        mov word ptr WrRgn.Right,BufWdth-1
        mov word ptr WrRgn.Bottom,BufHght-1

Every word override adds a byte, so you have at least a qword of wasted bytes (66h), naughty.

Just define the structures already initialised...

SizCord COORD <80,25>
LocCord COORD <0,0>
WrRgn  SMALL_RECT <0,0,79,24>

Light travels faster than sound, that's why some people seem bright until you hear them.

frktons

Quote from: sinsi on August 17, 2010, 07:45:23 AM
Why?

;set structure values

        mov word ptr SizCord.x,BufWdth
        mov word ptr SizCord.y,BufHght

        mov word ptr LocCord.x,0
        mov word ptr LocCord.y,0

        mov word ptr WrRgn.Left,0
        mov word ptr WrRgn.Top,0
        mov word ptr WrRgn.Right,BufWdth-1
        mov word ptr WrRgn.Bottom,BufHght-1

Every word override adds a byte, so you have at least a qword of wasted bytes (66h), naughty.

Just define the structures already initialised...

SizCord COORD <80,25>
LocCord COORD <0,0>
WrRgn  SMALL_RECT <0,0,79,24>



Reducing the size of the overall process, and getting it a bit faster will be
the next step in the project, in my planning at least. So any comment on
how to reduce the size and optimize the speed is welcome.  :U

Your comment is about reducing the size of the program, if I got it right,
I'll try ASAP and let you know.  :bg

Edit: the size of the exe doesn't change a byte [2.560 bytes]. I'm going to try Polink to see what happens.

Edit2: with the good old polink I got an exe file of 1.536 bytes:

\masm32\polink /SUBSYSTEM:console /ALIGN:4096 WrCon2.obj

:P

Quote from: dedndave on August 17, 2010, 02:21:52 AM
it's all good, Frank   :bg
....
interesting to note that it works with either data file


Good to know that the WriteConsoleOutput() API just ignores the second byte
passed [zero or space].
Mind is like a parachute. You know what to do in order to use it :-)

sinsi

Not so much reducing the exe size, more like since they are constants you can define them initialised in the data section.
This saves the code to initialise them but unless your codesize is large (around the size of the file section alignment) there is no real benefit.
Mind you, if you do it for a lot of structures then it makes a difference - 4 bytes in .data versus ~12 in .code.

We are, after all, asm programmers who boast about small code sizes... :bdg
Light travels faster than sound, that's why some people seem bright until you hear them.

frktons

Quote from: sinsi on August 17, 2010, 11:17:07 AM
Not so much reducing the exe size, more like since they are constants you can define them initialised in the data section.
This saves the code to initialise them but unless your codesize is large (around the size of the file section alignment) there is no real benefit.
Mind you, if you do it for a lot of structures then it makes a difference - 4 bytes in .data versus ~12 in .code.

We are, after all, asm programmers who boast about small code sizes... :bdg

You mean that if I had 200-300 data structure in the program, initializing them
in .data section will get 1 kb more or less of gain vs .code section? And the overall speed of the
program will be affected as well? 
I ask because the far away plan is to have this amount of data in the final project, I
mean 200-300 console screen defined and initialized inside the program without
external data files. All the data and code will be inside the program/libraries. Nothing
to read for displaying console screens, only proc calling that will design them
on the fly.

Mind is like a parachute. You know what to do in order to use it :-)

sinsi

The idea is to try and use one structure already defined, then only change the members that need it (if any).
If you are going to be showing different screens, but they are all the same size, the only thing that changes is the address of the data - 0,0-79,24 don't.

Light travels faster than sound, that's why some people seem bright until you hear them.

frktons

Quote from: sinsi on August 17, 2010, 12:32:27 PM
The idea is to try and use one structure already defined, then only change the members that need it (if any).
If you are going to be showing different screens, but they are all the same size, the only thing that changes is the address of the data - 0,0-79,24 don't.

Yes sinsi, the idea is that all the console screens will have the same aspect [25 rows * 80 cols]
and a group of proc and data will create them as needed, using the same screen buffer, or more
than one probably, because I'll need save_screen / restore_screen functions to swap
among the most used ones. I am in the design fase of the project, and from what I can imagine
for the time being, many repetitive data patterns can be replaced by code in order to have a more
compact program. [you are Assembly programmers, after all, and the size and speed count]  :P

If I had, for example 10 console screens of 8000 bytes each and 5000 bytes of code, my hope
is to reduce the overall dimesions from 85000 bytes to 9000-10000 with a gain of 80-90%
in the size, without any performace loss. Not having to read from external files the data to be
displayed, the performance will probably be better than otherwise.  ::)

By the way, the next thread I'll start on september will be about this task: from xx kb to x kb
transforming data into code.
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

#36
well - not knowing how it might be used, i wrote it that way
i am aware of override bytes and speed penalties
i wanted something that was simple and easy to understand - just to get it working

as for setting the console cursor to off, that doesn't always seem to work
but, if you want to use SetConsoleCursorInfo, it may be best to fill the structure with GetConsoleCursorInfo, first
then modify the values as desired prior to the SetConsoleCursorInfo call

you don't need "save screen" and "restore screen"
you can use the screen buffer pages (4 pages i think, in this mode - maybe 8 - i forget)
you can read/write one page while viewing another
then, just switch pages
it is very fast, and makes the program appear to be even faster - lol
you can usually do a pretty good job on a single-screen display using only 2 pages
if they flip to a menu or something, additional pages

Neil

Dave you are right in saying that the cci needs to be be filled before trying to turn the console cursor on or off. Here is the method I use to turn the cursor on or off & it works every time.

.data?
cci             CONSOLE_CURSOR_INFO <>

.code
; -------------------------------------------------------------------------

hidecursor:
    invoke GetConsoleCursorInfo,hConsoleOutput,addr cci
    mov cci.bVisible,FALSE
    invoke SetConsoleCursorInfo,hConsoleOutput,addr cci
    ret

; -------------------------------------------------------------------------

showcursor:
    invoke GetConsoleCursorInfo,hConsoleOutput,addr cci
    mov cci.bVisible,TRUE
    invoke SetConsoleCursorInfo,hConsoleOutput,addr cci
    ret

; -------------------------------------------------------------------------

Call these procs from inside your prog & you have complete control.

dedndave

well - it doesn't always work for all adapters - i am guessing, here   :P
let me put it this way - i have seen it not work - lol

frktons

Quote from: dedndave on August 17, 2010, 02:58:40 PM
you don't need "save screen" and "restore screen"
you can use the screen buffer pages (4 pages i think, in this mode - maybe 8 - i forget)
you can read/write one page while viewing another
then, just switch pages
it is very fast, and makes the program appear to be even faster - lol
you can usually do a pretty good job on a single-screen display using only 2 pages
if they flip to a menu or something, additional pages

Well, this is one of the ways I think I'm going to do it. The save_screen / restore screen
could use this method or any suitable one, and I'll need a save_area / restore_area functions
as well for displaying boxes on actual screen and restoring back the area of the screen buffer
that is temporarily swapped out with save_area  using the appropriate APIs.

Regarding the cursor on/off :
Quote from: Neil on August 17, 2010, 04:00:29 PM
Dave you are right in saying that the cci needs to be be filled before trying to turn the console cursor on or off. Here is the method I use to turn the cursor on or off & it works every time.

.data?
cci             CONSOLE_CURSOR_INFO <>

.code
; -------------------------------------------------------------------------

hidecursor:
    invoke GetConsoleCursorInfo,hConsoleOutput,addr cci
    mov cci.bVisible,FALSE
    invoke SetConsoleCursorInfo,hConsoleOutput,addr cci
    ret

; -------------------------------------------------------------------------

showcursor:
    invoke GetConsoleCursorInfo,hConsoleOutput,addr cci
    mov cci.bVisible,TRUE
    invoke SetConsoleCursorInfo,hConsoleOutput,addr cci
    ret

; -------------------------------------------------------------------------

Call these procs from inside your prog & you have complete control.


I've used these APIs in PBCC and C programs and they work just fine.  :U
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

yes - Neil's cursor procs are just what you need
notice that the structure is updated with current values each time
if you make changes in these values elsewhere in the program, the procs will still work with no surprises (i.e. bugs)

what you are talking about is the text-mode equivalent of a "Z-buffer"
and, the alternate pages may be used that way
it seemed a little simpler in the old DOS days, though   :P

frktons

Quote from: dedndave on August 17, 2010, 10:59:08 PM
yes - Neil's cursor procs are just what you need
notice that the structure is updated with current values each time
if you make changes in these values elsewhere in the program, the procs will still work with no surprises (i.e. bugs)

what you are talking about is the text-mode equivalent of a "Z-buffer"
and, the alternate pages may be used that way
it seemed a little simpler in the old DOS days, though   :P

Yes Dave, you are right. I'm trying to recreate the old DOS Menu/Screen/Boxes
and so on of my youth  :P and it was easier in those times. But now we can
take advantage of Gbs of RAM and Tbs of Hard disk space, with processors that
are nearly 500/1000 times more powerful. So we loose something and we gain
something else.  :lol
That's life anyway  :bg
Mind is like a parachute. You know what to do in order to use it :-)