Subversion Repositories Kolibri OS

Rev

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