2

I'm writing a game using MASM,

I use ClrScr which is a procedure in Irvine32.inc

but it can't clean the whole console window

some char still remain.

My code is run under 32-bits system, so I can't use "int" instruction

I am trying to write a procedure to output black-color-space to the entire console

but it will flicker when I call that proc. and it's hard to stare at screen ..

Is there a solutions?


UPDATE

Here is my code to clear the screen

ForceCLS  PROC
    PUSH ECX
        Translate 0,0   ;Gotoxy 0, 0
        LoopTimes 50    ;Same AS MOV ECX, 50
        SettingColor Black ;Set Font Color to Black
        NewLine:
            PUSH ECX
                LoopTimes 115
                BLANKS:
                    Write 020H
                        ; Same As MOV EAX, 020H ; CALL  WriteChar
                    Loop BLANKS
            POP  ECX
            NL ;New Line
            Loop NewLine
    POP  ECX

    Translate 0,0   ;Same As Gotoxy 0, 0
    DefaultColor    ;Set Font Color to Default
    RET
ForceCLS ENDP

And here are examples of the output:

enter image description here

rkhb
  • 14,159
  • 7
  • 32
  • 60
CasparChou
  • 23
  • 5

1 Answers1

2

The flickering happens because when you clear the console it becomes blank for a moment.

To prevent this flickering you need to render a scene in a buffer in memory and after that output the buffer to console. You can use WriteConsoleOutput function for this.

Here is a simple example of the animation in Windows console. The most interesting part happens in the ANIMATION loop. RenderScene procedure renders the scene to the buffer, and WriteConsoleOutput function sends the content of this buffer to the console.

TITLE Animation example


INCLUDE Irvine32.inc
INCLUDE win32.inc


COLS = 80               ; number of columns
ROWS = 25               ; number of rows
CHAR_ATTRIBUTE = 0Fh    ; bright white foreground


.data
console HANDLE 0
buffer CHAR_INFO ROWS * COLS DUP(<<'-'>, CHAR_ATTRIBUTE>)
bufferSize COORD <COLS, ROWS>
bufferCoord COORD <0, 0>
region SMALL_RECT <0, 0, COLS-1, ROWS-1>

x DWORD 0               ; current position
y DWORD 2               ; of the figure
character WORD '0'      ; filled with this symbol


.code
main PROC
    INVOKE GetStdHandle, STD_OUTPUT_HANDLE
    mov console, eax    ; save console handle

    mov ecx, 70         ; draw 70 frames
ANIMATION:
    push ecx
    call RenderScene
    invoke WriteConsoleOutput, console, 
           ADDR buffer, bufferSize, bufferCoord, ADDR region
    INVOKE Sleep,250    ; delay between frames
    pop ecx
    loop ANIMATION

    exit
main ENDP


ClearBuffer PROC USES eax 
    xor eax, eax

BLANKS:  
    mov buffer[eax * CHAR_INFO].Char, ' '
    inc eax
    cmp eax, ROWS * COLS
    jl BLANKS

    ret       
ClearBuffer ENDP


CharToBuffer PROC USES eax edx bufx:DWORD, bufy:DWORD, char:WORD 
    mov eax, bufy
    mov edx, COLS
    mul edx
    add eax, bufx
    mov dx, char
    mov buffer[eax * CHAR_INFO].Char, dx
    ret
CharToBuffer ENDP


RenderScene PROC USES eax edx ecx
    CALL ClearBuffer

    ; render 10 by 7 rectangle
    mov edx, y
    mov ecx, 7
ONELINE:
    mov eax, x

    push ecx
    mov ecx, 10

ONECHAR:
    INVOKE CharToBuffer, eax, edx, character
    inc eax
    loop ONECHAR    ; inner loop prints characters

    inc edx
    pop ecx
    loop ONELINE    ; outer loop prints lines

    inc x           ; increment x for the next frame
    inc character   ; change fill character for the next frame

    ret
RenderScene ENDP


END main

This example uses some function and structures that are not included into Irvine32.inc so I added some declarations in win32.inc file:

CHARTYPE UNION
    UnicodeChar    WORD ?
    AsciiChar      DB ?
CHARTYPE ENDS

CHAR_INFO STRUCT
    Char          CHARTYPE <>
    Attributes    WORD ?
CHAR_INFO ENDS

WriteConsoleOutput EQU <WriteConsoleOutputA>

WriteConsoleOutput PROTO,
    hConsoleOutput:HANDLE,
    lpBuffer:PTR CHAR_INFO,
    dwBufferSize:COORD,
    dwBufferCoord:COORD,
    lpWriteRegion:PTR SMALL_RECT
alxersov
  • 137
  • 1
  • 2
  • 8