Непонятная ошибка в вычислении положения куба на плоскости

Тема в разделе "WASM.BEGINNERS", создана пользователем Dumanovsky, 23 мар 2008.

  1. Dumanovsky

    Dumanovsky New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2008
    Сообщения:
    13
    Попробовал написать программу (я в ассемблере начинающий), но столкнулся с проблемами.
    1. Когда кубик движется вниз, то всё нормально (он движется постепенно), но при отскакиваниии от платформы мгновенно перемещается по диагонали до правой границы экрана.
    2. По идее программа должна реагировать на нажатие клавиши Esc, но он почему-то не реагирует.
    Разбирался с этим делом до тех пор, пока мой ЖК монитор (надеюсь временно) перестал вообще отображать что либо в этом графическом режиме.



    Если Вас не затруднит, не могли бы мне указать мои ошибки, чтобы эта прога работала нормально и выходила только при потере кубика или нажатии Esc, а не через Alt+Enter и диспетчер задач. Я ещё также переместил блок проверки положения куба в ту часть кода, которая выполняется только тогда, когда его координаты меняются, но проверить уже не смог:dntknw:, Впрочем:

    Код (Text):
    1. .model small
    2. .stack 256
    3. .386
    4.  
    5. .data
    6. ;Data Segment--------------------------------
    7.  
    8. saveMode db ?   ; сохраненный видео режим
    9. xVal     dw 151   ; координата X платформы 160-8-1, т.к. ширина платформы - 16 и смещение с 0
    10. yVal     dw 189   ; координата Y платформы
    11. xc     dw 0; координата X куба
    12. yc     dw 0; координата Y куба
    13. adxc     db 1; значение Х, прибавляемое к положению куба при перемещении
    14. adyc     db 1; значение У, прибавляемое к положению куба при перемещении
    15.  
    16. .code
    17. ; Code Segment--------------------------------
    18. main proc
    19. .startup ;инициализация сегмента данных
    20.  
    21.         call SetVideoMode    Установить видеорежим
    22.         call SetIndexes        Определить цветовые индексы
    23.         call DrawCube;Нарисовать куб
    24.         call DrawPlace;    Нарисовать платформу        
    25.         mov ah,00h;        Функция чтения счётчика тиков
    26.         int 1ah;        Выполнить прерывание    
    27.         mov bx, dx;        Сохранить младшие рязряды количества тиков в bx
    28. ;Game
    29. Game:                    
    30.         mov ah, 1;    функция прерывания int 16h для чтения символа с клавиатуры
    31.         int    16h
    32.         cmp ah,0
    33.         jne checkcursor;Функциональная клавиша не нажата
    34.         cmp al, 27;    Если нажата Escape
    35.         je Q;        то выход иначе продолжаем
    36.         jmp endkeys;    Конец проверок клавиш
    37. checkcursor:    
    38.         cmp AH, 75;    Указатель курсора влево?
    39.         jne checkcursor1
    40.         cmp xVal,0;    Дальнейший сдвиг влево возможен?
    41.         je endkeys;    Конец проверок клавиш        
    42.         call clearplace;Стереть платформу        
    43.         sub xVal,1;    Сдвинуть на 1 влево
    44.         call DrawPlace;    Нарисовать платформу
    45.         jmp endkeys;    Конец проверок клавиш
    46. checkcursor1:  
    47.         cmp AH, 77;    Указатель курсора вправо?
    48.         jne endkeys;    Конец проверок клавиш
    49.         cmp xVal, 303;    Дальнейший сдвиг вправо возможен? (320-16-1=303)
    50.         je endkeys;    Конец проверок клавиш        
    51.         call clearplace;Стереть платформу        
    52.         add xVal,1;    Сдвинуть на 1 вправо
    53.         call DrawPlace;    Нарисовать платформу
    54. endkeys:        
    55.         mov ah, 5    ;Функция записи символа в буфер клавиатуры прерывания Int 16h
    56.         mov cx,0    ;Запись 0-го символа
    57.         int 16h        ;Выполнение прерывания
    58.         CLI                    ;запрещаем прерывания
    59.         push ES               ;Сохранить содержимое сегментного регистра ES в стеке    
    60.         SUB  AX,AX             ;обнуляем регистр
    61.         MOV  ES,AX            ;добавочный сегмент - с начала памяти
    62.         MOV  AL,ES:[41AH]      ;берем указатель на голову буфера
    63.         MOV  ES:[41CH],AL      ;посылаем его в указатель хвоста        
    64.         POP ES            ; Восстанавливаем содержимое сегментного регистра ES
    65.         STI                   ;разрешаем прерывания        
    66.        
    67.         mov ah,00h;    Функция чтения счётчика тиков
    68.         int 1ah;    Выполнить прерывание    
    69.         cmp bx, dx;    Сравнить с предыдущим значением тиков
    70.         je l5;        Если совпадают - не перемещать куб
    71.         mov bx,dx;    Сохранить младшие рязряды количества тиков в bx
    72.        
    73.         cmp xc,0;    Координата куба Х = 0 (касание левого края экрана)?
    74.         jne l1; нет
    75.         mov adxc,1;    да - следующее перемещение куба по х в положительном направлении (Ось Х направлена вправо)
    76. l1:        cmp xc,317;    Координата куба Х = 317 (320-2-1) (касание правого края экрана)?
    77.         jne l2;        нет
    78.         mov adxc,-1;    да - следующее перемещение куба по х в орицательном направлении
    79. l2:        cmp yc,0;    Координата куба У = 0 (касание верхнего края экрана)?
    80.         jne l3;        нет
    81.         mov adyc,1;    да - следующее перемещение куба по У в положительном направлении (Ось У направлена вниз)    
    82. l3:        cmp yc, 187;    Нижняя граница куба поравнялась с нижней границей платформы (187+2=189=yVal)?
    83.         jae Q;        Игра окончена
    84.         cmp yc, 186;    Нижняя граница куба поравнялась с верхней границей платформы ((186+2=188)<(189=yVal) на 1 - высота отбития)?
    85.         jne l4;    нет - куб не отбит
    86.         mov ax, xVal;    Куб по ширине 3 пиксела - если он хотябы половиной коснётся платформы - он отбит,
    87.         sbb ax, 2;    следовательно, допустимо смещение левого края куба на 2 влево от края платформы
    88.         cmp xc, ax;    Условие описанное выше соблюдается?
    89.         jl l4;        нет - куб не отбит
    90.         adc ax, 18;    Проверим правый край. Ширина платформы - 16 +2 вычтенная ранее = 18
    91.         cmp xc,ax;    Куб попадает на платформу?
    92.         jg l4;        нет - куб не отбит
    93.         mov adyc, -1;    да - куб отбит следующее перемещение куба по У в отрицательном направлении        
    94.        
    95.         ; Закрасить куб цветом фона
    96.         ;Вычисление смещения первой точки буфера Куба
    97. l4:        mov ax,320    ; 320 для режима 13h
    98.         mul yc      ; координата Y куба
    99.         add ax,xc   ; координата X куба
    100.         ;Поступательное движение куба
    101.         mov di,ax       ; в регистре AX хранится смещение буфера
    102.         mov byte ptr es:[di],0     ; рисование точки, 0 - индекс палитры
    103.         add di,1
    104.         mov byte ptr es:[di],0     ; рисование точки, 0 - индекс палитры
    105.         add di,1
    106.         mov byte ptr es:[di],0     ; рисование точки, 0 - индекс палитры
    107.         add di, 320; следующая строка
    108.         mov byte ptr es:[di],0     ; рисование точки, 0 - индекс палитры
    109.         sub di,1
    110.         mov byte ptr es:[di],0     ; рисование точки, 0 - индекс палитры
    111.         sub di,1
    112.         mov byte ptr es:[di],0     ; рисование точки, 0 - индекс палитры
    113.        
    114.         mov ax,0
    115.         mov al, adxc;
    116.         add xc, ax; Переместить куб
    117.         mov ax,0
    118.         mov al, adyc;
    119.         add yc, ax; Переместить куб
    120.            
    121.         call DrawCube;Нарисовать куб
    122.  
    123. l5:        jmp Game; новая итерация цикла
    124.  
    125. Q:        call RestoreVideoMode
    126.         .exit;        
    127.  
    128. main endp
    129.  
    130.  
    131.  
    132. ;-----------
    133. SetVideoMode proc
    134. ;-----------
    135. ; Эта процедура сохраняет старый видео режим, переключается в новый и
    136. ; указывает регистр ES на видео сегмент
    137.  
    138. mov ah,0Fh        ; получить видеорежим
    139. int 10h
    140. mov saveMode,al   ; сохранить
    141.  
    142. mov ah,0          ; установить новый видео режим
    143. mov al,13h        ; режим 13h
    144. int 10h
    145.  
    146.  
    147. push 0A000h       ; адрес видео сегмента
    148. pop es            ; ES = 0A000h
    149.  
    150. ret
    151. SetVideoMode endp
    152.  
    153. ;------------
    154. RestoreVideoMode proc
    155. ;------------
    156. ; Эта процедура ожидает нажатия клавиши, а затем восстанавливает
    157. ; прежний видео режим
    158.  
    159. mov ah, 10h         ; ожидает нажатия
    160. int 16h
    161.  
    162. mov ah,0            ; установить видео режим
    163. mov al,saveMode     ; который был при старте
    164. int 10h
    165.  
    166. ret
    167. RestoreVideoMode endp
    168.  
    169. ;-----------------
    170. SetIndexes proc
    171. ;-----------------
    172. mov dx,3c8h   ; порт видео палитры (3C8h)
    173. mov al,0      ; установить индекс палитры 0 в чёрный
    174. out dx,al
    175.  
    176. mov dx,3c9h                  ; порт записи 3C9h
    177. mov al,0            ; красный
    178. out dx,al
    179. mov al,0            ; зеленый
    180. out dx,al
    181. mov al,0            ; синий
    182. out dx,al
    183. ;-------------------------------------------
    184. mov dx,3c8h   ; порт видео палитры (3C8h)
    185. mov al,1      ; установить индекс палитры 1 в белый
    186. out dx,al
    187.  
    188. mov dx,3c9h                  ; порт записи 3C9h
    189. mov al,63            ; красный
    190. out dx,al
    191. mov al,63            ; зеленый
    192. out dx,al
    193. mov al,63            ; синий
    194. out dx,al
    195. ;-------------------------------------------
    196. mov dx,3c8h   ; порт видео палитры (3C8h)
    197. mov al,2      ; установить индекс палитры 2 в синий
    198. out dx,al
    199.  
    200. mov dx,3c9h                  ; порт записи 3C9h
    201. mov al, 0            ; красный
    202. out dx,al
    203. mov al, 0            ; зеленый
    204. out dx,al
    205. mov al,63            ; синий
    206. out dx,al
    207.  
    208. ret
    209. SetIndexes endp
    210.  
    211. ;----------------
    212. DrawPlace proc;----------------
    213.  
    214. ; нарисовать платформу
    215.  
    216. ;Вычисление смещения первой точки буфера платформы
    217. mov ax,320    ; 320 для режима 13h
    218. mul yVal      ; координата Y платформы
    219. add ax,xVAl   ; координата X платформы
    220.  
    221. mov cx,16       ; нарисовать 16 точек - ширина платформы
    222. mov di,ax       ; в регистре AX хранится смещение буфера
    223.  
    224. Place:
    225.     mov byte ptr es:[di],2     ; рисование точки, 2 - индекс палитры
    226.     add di,1
    227. loop Place
    228.  
    229. ret
    230. DrawPlace endp
    231.  
    232.  
    233. clearplace proc
    234. ;Вычисление смещения первой точки буфера платформы
    235. mov ax,320    ; 320 для режима 13h
    236. mul yVal      ; координата Y платформы
    237. add ax,xVAl   ; координата X платформы
    238.  
    239. mov cx,16       ; нарисовать 16 точек - ширина платформы
    240. mov di,ax       ; в регистре AX хранится смещение буфера
    241.  
    242. clearplace1:
    243.     mov byte ptr es:[di],0     ; рисование точки, 0 - индекс палитры
    244.     add di,1
    245. loop clearplace1
    246. ret
    247. clearplace endp
    248.  
    249. DrawCube proc
    250. ; Нарисовать куб
    251.  
    252. ;Вычисление смещения первой точки буфера Куба
    253. mov ax,320    ; 320 для режима 13h
    254. mul yc      ; координата Y куба
    255. add ax,xc   ; координата X куба
    256.  
    257. mov di,ax       ; в регистре AX хранится смещение буфера
    258. mov byte ptr es:[di],1     ; рисование точки, 1 - индекс палитры
    259. add di,1
    260. mov byte ptr es:[di],1     ; рисование точки, 1 - индекс палитры
    261. add di,1
    262. mov byte ptr es:[di],1     ; рисование точки, 1 - индекс палитры
    263. add di, 320; следующая строка
    264. mov byte ptr es:[di],1     ; рисование точки, 1 - индекс палитры
    265. sub di,1
    266. mov byte ptr es:[di],1     ; рисование точки, 1 - индекс палитры
    267. sub di,1
    268. mov byte ptr es:[di],1     ; рисование точки, 1 - индекс палитры    
    269. ret
    270. DrawCube endp
    271.  
    272. end
     
  2. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Элементарно, Ватсон. Ты засылаешь "якобы" -1, а получается +255 по Y.