Subversion Repositories Kolibri OS

Rev

Rev 2023 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;   SQ_game for MenuetOS
  2. ;   Author:    Alexei Ershov aka ealex
  3. ;   E-mail:    e-al[at]yandex[dot]ru
  4. ;   Fidonet:   2:469/335.38
  5. ; slightly optimized by diamond
  6. ; english translation by diamond (two strings in end of source)
  7.  
  8.  
  9.         BtnSize     equ 32      ; размер кнопки
  10.         BtnSpace    equ 10      ; промежуток между кнопками
  11.         NofBtn      equ 4   ; размер поля (3-15)
  12.         Color1      equ 0xcc0000
  13.         Color2      equ 0x00cc00
  14.  
  15.         FieldSize   = (BtnSize+BtnSpace)*NofBtn + BtnSpace*3
  16.         center      = FieldSize / 2
  17.  
  18.  
  19.   use32              ; включить 32-битный режим ассемблера
  20.   org    0x0         ; адресация с нуля
  21.  
  22.   db     'MENUET01'  ; 8-байтный идентификатор MenuetOS
  23.   dd     0x01        ; версия заголовка (всегда 1)
  24.   dd     START       ; адрес первой команды
  25.   dd     I_END       ; размер программы
  26.   dd     0x1000      ; количество памяти
  27.   dd     0x1000      ; адрес вершины стэка
  28.   dd     0x0         ; адрес буфера для параметров (не используется)
  29.   dd     0x0         ; зарезервировано
  30.  
  31. include 'macros.inc' ; макросы облегчают жизнь ассемблерщиков!
  32.  
  33.  
  34. START:
  35.     call Game_Init
  36. red:
  37.     call Draw_Window
  38.  
  39. still:
  40.     mcall 10            ; функция 10 - ждать события
  41.         dec     eax
  42.         jz      red
  43.         dec     eax
  44.         jnz     button
  45.  
  46.  key:                  ; нажата клавиша на клавиатуре
  47.         mov     al, 2
  48.         int     0x40
  49.         jmp     still
  50. ;---------------------------------------------------------------------
  51.  
  52. button:
  53.         mov     al, 17  ; 17 - получить идентификатор нажатой кнопки
  54.         int     0x40
  55.     cmp   ah, 1         ; если нажата кнопка с номером 1, выходим
  56.     je    .exit
  57.  
  58.     cmp   ah, 2         ; если нажата кнопка 2, начинаем новую игру
  59.     je    START
  60.  
  61.       ; Нажа кнопка на поле
  62.         inc     dword [moves]     ; увеличиваем число ходов
  63.  
  64.         shr     eax, 8            ; в eax идентификатор нажатой кнопки
  65.  
  66.         mov     dh, NofBtn
  67.         div     dh            ; al = ax(номер кнопки) / NofBtn
  68.                               ; ah = остаток  (см. рисунок)
  69.         mov     ebx, eax      ; сохраним частное и остаток в ebx
  70.  
  71.       ; al\ah 0   1    2    3
  72.       ;     +-+  +-+  +-+  +-+
  73.       ;  1  |4|  |5|  |6|  |7|
  74.       ;     +-+  +-+  +-+  +-+
  75.  
  76.       ;     +-+  +-+  +-+  +-+
  77.       ;  2  |8|  |9|  |10  |11
  78.       ;     +-+  +-+  +-+  +-+
  79.  
  80.       ;     +-+  +-+  +-+  +-+
  81.       ;  3  |12  |13  |14  |15
  82.       ;     +-+  +-+  +-+  +-+
  83.  
  84.       ;     +-+  +-+  +-+  +-+
  85.       ;  4  |16  |17  |18  |19
  86.       ;     +-+  +-+  +-+  +-+
  87.  
  88. ; Меняем цвет столбика
  89.         shr     eax, 8        ; eax = ah
  90.         mov     edi, field
  91.         add     edi, eax    ; edi указвыет на первую кнопку и искомом стлбце
  92.         mov     ecx, NofBtn
  93. @@:
  94.         not     byte[edi]    ; меняем цвет во всем столбике
  95.         dec     ecx
  96.         add     edi, NofBtn
  97.         test    ecx, ecx
  98.         jnz     @r
  99.  
  100. ; Меняем цвет строки
  101.         mov     eax, ebx      ; восстанавливаем eax
  102.         dec     eax
  103.         mov     dl, NofBtn
  104.         mul     dl            ; ax = al * NofBtn
  105.         mov     edi, field
  106.         add     edi, eax     ; edi указвыет на первую кнопку в искомой строке
  107.         mov     ecx, NofBtn
  108. @@:
  109.         not     byte [edi]    ; меняем цвет во всей строке
  110.         dec     ecx
  111.         inc     edi
  112.         test    ecx, ecx
  113.         jnz     @r
  114. ; Цвет нажатой кнопки менялся 2 раза (когда обрабатывали строку и столбец),
  115. ; т.е. остался первоначалным
  116. ; Меняем цвет нажатой кнопки
  117.         shr     ebx, 8        ; ebx = остаток (ah на рисунке)
  118.         not     byte [field+eax+ebx]
  119.         jmp     red
  120.  
  121.  
  122.  
  123.   .exit:
  124.     mcall -1            ; иначе конец программы
  125.  
  126.  
  127. ;----------------------------------------------------------------------------
  128. ;               Draw_Window
  129. ;----------------------------------------------------------------------------
  130. Draw_Window:
  131.  
  132.     mcall 12, 1
  133.     mcall 0, 200*65536+FieldSize,\
  134.              200*65536+FieldSize+20+20+20,\
  135.              0x14AABBCC, 0x805080D0, header
  136.  
  137.     mcall 8, BtnSpace*2*65536 + 83,\
  138.              (FieldSize+BtnSpace+20)*65536+ 15, 2
  139.     mcall 4, (BtnSpace*2+3)*65536+(BtnSize+BtnSpace)*NofBtn+BtnSpace*4+20+4,\
  140.              0x10DDEEFF, strNew, strNew_e - strNew
  141.     mcall 4, (center - 25) * 65536 + 30, 0, strMovs, strMovs_e - strMovs
  142.     mcall 47, 4*65536+1, moves, (center + 2 ) * 65536 + 30, 0
  143.  
  144.  
  145.  
  146.         mov     ecx, (20+20+BtnSpace-BtnSize)*65536+BtnSize
  147.         mov     edx, NofBtn           ; идентификатор первой кнопки на поле
  148.                                       ; см рисунок
  149.  
  150. buttons:                              ; рисуем кнопочки
  151.         mov     eax, edx
  152.         mov     dh, NofBtn
  153.         div     dh           ; al = ax / dh, ah - остаток
  154.         mov     dh, 0
  155.         test    ah, ah       ; если ah = 0, начинаем новый ряд
  156.         jnz     @f
  157.         add     ecx, (BtnSize+BtnSpace)*65536
  158.         mov     ebx, BtnSpace*2*65536+BtnSize
  159. @@:
  160.         mov     esi, Color1                    ; байт по адресу
  161.         cmp     byte [field-NofBtn+edx], 0      ; field-NofBtn+номер_кнопки
  162.         jz      @f                              ; говорит о ее цвете
  163.         mov     esi, Color2
  164. @@:
  165.         mcall 8,
  166.         add     ebx, (BtnSize+BtnSpace)*65536
  167.         inc     edx                        ; переходим к следующей кнопке
  168.         cmp     edx, NofBtn*(NofBtn+1)
  169.         jb      buttons
  170.  
  171.     mcall 12, 2                    ; функция 12: сообщить ОС об отрисовке окна
  172.  
  173. ret
  174.  
  175. ;----------------------------------------------------------------------------
  176. ;               Game_Init
  177. ;----------------------------------------------------------------------------
  178. Game_Init:
  179.         and     [moves], 0             ; обнулим количество ходов
  180.  
  181.         call    random                 ; в eax случайное число
  182.         mov     ecx, NofBtn * NofBtn   ; в ecx кол-во кнопок на поле
  183.         mov     bh, 0                  ; для каждой кнопки будем брать
  184.                                        ; 1 бит из eax, bh - сколько
  185. button_init:                           ; бит уже использовали
  186.         shr     eax, 1           ; младший бит попадает в флаг CF
  187.                                  ; в зависимости от его значения
  188.                                  ; в bl записывается -1 или 0
  189.         sbb     bl, bl
  190.         mov     [field + ecx - 1], bl
  191.  
  192.         inc     bh
  193.         cmp     bh, 32           ; если использованы все 32 бита из eax
  194.         jb      @f               ; нао получить новое случайное число
  195.         call    random
  196.         mov     bh, 0
  197. @@:
  198.         loop    button_init
  199.  
  200. ret
  201.  
  202. ;----------------------------------------------------------------------------
  203. ;     random - взята из тетриса
  204. ;----------------------------------------------------------------------------
  205. random:         mov eax,[generator]
  206.                 add eax,-43ab45b5h
  207.                 ror eax,1
  208.                 xor eax,32c4324fh
  209.                 ror eax,1
  210.                 mov [generator],eax
  211.                 ; --- IVAN ---
  212.                 mov eax,26
  213.                 mov ebx,9
  214.                 int 0x40
  215.                 xor eax,0xdeadbeef
  216.                 add eax,[generator]
  217.                 ; --- IVAN ---
  218.                 ret
  219.  
  220. ;============================================================================
  221.  
  222. field           db NofBtn * NofBtn dup(0)
  223. moves           dd 0
  224. generator       dd 0
  225.  
  226. if lang eq ru
  227. header          db 'CQ game',0
  228. header_e:
  229. strMovs         db 'ХОД'        ; 'ХОД'
  230. strMovs_e:
  231. strNew          db 'Новая игра' ; 'Новая игра'
  232. strNew_e:
  233. else
  234. header          db 'CQ game',0
  235. header_e:
  236. strMovs         db 'MOVE'
  237. strMovs_e:
  238. strNew          db ' New game'
  239. strNew_e:
  240. end if
  241.  
  242.  
  243.  
  244. I_END:                             ; метка конца программы
  245.