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