Графика в TASM: текстовая строка, которая двигается стрелками клавиатуры, и меняет цвет при каждом нажатии клавиши - Assembler

Узнай цену своей работы

Формулировка задачи:

Нужно реализовать текстовую строку которая двигается стрелками клавиатуры, и меняет цвет при каждом нажатии клавиши, совсем не понимаю как можно реализовать, подскажите

Решение задачи: «Графика в TASM: текстовая строка, которая двигается стрелками клавиатуры, и меняет цвет при каждом нажатии клавиши»

textual
Листинг программы
.model small
 
.stack 100h
 
.data
        ;коды, возвращаемые int 16h ah=00h
        kbArrowUp       equ     4800h
        kbArrowDown     equ     5000h
        kbArrowLeft     equ     4B00h
        kbArrowRight    equ     4D00h
        kbEsc           equ     011Bh
 
        CrLf            db      0Dh, 0Ah, '$'
        azMsg           db      'My Little String!', 0
        MsgLen          equ     $-azMsg-1
 
        Mode0D_W        equ     320     ;ширина экрана в пикселях для видеорежима 0Dh
        Mode0D_H        equ     200     ;высота экрана в пикселях для видеорежима 0Dh
        Mode0D_C        equ     16      ;количество цветов для видеорежима 0Dh
        Mode0D_A        equ     0A000h  ;начальный адрес видеопамяти для видеорежима 0Dh
 
        VideoPage       db      ?       ;номер видеостраницы
 
        lpFontTable8x14 dw      2 dup(?);указатель на таблицу символов 8x14
        FontH           equ     14      ;количество строк в описании глифа
        FontW           equ     8       ;количество столбцов в описании глифа
 
        Xstart          dw      100     ;координаты начала надписи
        Ystart          dw      70
 
        Xcurr           dw      ?       ;текущие координаты левого верхнего угла строки
        Ycurr           dw      ?
 
        Color           db      1       ;цвет выводимого текста
 
        PointsPerMsg    equ     MsgLen*FontW    ;длина изображения строки в точках
 
.code
 
main    proc
        mov     ax,     @data
        mov     ds,     ax
 
        ; установка графического видео режима
        mov     ax,     000Dh
        int     10h
 
        ;возьмём какую-нибудь таблицу знакогенератора
        ;например, 8x14
        mov     ax,     1130h   ;Get EGA information
        mov     bh,     2       ;2 = return ES:BP => ROM 8x14 font table addr
        int     10h
        mov     [lpFontTable8x14  ],    bp
        mov     [lpFontTable8x14+2],    es
 
        mov     ah,     0Fh     ;уточнение параметров видеорежима
        int     10h
        mov     [VideoPage],    bh
 
        call    ShowString
 
        mov     ah,     00h
        int     16h
        inc     [Color]
        call    ShowString
 
        @@GetCmd:
                ;ожидание нажатия любой клавиши
                mov     ah,     00h
                int     16h
                ;обработка команды
        @@TestCmd1:
                cmp     ax,     kbArrowUp
                jne     @@TestCmd2
                mov     dx,     [Ystart]
                cmp     dx,     0
                je      @@GetCmd
                dec     dx
                mov     cx,     [Xstart]
                jmp     @@Redraw
        @@TestCmd2:
                cmp     ax,     kbArrowDown
                jne     @@TestCmd3
                mov     dx,     [Ystart]
                add     dx,     FontH
                cmp     dx,     Mode0D_H
                jae     @@GetCmd
                sub     dx,     FontH
                inc     dx
                mov     cx,     [Xstart]
                jmp     @@Redraw
        @@TestCmd3:
                cmp     ax,     kbArrowLeft
                jne     @@TestCmd4
                mov     cx,     [Xstart]
                cmp     cx,     0
                je      @@GetCmd
                dec     cx
                mov     dx,     [Ystart]
                jmp     @@Redraw
        @@TestCmd4:
                cmp     ax,     kbArrowRight
                jne     @@TestCmd5
                mov     cx,     [Xstart]
                add     cx,     PointsPerMsg
                cmp     cx,     Mode0D_W
                jae     @@GetCmd
                sub     cx,     PointsPerMsg
                inc     cx
                mov     dx,     [Ystart]
                jmp     @@Redraw
        @@TestCmd5:
                cmp     ax,     kbEsc
                jne     @@GetCmd
                jmp     @@StopCmdLoop
        @@Redraw:
                mov     al,     [Color]
                mov     [Color],        0
                call    ShowString
                inc     al                      ;Color++
                cmp     al,     Mode0D_C        ;if (Color>MaxColor)
                sbb     ah,     ah              ;  Color=1
                and     al,     ah
                cmp     al,     1
                adc     al,     0
                mov     [Color],        al
                mov     [Xstart],       cx
                mov     [Ystart],       dx
                call    ShowString
        jmp     @@GetCmd
@@StopCmdLoop:
        ;переключение в текстовый режим
        mov     ax,     0003h
        int     10h
        ;завершение программы
        mov     ax,     4C00h
        int     21h
main    endp
 
ShowString      proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
 
        mov     ax,     [Xstart]
        mov     [Xcurr],        ax
        mov     ax,     [Ystart]
        mov     [Ycurr],        ax
        lea     si,     [azMsg]
        cld
ForByChar:
        lodsb                   ;al - очередной символ строки
        or      al,     al      ;конец строки? - прервать цикл
        jz      Break
 
        mov     cx,     FontH   ;цикл по строкам глифа
        mul     cl              ;di=(код символа)*(размер глифа) - смещение строки текущего глифа
        mov     di,     ax
ForByLines:
        push    ax
        push    cx
 
        mov     ah,     es:[bp+di]      ;считываем очередную строку глифа
        mov     cx,     8
ForByBits:
        mov     al,     0       ;сдвигаем биты влево, и выбираем цвет точки
        shl     ah,     1
        sbb     al,     0       ;если бит был равен 0 - то al:=0
        and     al,     [Color] ;если бит был равен 1 - то al:=Color
 
        push    ax
        push    bx
        push    cx
        push    dx
        ;установка графической точки
        mov     ah,     0Ch
        mov     bh,     [VideoPage]     ;номер видеостраницы
        mov     dx,     [Ycurr]         ;строка
        mov     cx,     [Xcurr]         ;колонка
        ;mov    al,     1       ;цвет (+80h означает XOR с точкой на экране)
        int     10h
        pop     dx
        pop     cx
        pop     bx
        pop     ax
 
        inc     word ptr [Xcurr]        ;следующую точку выводить правее
        loop    ForByBits
 
        ;сместиться на одну строку вниз при выводе следующей линии глифа
        inc     word ptr [Ycurr]
        ;вернуться на начальную колонку при выводе след. линии глифа
        sub     [Xcurr],word ptr 8
        pop     cx
        pop     ax
        add     di,     1       ;переходим к рассмотрению следующей строки глифа
        loop    ForByLines
 
        ;для вывода глифа следующего символа
        ; - уменьшить строку на высоту глифа
        sub     [Ycurr],word ptr FontH
        ; - сдвинуть колонку на ширину глифа
        add     [Xcurr],word ptr 8
        jmp     ForByChar
Break:
 
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
ShowString      endp
 
end     main

Оцени полезность:

12   голосов , оценка 4 из 5
Похожие ответы