Search code examples
assemblyx86masm32-bitirvine32

Clear Screen Without Interrupt


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


Solution

  • 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