Subversion Repositories Kolibri OS

Rev

Rev 5282 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4323 yogev_ezra 1
;заголовок приложения
2
 
3
SK_SPACE equ 0x39
4
SK_CTRL  equ 0x1D
5
SK_UP	 equ 0x48
6
SK_DOWN  equ 0x50
7
SK_LEFT  equ 0x4B
8
SK_RIGHT equ 0x4D
9
SK_ESC	 equ 0x01
10
 
11
 
12
INIT_PLANE_X equ 20
13
INIT_PLANE_Y equ 20
14
BACK_COLOR equ 0x9bcdfa
15
GROUND_COLOR equ 0x808080
16
BANG_COLOR equ 0xB0140E
17
ANIM_PLANE_BMP_PIXELS_COUNT equ 22*32*32
18
WINDOW_WIDTH equ 800
19
WINDOW_HEIGHT equ 600
20
GROUNG_HEIGHT equ 100
21
CITY_OFFSET equ (WINDOW_WIDTH-32*20)/2
22
MAX_BOMBS equ 8
23
GRAVY_ACCEL equ 1
24
BOMB_DELAY equ 12
25
MAX_LEVEL equ 5
26
ACKACK_BULLET_SPEED equ 17
27
BULLET_SIZE equ 7
28
MAX_SOUNDS equ 8
29
 
30
VOLUME_BOMBFLY equ 16
31
VOLUME_BOMBBANG equ 28
32
VOLUME_ACKACK equ 24
33
VOLUME_PLANE equ 48
34
VOLUME_ARW equ 16
35
 
36
 
37
use32			   ; транслятор, использующий 32 разрядных команды
38
    org 0x0		   ; базовый адрес кода, всегда 0x0
39
    db 'MENUET01'	; идентификатор исполняемого файла (8 байт)
40
    dd 0x1	     ; версия формата заголовка исполняемого файла
41
    dd start	     ; адрес, на который система передаёт управление
42
		       ; после загрузки приложения в память
43
    dd i_end	    ; размер приложения
44
    dd i_end  ; Объем используемой памяти, для стека отведем 0х100 байт
45
    dd i_end  ; расположим позицию стека в области памяти, сразу за телом программы. Вершина стека в диапазоне памяти, указанном выше
46
    dd 0x0, _s_current_dir		  ; указатель на строку с параметрами.
47
		 ;    если после запуска неравно нулю, приложение было
48
		 ;    запущено с параметрами из командной строки
49
 
50
		 ;    указатель на строку, в которую записан путь,
51
		 ;    откуда запущено приложение
52
;Область кода
53
 
54
;----------------- include -------------------------------------
5282 mario79 55
include 'lang.inc'
4323 yogev_ezra 56
include 'ssmix.inc'
57
 
58
;---------------------------------------------------------------------------
59
;----------------------------- главный цикл --------------------------------
60
;---------------------------------------------------------------------------
61
 
62
align 4
63
start:		   ;Точка входа в программу
64
 
65
     ; режим клавиатуры: скан-коды
66
     mov  eax, 66
67
     mov  ebx, 1
68
     mov  ecx, 1
69
     int  0x40
70
 
71
     ; инициализация кучи
72
     mov  eax, 68
73
     mov  ebx, 11
74
     int  0x40
75
     cmp  eax, 1000000	; куча нужна минимум на ~1000кб (это с запасом)
76
     ja   heap_ok
77
     mov  eax, -1
78
     int  0x40	       ; иначе закрываем все
79
   heap_ok:
80
 
81
     mov    eax, bmp_plane
82
     mov    ebx, 736*32*3
83
     call   convert_bmp_backcolor
84
     mov    eax, bmp_bomb
85
     mov    ebx, 96*16*3
86
     call   convert_bmp_backcolor
87
     mov    eax, bmp_tile
88
     mov    ebx, 20*20*3
89
     call   convert_bmp_backcolor
90
     mov    eax, bmp_ackack
91
     mov    ebx, 40*20*3
92
     call   convert_bmp_backcolor
93
 
94
     call  read_sounds_file
95
     call  ssmix_init
96
 
97
     mov  [_game_state], 0
98
 
99
redraw_window:
100
     call draw_window
101
     cmp  [_game_state], 0
102
     jne   still_no_intro
103
     call draw_intro
104
  still_no_intro:
105
 
106
still:
107
     ; обработка событий
108
     mov  eax,11
109
     int  0x40
110
     cmp  eax,1
111
     je   redraw_window
112
     cmp  eax,2
113
     je   key
114
     cmp  eax,3
115
     je   close_button
116
 
117
     ; пауза
118
     mov  eax,5
119
     mov  ebx,1
120
     int  0x40
121
 
122
     mov  eax, 26
123
     mov  ebx, 9
124
     int  0x40
125
     mov  ebx, eax
126
     sub  eax, [_last_value_timecount]
127
     cmp  eax, [_delay]
128
     jbe  still
129
     mov  [_last_value_timecount], ebx
130
 
131
     call timer_x2
132
     call timer_x4
133
 
134
     ; проверка на игру
135
     cmp  [_game_state], 1
136
     jne  still_no_game
137
     ; вызов процедур игрового процесса
138
     mov  eax, [_plane_health]
139
     cmp  eax, 0
140
     jle  still_no_plane
141
     call flight_control_plane
142
     call plane_interaction
143
     call draw_plane
144
   still_no_plane:
145
     call draw_plane_health
146
     call bomb_proc
147
     call bang_proc
148
     call ground_draw
149
     call city_draw
150
     call ackack_draw
151
     call ackack_bullet_proc
152
     ; таймер завершения игры
153
     call  game_over_timer
154
   still_no_game:
155
 
156
     jmp  still
157
 
158
 
159
key:			    ; обработка нажатия клавиш
160
    mov  eax,2
161
    int  0x40
162
 
163
    push eax
164
  key_SPACE:
165
    cmp  ah, SK_SPACE
166
    jne  key_SPACE_end
167
    cmp  [_game_state], 1
168
    je	 key_SPACE_do_a_barrel_roll
169
  key_SPACE_start_game: 	      ; запуск игры
170
    mov  [_game_state], 1
171
    call init_game_state
172
    jmp  key_SPACE_end
173
  key_SPACE_do_a_barrel_roll:	      ; сделать бочку
174
    mov  eax, [_plane_state]
175
    cmp  eax, 0
176
    je	 key_SPACE_do_a_barrel_roll_r
177
    cmp  eax, 1
178
    je	 key_SPACE_do_a_barrel_roll_l
179
    jmp  key_SPACE_end
180
  key_SPACE_do_a_barrel_roll_r:
181
    mov  eax,[_X_plane]
182
    cmp  eax, WINDOW_WIDTH-130-32
183
    jg	 key_SPACE_end
184
    mov  [_plane_state], 4
185
    mov  [_plane_state_step], 0
186
    jmp  key_SPACE_end
187
  key_SPACE_do_a_barrel_roll_l:
188
    mov  eax,[_X_plane]
189
    cmp  eax, 130
190
    jl	 key_SPACE_end
191
    mov  [_plane_state], 5
192
    mov  [_plane_state_step], 0
193
  key_SPACE_end:
194
    pop  eax
195
 
196
  key_CTRL:
197
    cmp  ah, SK_CTRL
198
    jne  key_CTRL_end
199
    call bomb_drop
200
  key_CTRL_end:
201
 
202
  key_UP:
203
    cmp  ah, SK_UP
204
    jne  key_UP_end
205
    cmp  [_game_state], 0
206
    jne  key_UP_end
207
    mov  ebx, [_level_num]
208
    inc  ebx
209
    mov  [_level_num], ebx
210
    cmp  ebx, MAX_LEVEL
211
    jbe  key_UP_no_max
212
    mov  [_level_num], MAX_LEVEL
213
  key_UP_no_max:
214
    call draw_level_num
215
  key_UP_end:
216
 
217
  key_DOWN:
218
    cmp  ah, SK_DOWN
219
    jne  key_DOWN_end
220
    cmp  [_game_state], 0
221
    jne  key_DOWN_end
222
    mov  ebx, [_level_num]
223
    dec  ebx
224
    mov  [_level_num], ebx
225
    cmp  ebx, 1
226
    jae  key_DOWN_no_min
227
    mov  [_level_num], 1
228
  key_DOWN_no_min:
229
    call draw_level_num
230
  key_DOWN_end:
231
 
232
 
233
  key_LEFT:
234
    cmp  ah, SK_LEFT
235
    jne  key_LEFT_end
236
    cmp  [_game_state], 0
237
    jne  key_LEFT_end
238
    mov  ebx, [_set_volume]
239
    dec  ebx
240
    cmp  ebx, 0
241
    jge  @f
242
    mov  ebx, 0
243
  @@:
244
    mov  [_set_volume], ebx
245
    shl  ebx, 4
246
    stdcall ssmix_setvolume, ebx, ebx
247
    call draw_volume_num
248
  key_LEFT_end:
249
 
250
 
251
  key_RIGHT:
252
    cmp  ah, SK_RIGHT
253
    jne  key_RIGHT_end
254
    cmp  [_game_state], 0
255
    jne  key_RIGHT_end
256
    mov  ebx, [_set_volume]
257
    inc  ebx
258
    cmp  ebx, 8
259
    jle  @f
260
    mov  ebx, 8
261
  @@:
262
    mov  [_set_volume], ebx
263
    shl  ebx, 4
264
    stdcall ssmix_setvolume, ebx, ebx
265
    call draw_volume_num
266
  key_RIGHT_end:
267
 
268
 
269
  key_ESC:
270
    cmp  ah, SK_ESC
271
    jne  key_ESC_end
272
    jmp  close_button
273
  key_ESC_end:
274
 
275
    jmp  still
276
 
277
 
278
 
279
 
280
close_button:		    ; завершение работы
281
 
282
     call  ssmix_release
283
     call  sounds_free_memory
284
     ; закрыть приложение
285
     mov  eax, -1
286
     int  0x40
287
 
288
 
289
;---------------------------------------------------------------------------
290
;----------------------------- подрограммы ---------------------------------
291
;---------------------------------------------------------------------------
292
 
293
 
294
convert_bmp_backcolor:	    ; eax - указаталь на начало данных, ebx - размер данных
295
 
296
     push  ecx
297
   cbb_loop:
298
     cmp   ebx, 0
299
     jle   cbb_loop_end
300
     mov   ecx, [eax]
301
     and   ecx, 0x00FFFFFF
302
     cmp   ecx, 0x00FFFFFF
303
     jne   @f
304
     mov   ecx, BACK_COLOR
305
     mov   [eax], cl
306
     shr   ecx, 8
307
     mov   [eax+1], cl
308
     shr   ecx, 8
309
     mov   [eax+2], cl
310
   @@:
311
     add   eax, 3
312
     sub   ebx, 3
313
     jmp   cbb_loop
314
   cbb_loop_end:
315
     pop   ecx
316
 
317
     ret
318
 
319
; чтение файла со звуками
320
read_sounds_file:
321
 
322
     mov  edi, _s_current_dir
323
     mov  al, 0
324
     mov  ecx, 4096
325
     repne scasb
326
     mov  dword[edi-1], 'data'
327
     mov  dword[edi+3], '.bin'
328
     mov  [_flag_bomberdatabin_ok], 1
329
     ; прочитать из файла данных количество звуков
330
     mov  [_fi_func], 0
331
     mov  [_fi_pos], 8
332
     mov  [_fi_size], 4
333
     mov  [_fi_pbuff], _count_sounds
334
     mov  [_fi_pfilename], _s_current_dir
335
     mov  eax, 70
336
     mov  ebx, file_info
337
     int  0x40
338
     cmp  ebx, -1
339
     jne  @f
340
     mov  [_flag_bomberdatabin_ok], 0
341
     jmp  .end
342
   @@:
343
     ; прочитать данные о смещении и размере звуков в файле, и записать их (временно) в массив звуков
344
     mov  ecx, [_count_sounds]
345
     shl  ecx, 3
346
     mov  [_fi_func], 0
347
     mov  [_fi_pos], 12
348
     mov  [_fi_size], ecx
349
     mov  [_fi_pbuff], _array_sounds
350
     mov  [_fi_pfilename], _s_current_dir
351
     mov  eax, 70
352
     mov  ebx, file_info
353
     int  0x40
354
     ; прочитать звуки в файле и записать их в память
355
     mov  ecx, [_count_sounds]
356
     mov  esi, _array_sounds
357
   .loop:
358
     push  ecx
359
     ; подготовить данные информационной структуры для чтения из файла
360
     mov  [_fi_func], 0
361
     mov  eax, [esi]
362
     mov  [_fi_pos], eax
363
     mov  eax, [esi+4]
364
     mov  [_fi_size], eax
365
     ; выделить память под звук, получить указатель, и изменить данные в массиве звуков
366
     mov  ecx, [esi+4]
367
     mov  eax, 68
368
     mov  ebx, 12
369
     int  0x40
370
     mov  [esi], eax
371
     mov  ecx, [esi+4]
372
     add  ecx, eax
373
     mov  [esi+4], ecx
374
     ; прочитать сэмпл из файла
375
     mov  [_fi_pbuff], eax
376
     mov  [_fi_pfilename], _s_current_dir
377
     mov  eax, 70
378
     mov  ebx, file_info
379
     int  0x40
380
     pop   ecx
381
     add  esi, 8
382
     dec  ecx
383
     jnz  .loop
384
   .end:
385
 
386
     ret
387
 
388
 
389
sounds_free_memory:
390
 
391
     mov  ecx, [_count_sounds]
392
     mov  esi, _array_sounds
393
   .loop:
394
     push  ecx
395
     ; выделить память под звук, получить указатель, и изменить данные в массиве звуков
396
     mov  eax, 68
397
     mov  ebx, 13
398
     mov  ecx, [esi]
399
     int  0x40
400
     pop   ecx
401
     add  esi, 8
402
     dec  ecx
403
     jnz  .loop
404
 
405
 
406
     ret
407
 
408
 
409
init_game_state:		     ; инициализация игровых данных
410
    mov  [_game_over_time], 0
411
    mov  [_X_plane], INIT_PLANE_X
412
    mov  [_Y_plane], INIT_PLANE_Y
413
    mov  [_VX_plane], 4
414
    mov  [_plane_state], 0
415
    mov  [_anim_pos_plane], 0
416
    mov  [_plane_health], 100
417
    mov  [_timer_x2], 0
418
    mov  [_timer_x4], 0
419
    mov  [_bomb_count], 0
420
    mov  [_bomb_delay_time], 0
421
    mov  [_addit_VY_plane], 0
422
    mov  [_flag_air_raid_warning], 0
423
 
424
    call load_level
425
 
426
    ; инициализация массива взрывов
427
    mov  ebx, _bang_array
428
    xor  ecx, ecx
429
  igs_bang_array_loop:
430
    cmp  ecx, MAX_BOMBS
431
    jae  igs_bang_array_loop_end
432
    mov  eax, -1
433
    mov  [ebx], eax
434
    add  ebx, 8
435
    inc  ecx
436
    jmp  igs_bang_array_loop
437
 igs_bang_array_loop_end:
438
    ; инициализация массива зенитных снарядов
439
    mov  ebx, _ackack_bullet
440
    xor  ecx, ecx
441
  igs_bullet_array_loop:
442
    cmp  ecx, 32
443
    jae  igs_bullet_array_loop_end
444
    mov  eax, 0
445
    mov  [ebx], eax
446
    add  ebx, 4
447
    inc  ecx
448
    jmp  igs_bullet_array_loop
449
 igs_bullet_array_loop_end:
450
 
451
    ; очистить экран
452
    call draw_window
453
 
454
    ;запустить звук пропелера
455
    cmp  [_flag_bomberdatabin_ok], 1
456
    jne  @f
457
    stdcall  ssmix_playtrack, [_array_sounds+8*((( 4 ))-1)], [_array_sounds+8*((( 4 ))-1)+4], VOLUME_PLANE, VOLUME_PLANE, SSMIX_CHANMODE_REPEAT
458
  @@:
459
    mov  [_channel_sound_plane], eax
460
 
461
    mov  [_channel_sound_arw], -1
462
 
463
    ret
464
 
465
 
466
 
467
game_over:
468
 
469
    mov   [_game_over_time], 30   ; задаем задержку на game over
470
    ;вывод текста GAME OVER
471
    mov  eax,4
472
    mov  ebx,(WINDOW_WIDTH/2 - 50)*65536 + 30
473
    mov  ecx,0x80000000
474
    mov  edx,_text_game_over
475
    int  0x40
476
 
477
    cmp  [_flag_bomberdatabin_ok], 1
478
    jne  @f
479
    stdcall  ssmix_stoptrack, [_channel_sound_plane]
480
  @@:
481
 
482
    ret
483
 
484
 
485
game_over_timer:	       ; таймер завершения игры, создает небольшую паузу перед остановкой игры
486
 
487
    mov   ebx, [_game_over_time]
488
    cmp   ebx, 0
489
    je	  got_end
490
    dec   ebx
491
    mov   [_game_over_time], ebx
492
    cmp   ebx, 0
493
    jg	  got_end
494
    mov   [_game_state], 0
495
    cmp  [_flag_bomberdatabin_ok], 1
496
    jne  @f
497
    call  ssmix_stopalltracks
498
  @@:
499
    call  draw_window
500
    call  draw_intro
501
  got_end:
502
 
503
    ret
504
 
505
 
506
next_level:		       ; следующий уровень
507
 
508
    push  eax
509
    mov   [_game_over_time], 1	 ; быстренько завершим игру
510
    mov   eax, [_level_num]	 ; на следующий уровень
511
    inc   eax
512
    cmp   eax, MAX_LEVEL
513
    jbe   next_level_no_overmax
514
    mov   eax, MAX_LEVEL
515
  next_level_no_overmax:
516
    mov   [_level_num], eax
517
    pop   eax
518
 
519
    ret
520
 
521
 
522
 
523
check_level_complete:		; проверка на завершение уровня
524
 
525
    push  eax
526
    push  ebx
527
    push  ecx
528
    push  edx
529
 
530
    mov  edx, 0        ; флаг наличия строений в городе: 0 - нет строений, 1 - есть строения
531
    mov  ebx, _city
532
    xor  ecx, ecx
533
  clc_loop:
534
    cmp  ecx, 32
535
    jae  clc_loop_end
536
    xor  eax, eax
537
    mov  ax, [ebx]
538
    cmp  eax, 0
539
    je	 clc_no_buildings
540
    mov  edx, 1
541
    jmp  clc_loop_end
542
  clc_no_buildings:
543
    add  ebx, 2
544
    inc  ecx
545
    jmp  clc_loop
546
  clc_loop_end :
547
    cmp  edx, 0
548
    jne  clc_end
549
    ; уровень завершен - идем на посадку
550
    ;вывод текста LEVEL COMPLETE
551
    mov  eax,4
552
    mov  ebx,(WINDOW_WIDTH/2 - 70)*65536 + 30
553
    mov  ecx,0x80000000
554
    mov  edx,_text_level_complete
555
    int  0x40
556
    ; быстрое снижение самолета
557
    mov  [_addit_VY_plane], 3	   ; задать скорость быстрого снижения
558
    ; выключить сирену
559
    call air_raid_warning_off
560
  clc_end:
561
 
562
    pop  edx
563
    pop  ecx
564
    pop  ebx
565
    pop  eax
566
 
567
    ret
568
 
569
 
570
draw_plane_health:
571
 
572
   mov	ebx, 5*0x00010000 + 100
573
   mov	ecx, 5*0x00010000 + 10
574
   mov	edx, 0x00000000
575
   mov	eax, 13
576
   int	0x40
577
 
578
   mov	ebx, [_plane_health]
579
   add	ebx, 5*0x00010000
580
   mov	edx, 0x00008000
581
   int	0x40
582
 
583
   ret
584
 
585
 
586
air_raid_warning_on:
587
   push eax
588
   cmp	[_flag_air_raid_warning], 1
589
   je	.end
590
   mov	[_flag_air_raid_warning], 1
591
   cmp	[_flag_bomberdatabin_ok], 1
592
   jne	@f
593
   stdcall  ssmix_playtrack, [_array_sounds+8*((( 5 ))-1)], [_array_sounds+8*((( 5 ))-1)+4], VOLUME_ARW, VOLUME_ARW, SSMIX_CHANMODE_REPEAT
594
 @@:
595
   mov	[_channel_sound_arw], eax
596
 .end:
597
   pop	eax
598
   ret
599
 
600
 
601
air_raid_warning_off:
602
   cmp	[_flag_air_raid_warning], 0
603
   je	.end
604
   mov	[_flag_air_raid_warning], 0
605
   cmp	[_flag_bomberdatabin_ok], 1
606
   jne	.end
607
   stdcall  ssmix_stoptrack, [_channel_sound_arw]
608
 .end:
609
   ret
610
 
611
 
612
;======================================= САМОЛЕТ ======================================
613
 
614
 
615
flight_control_plane:  ; процедура управления полетом самолета
616
 
617
    mov  eax,[_X_plane]
618
    add  eax, [_VX_plane]
619
    mov  [_X_plane], eax
620
 
621
    cmp  eax, WINDOW_WIDTH-60-32
622
    jl	 fcp_set_utunr_rl
623
    mov  ebx, [_plane_state]
624
    cmp  ebx, 0
625
    jne  fcp_set_utunr_rl
626
    mov  [_plane_state],2
627
    mov  [_plane_state_step], 0
628
  fcp_set_utunr_rl:
629
 
630
    cmp  eax, 60
631
    jg	 fcp_set_utunr_lr
632
    mov  ebx, [_plane_state]
633
    cmp  ebx, 1
634
    jne  fcp_set_utunr_lr
635
    mov  [_plane_state],3
636
    mov  [_plane_state_step], 0
637
  fcp_set_utunr_lr:
638
 
639
  ; далее код выполняется в 2 раза медленней
640
    mov eax, [_timer_x2]
641
    cmp eax, 0
642
    jne fcp_timex2_end
643
 
644
    mov  eax, [_plane_state]
645
    cmp  eax, 2 		   ; если делаем разворот налево
646
    jne  fcp_uturn_rl_end
647
    mov  eax, [_plane_state_step]
648
    mov  ebx, 4
649
    sub  ebx, eax
650
    mov  [_VX_plane], ebx	    ; то расчитываем скорость исходя из текущего шага состояния
651
    inc  eax			    ; переходим на следующий шаг состояния
652
    mov  [_plane_state_step], eax
653
    cmp  eax, 9 		    ; проверяем, закончились ли шаги
654
    jne  fcp_uturn_rl_end
655
    mov  [_plane_state], 1	    ; если да то переводим состояние на прямой полет
656
  fcp_uturn_rl_end:
657
 
658
 
659
    mov  eax, [_plane_state]
660
    cmp  eax, 3 		   ; если делаем разворот направо
661
    jne  fcp_uturn_lr_end
662
    mov  eax, [_plane_state_step]
663
    mov  ebx, -4
664
    add  ebx, eax
665
    mov  [_VX_plane], ebx	    ; то расчитываем скорость исходя из текущего шага состояния
666
    inc  eax			    ; переходим на следующий шаг состояния
667
    mov  [_plane_state_step], eax
668
    cmp  eax, 9 		    ; проверяем, закончились ли шаги
669
    jne  fcp_uturn_lr_end
670
    mov  [_plane_state], 0	    ; если да то переводим состояние на прямой полет
671
  fcp_uturn_lr_end:
672
 
673
    mov  eax, [_plane_state]
674
    cmp  eax, 4 		    ; если делаем бочку вправо
675
    jne  fcp_barrel_r_end
676
    mov  eax, [_plane_state_step]
677
    inc  eax			    ; переходим на следующий шаг состояния
678
    mov  [_plane_state_step], eax
679
    cmp  eax, 8 		    ; проверяем, закончились ли шаги
680
    jne  fcp_barrel_r_end
681
    mov  [_plane_state], 0	    ; если да то переводим состояние на прямой полет
682
  fcp_barrel_r_end :
683
 
684
    mov  eax, [_plane_state]
685
    cmp  eax, 5 		    ; если делаем бочку влево
686
    jne  fcp_barrel_l_end
687
    mov  eax, [_plane_state_step]
688
    inc  eax			    ; переходим на следующий шаг состояния
689
    mov  [_plane_state_step], eax
690
    cmp  eax, 8 		    ; проверяем, закончились ли шаги
691
    jne  fcp_barrel_l_end
692
    mov  [_plane_state], 1	    ; если да то переводим состояние на прямой полет
693
  fcp_barrel_l_end:
694
 
695
    call animation_plane
696
 
697
  fcp_timex2_end:
698
 
699
    ; далее код выполняется в 4 раза медленней
700
    mov eax, [_timer_x4]
701
    cmp eax, 0
702
    jne fcp_timex4_end
703
 
704
    ; медленное снижение самолета
705
    mov  eax,[_Y_plane]
706
    add  eax, 1
707
    mov  [_Y_plane], eax
708
 
709
  fcp_timex4_end:
710
 
711
    ; быстрое снижение самолета
712
 
713
    mov  eax,[_Y_plane]
714
    mov  ebx,[_addit_VY_plane]
715
    add  eax, ebx
716
    mov  [_Y_plane], eax
717
 
718
    ; контроль высоты самолета, посадка
719
    mov  eax,[_Y_plane]
720
    cmp  eax,  WINDOW_HEIGHT - GROUNG_HEIGHT - 32
721
    jl	 fcp_end_plane_landing
722
    mov  [_addit_VY_plane], 0	  ; прекратить быстрое снижение
723
    mov  ebx, [_plane_state]
724
    cmp  ebx, 6
725
    je	fcp_end_plane_landing
726
    cmp  ebx, 0
727
    jne  fcp_horiz_fly
728
    mov  [_plane_state], 6	  ; режим посадки
729
    ;jmp  fcp_end_plane_landing
730
  fcp_horiz_fly:
731
    mov  eax,  WINDOW_HEIGHT - GROUNG_HEIGHT - 32
732
  fcp_end_plane_landing:
733
    cmp  eax, WINDOW_HEIGHT - GROUNG_HEIGHT - 32 + 6
734
    jle  fcp_no_plane_underground	  ; проверка на то, чтобы самолет не ушел "под землю"
735
    mov  eax, WINDOW_HEIGHT - GROUNG_HEIGHT - 32 + 6
736
    mov  ebx, [_X_plane]
737
    cmp  ebx, WINDOW_WIDTH - 60-32
738
    jl	 fcp_no_end_level		    ; проверка на то, что докатился до конца посадочной полосы
739
    ; завершение уровня
740
    call  next_level			     ; переход на следующий уровень
741
  fcp_no_end_level:
742
  fcp_no_plane_underground:
743
    mov  [_Y_plane], eax
744
 
745
    ret
746
 
747
 
748
 
749
animation_plane:
750
 
751
    ; анимация самолета
752
 
753
    ; полет вправо
754
    mov  eax, [_plane_state]
755
    cmp  eax, 0
756
    jne  ap_state0_end
757
    mov  [_anim_pos_plane], 0
758
  ap_state0_end:
759
 
760
    ; полет влево
761
    mov  eax, [_plane_state]
762
    cmp  eax, 1
763
    jne  ap_state1_end
764
    mov  [_anim_pos_plane], 8
765
  ap_state1_end:
766
 
767
    ; анимация для разворотов и бочек
768
    mov  eax, [_plane_state]
769
    cmp  eax, 5
770
    ja	 ap_state2345_end
771
    cmp  eax, 2
772
    jb	 ap_state2345_end
773
    sub  eax, 2
774
    mov  ebx, eax	   ; умножить eax на 9
775
    shl  eax, 3
776
    add  eax, ebx
777
    add  eax, [_plane_state_step]    ; прибавить номер шага
778
    shl  eax, 2 		     ; умножить на 4
779
    add  eax, _anim_array_uturn_rl   ; получается смещение для номера требуемого кадра
780
    mov  ebx, [eax]
781
    mov  [_anim_pos_plane], ebx      ; здесь вытаскиваем сам номер
782
  ap_state2345_end:
783
 
784
    ; посадка (только вправо)
785
    mov  eax, [_plane_state]
786
    cmp  eax, 6
787
    jne  ap_state6_end
788
    mov  [_anim_pos_plane], 22
789
  ap_state6_end:
790
 
791
     ret
792
 
793
 
794
 
795
draw_plane:
796
 
797
    ; стереть предыдущее изображение
798
    mov  eax, 13
799
    mov  ebx,[_last_XY_plane]
800
    and  ebx, 0xffff0000
801
    add  ebx, 32
802
    mov  ecx,[_last_XY_plane]
803
    shl  ecx, 16
804
    add  ecx, 32
805
    mov  edx, BACK_COLOR
806
    int  0x40
807
 
808
    ; расчет адреса картинки исходя из номера кадра _anim_pos_plane
809
    mov  ebx, [_anim_pos_plane]
810
    shl  ebx, 10
811
    mov  eax, ebx
812
    add  ebx, eax
813
    add  ebx, eax
814
    add  ebx, bmp_plane
815
 
816
    ; подготовка координат
817
    mov  edx,[_X_plane]
818
    shl  edx, 16
819
    add  edx,[_Y_plane]
820
    mov  [_last_XY_plane], edx
821
 
822
    ; вывод картинки
823
    mov  eax,7
824
    mov  ecx,32*65536+32
825
    int  0x40
826
 
827
    ret
828
 
829
 
830
plane_interaction:
831
 
832
    push  eax
833
    push  ebx
834
    push  ecx
835
    push  edx
836
 
837
    mov   eax, [_X_plane]
838
    mov   ebx, [_Y_plane]
839
    add   ebx, 16
840
    mov   ecx, [_VX_plane]
841
    cmp   ecx, 0
842
    jl	  pi_no_positive_vx
843
    add   eax, 32		; здесь в зависимости от направления полета определяем точку взаимодействия с городом
844
   pi_no_positive_vx:
845
    ; теперь в eax и ebx координаты X,Y  точки взаимодействия самолета с городом
846
    mov   edx, eax
847
    sub   eax, CITY_OFFSET
848
    ; проверка на вылет за пределы города
849
    cmp   eax, 0
850
    jl	  pi_out_of_city
851
    cmp   eax, 32*20
852
    jg	  pi_out_of_city
853
    ; проверка на взаимодействие с городом
854
    add   eax, 10	 ; делим координату X на 20
855
    mov   ecx, eax
856
    shr   eax, 4
857
    shr   ecx, 6
858
    sub   eax, ecx
859
    shr   ecx, 2
860
    add   eax, ecx
861
    shr   ecx, 2
862
    sub   eax, ecx
863
    dec   eax	      ; в eax номер столбца города по которому летит бомба
864
    mov   esi, eax
865
    shl   esi, 1
866
    add   esi, _city	; в esi указатель на высоту постройки в данном столбце
867
    mov   eax, edx
868
    ; теперь сравним координату Y вершины постройки с координатой Y точки взаимодействия самолета
869
    xor   ecx, ecx
870
    mov   cx, [esi]
871
    mov   edx, ecx
872
    shl   ecx, 4
873
    shl   edx, 2
874
    add   ecx, edx
875
    mov   edx, WINDOW_HEIGHT - GROUNG_HEIGHT
876
    sub   edx, ecx	       ; в edx координата Y вершины постройки
877
    cmp   ebx, edx
878
    jl	  pi_no_crash
879
    ; если столкновение произошло
880
    mov   [_plane_health], 0
881
    call  bang_add	    ; делаем взрыв
882
    call  game_over	    ; завершение игры
883
  pi_no_crash:
884
 
885
  pi_out_of_city:
886
 
887
    pop   edx
888
    pop   ecx
889
    pop   ebx
890
    pop   eax
891
 
892
    ret
893
 
894
 
895
; ================================== БОМБЫ ===========================================
896
 
897
bomb_drop:	    ; процедура "бросания бомбы". создает новую бомбу, задает для нее начальные параметры.
898
    ; проверка на здоровье самолета
899
    mov  eax, [_plane_health]
900
    cmp  eax, 0
901
    jle  bomb_drop_end
902
    ; проверить на допустимые состояния самолета (нельзя во время бочки)
903
    mov  eax, [_plane_state]
904
    cmp  eax, 3
905
    ja	 bomb_drop_end
906
    ; проверить выдержан ли интервал времени между бросками
907
    mov  eax, [_bomb_delay_time]
908
    cmp  eax, 0
909
    jne  bomb_drop_end
910
    mov  [_bomb_delay_time], BOMB_DELAY
911
    ; собственно, бросаем бомбу
912
    mov  eax, [_bomb_count]
913
    cmp  eax, MAX_BOMBS-1
914
    jae  bomb_drop_end
915
    inc  eax
916
    mov  [_bomb_count], eax
917
    dec  eax
918
    shl  eax, 4
919
    add  eax, _bomb_array    ; здесь в еах получили указатель на начало данных о бомбе
920
 
921
    mov  ebx, [_X_plane]
922
    mov  [eax], ebx	       ; задание координаты X
923
    add  eax, 4
924
    mov  ebx, [_Y_plane]
925
    add  ebx, 30
926
    mov  [eax], ebx	       ; задание координаты Y
927
 
928
    add  eax, 4
929
    mov  ebx, [_VX_plane]
930
    cmp  ebx, 0
931
    jge  bomb_drop_pos_dir_vx
932
  bomb_drop_neg_dir_vx:
933
    neg  ebx
934
    shr  ebx, 1
935
    neg  ebx
936
    jmp  bomb_drop_dir_vx_end
937
  bomb_drop_pos_dir_vx:
938
    shr  ebx, 1
939
  bomb_drop_dir_vx_end:
940
    mov  [eax], ebx	       ; задание вектора скорости по X
941
 
942
    add  eax, 4
943
    mov  ebx, 0
944
    mov  [eax], ebx	       ; задание вектора скорости по Y
945
 
946
    push  ecx
947
    mov   ecx, [_bomb_count]
948
    dec   ecx
949
    call  bombfly_sound_start
950
    pop   ecx
951
 
952
  bomb_drop_end:
953
 
954
    ret
955
 
956
 
957
bomb_proc:
958
    ; таймер интервала между бросаниями бомб
959
    mov  eax, [_bomb_delay_time]
960
    cmp  eax, 0
961
    je	 bomb_proc_delay_timer_end
962
    dec  eax
963
    mov  [_bomb_delay_time], eax
964
  bomb_proc_delay_timer_end:
965
    ; обработка движения бомб
966
    mov  eax, [_bomb_count]
967
    cmp  eax, 0
968
    je	 bomb_proc_end
969
    xor  ecx, ecx
970
  bomb_proc_loop:		 ; цикл обработки падения бомб
971
    cmp  ecx, [_bomb_count]
972
    jae  bomb_proc_end
973
    mov  ebx, ecx
974
    shl  ebx, 4
975
    add  ebx,  _bomb_array	    ;  получили указатель на начало данных о бомбе
976
 
977
    call bomb_hide   ; стереть предыдущее значение
978
 
979
    ; обработка
980
 
981
    ; выполняется пересчет для скорости VY текущей бомбы
982
 
983
    add  ebx, 4*3
984
    mov  eax, [_timer_x2]
985
    cmp  eax, 0
986
    jne  bomb_proc_gravity_accel_end
987
    mov  eax, [ebx]
988
    add  eax, GRAVY_ACCEL
989
    mov  [ebx], eax
990
  bomb_proc_gravity_accel_end:
991
    ; выполняется пересчет для координат X текущей бомбы
992
    sub  ebx, 4*3
993
    mov  eax, [ebx]
994
    add  ebx, 4*2
995
    mov  edx, [ebx]
996
    add  eax, edx
997
    sub  ebx, 4*2
998
    mov  [ebx], eax
999
    push eax
1000
    ; выполняется пересчет для координат Y текущей бомбы
1001
    add  ebx, 4
1002
    mov  eax, [ebx]
1003
    add  ebx, 4*2
1004
    mov  edx, [ebx]
1005
    add  eax, edx
1006
    sub  ebx, 4*2
1007
    mov  [ebx], eax
1008
    push eax
1009
 
1010
    ; взаимодействие бомб с миром
1011
    sub  ebx, 4
1012
    pop  edx	  ; координата Y
1013
    pop  eax	  ; координата X
1014
    ; проверка на выход бомб за пределы игровой зоны, бомбы просто удаляются при вылете за границы
1015
    cmp  eax, 10
1016
    jle   bomb_proc_delete_bomb
1017
    cmp  eax, WINDOW_WIDTH - 36
1018
    jge   bomb_proc_delete_bomb
1019
    ; проверка на взаимодейтсвие с миром
1020
    push  eax
1021
    push  ebx
1022
    mov  ebx, edx
1023
    call  bomb_check_detonation
1024
    cmp   eax, 1
1025
    pop   ebx
1026
    pop   eax
1027
    je	bomb_proc_interaction_with_world
1028
    cmp  edx, WINDOW_HEIGHT - GROUNG_HEIGHT
1029
    jae  bomb_proc_interaction_with_world
1030
    jmp   bomb_proc_interaction_end
1031
  bomb_proc_interaction_with_world:
1032
    push  eax
1033
    push  ebx
1034
    mov  ebx, edx
1035
    call bang_add
1036
    call air_raid_warning_on   ; включение воздушной тревоги
1037
    pop   ebx
1038
    pop   eax
1039
  bomb_proc_delete_bomb:
1040
    call bomb_delete	      ; удаляем бомбу
1041
    dec  ecx		      ; т.к. бомбы удалена - остаемся на том же номере бомбы
1042
    mov  eax, [_bomb_count]
1043
    dec  eax
1044
    mov  [_bomb_count], eax   ; уменьшаем количество бомб
1045
    jmp  bomb_proc_draw_end   ; не рисуем бомбу если удалили ее
1046
  bomb_proc_interaction_end:
1047
    call bomb_draw
1048
  bomb_proc_draw_end:
1049
 
1050
    inc  ecx
1051
    jmp  bomb_proc_loop
1052
  bomb_proc_end:
1053
 
1054
    ret
1055
 
1056
 
1057
bomb_delete:	   ; удаление данных о бомбе, в есх номер удаляемой бомбы
1058
    push eax
1059
    push ebx
1060
    push ecx
1061
    push edx
1062
    call  bombfly_sound_stop
1063
    inc  ecx
1064
  bomb_delete_loop:
1065
    cmp  ecx, [_bomb_count]
1066
    jae  bomb_delete_loop_end
1067
    mov  ebx, ecx
1068
    shl  ebx, 4
1069
    add  ebx,  _bomb_array	    ;  получили указатель на начало данных о бомбе
1070
    dec  ecx
1071
    mov  edx, ecx
1072
    shl  edx, 4
1073
    add  edx,  _bomb_array	    ;  получили указатель на начало данных о следующей бомбе
1074
    inc  ecx
1075
    ; перемещение данных о следующей бомбе на место предыдущей
1076
    mov  eax, [ebx]
1077
    mov  [edx], eax
1078
    add  ebx,4
1079
    add  edx,4
1080
    mov  eax, [ebx]
1081
    mov  [edx], eax
1082
    add  ebx,4
1083
    add  edx,4
1084
    mov  eax, [ebx]
1085
    mov  [edx], eax
1086
    add  ebx,4
1087
    add  edx,4
1088
    mov  eax, [ebx]
1089
    mov  [edx], eax
1090
    ; переход к следующей бомбе
1091
    inc  ecx
1092
    jmp  bomb_delete_loop
1093
  bomb_delete_loop_end:
1094
    pop  edx
1095
    pop  ecx
1096
    pop  ebx
1097
    pop  eax
1098
 
1099
    ret
1100
 
1101
bomb_hide:  ; стереть бомбу с экрана, ebx - указатель на начало данных о бомбе
1102
 
1103
    push eax
1104
    push ebx
1105
    push ecx
1106
    push edx
1107
    mov  eax, 13
1108
    mov  edx, ebx
1109
    mov  ebx, [edx]
1110
    shl  ebx, 16
1111
    add  ebx, 16
1112
    add  edx, 4
1113
    mov  ecx, [edx]
1114
    shl  ecx, 16
1115
    add  ecx, 16
1116
    mov  edx, BACK_COLOR
1117
    int  0x40
1118
    pop  edx
1119
    pop  ecx
1120
    pop  ebx
1121
    pop  eax
1122
 
1123
    ret
1124
 
1125
 
1126
bomb_draw:	; отрисовать бомбу, ebx - указатель на начало данных о бомбе
1127
 
1128
    push eax
1129
    push ebx
1130
    push ecx
1131
    push edx
1132
 
1133
    ; получение в edx координат бомбы
1134
    mov  edx, [ebx]
1135
    shl  edx, 16
1136
    add  ebx, 4
1137
    mov  eax, [ebx]
1138
    add  edx, eax
1139
 
1140
    ; получение указателя на картинку бомбы в ebx (сразу с выбором нужной картинки)
1141
    add  ebx, 4
1142
    mov  eax, [ebx]	  ; здесь в eax - горизонтальная скорость бомбы
1143
    add  ebx, 4
1144
    mov  ecx, [ebx]	  ; здесь в ecx - вертикальная скорость бомбы
1145
    xor  ebx, ebx
1146
    cmp  ecx, 3
1147
    jl	 bomb_draw_midspeed_end
1148
    inc  ebx
1149
  bomb_draw_midspeed_end:
1150
    cmp  ecx, 9
1151
    jl	 bomb_draw_highspeed_end
1152
    inc  ebx
1153
  bomb_draw_highspeed_end:
1154
    cmp  eax, 0
1155
    jge  bomb_draw_left_dir_end
1156
    add  ebx, 3
1157
  bomb_draw_left_dir_end:
1158
       ; теперь в ebx номер картинки бомбы
1159
    shl  ebx, 8
1160
    mov  eax, ebx
1161
    add  ebx, eax
1162
    add  ebx, eax
1163
    add  ebx, bmp_bomb	 ; теперь в ebx указатель на картинку бомбы
1164
 
1165
    ; вывод картинки
1166
    mov  eax,7
1167
    mov  ecx,16*65536+16
1168
    int  0x40
1169
 
1170
    pop  edx
1171
    pop  ecx
1172
    pop  ebx
1173
    pop  eax
1174
 
1175
    ret
1176
 
1177
 
1178
; взаимодействие бомб с миром
1179
 
1180
bomb_check_detonation:	       ; проверить бомбу с координатами: eax - координата X, eab - координата Y
1181
			       ; и при необходимости провести нужные разрушения (или пустой взрыв)
1182
			       ; в eax вернуть результат события: 0 - ничего не произшло, 1 - произошел взрыв
1183
			       ; (корявая реализация)
1184
 
1185
    push  ecx
1186
    push  edx
1187
 
1188
    add   eax, 8
1189
    add   ebx, 8
1190
 
1191
    sub   eax, CITY_OFFSET
1192
    ; проверка на вылет за пределы города
1193
    cmp   eax, 0
1194
    jl	  bcd_out_of_city
1195
    cmp   eax, 32*20
1196
    jg	  bcd_out_of_city
1197
    ; проверка на взаимодействие с городом
1198
    add   eax, 10	 ; делим координату X на 20
1199
    mov   ecx, eax
1200
    shr   eax, 4
1201
    shr   ecx, 6
1202
    sub   eax, ecx
1203
    shr   ecx, 2
1204
    add   eax, ecx
1205
    shr   ecx, 2
1206
    sub   eax, ecx
1207
    dec   eax	      ; в eax номер столбца города по которому летит бомба
1208
    mov   esi, eax
1209
    shl   esi, 1
1210
    add   esi, _city	; в esi указатель на высоту постройки в данном столбце
1211
 
1212
    mov   edx, WINDOW_HEIGHT - GROUNG_HEIGHT
1213
    sub   edx, ebx
1214
    mov   ebx, edx
1215
    cmp   ebx, 0
1216
    jg	  bcd_no_neg_value_Y
1217
    xor   ecx, ecx
1218
    mov   cx, [esi]
1219
    xor   ebx, ebx
1220
    jmp   bcd_damage	; наносим разрушения
1221
  bcd_no_neg_value_Y:
1222
    add   ebx, 10	  ; делим координату Y на 20
1223
    mov   ecx, ebx
1224
    shr   ebx, 4
1225
    shr   ecx, 6
1226
    sub   ebx, ecx
1227
    shr   ecx, 2
1228
    add   ebx, ecx
1229
    shr   ecx, 2
1230
    sub   ebx, ecx	   ; в ebx высота  бомбы "в плитках" над поверхностью
1231
 
1232
    xor   ecx, ecx
1233
    mov   cx, [esi]
1234
    cmp   ebx, ecx	      ; проверка на попадание в строение
1235
    jg	  bcd_no_detonation
1236
  bcd_damage:	     ; разрушения
1237
    ;разрушение столбика в который попала бомба
1238
    mov   edx, ecx
1239
    mov   ecx, ebx
1240
    sub   ecx, 2
1241
    cmp   ecx, 0	     ; просто проверка на 0, чтоб не ушло в минус
1242
    jge   bcd_no_neg_value_H
1243
    xor   ecx, ecx
1244
   bcd_no_neg_value_H:
1245
    mov   [esi], cx	    ;  возврат значения высоты столбца после взрыва
1246
    ; зачистка взорванной области
1247
    call  clear_tiles
1248
    ; проверка на попадание в зенитки
1249
    call ackack_check_bombing
1250
    ; разрушение соседнего столбика слева
1251
    ; на данный момент имеем: eax - номер центрального (центральный - это в который непосредственно попала бомба) столбика,
1252
    ; ebx - высота попадания бомбы, ecx - новая высота центрального столбика, edx - прежняя высота центрального столбика,
1253
    ; esi - указатель на значение высоты центрального столбика в массиве
1254
    dec   eax
1255
    cmp   eax, 0
1256
    jl	  bcd_damage_left_end
1257
    sub   esi, 2
1258
    xor   ecx, ecx
1259
    mov   cx, [esi]	; в ecx высота левого столбика
1260
    mov   edx, ecx
1261
    push  ecx
1262
    sub   ecx, ebx
1263
    inc   ecx
1264
    cmp   ecx, 2
1265
    pop   ecx
1266
    ja	  bcd_damage_left_end	  ; условие  |ecx-ebx|<=1
1267
    dec   ecx
1268
    cmp   ecx, 0	     ; просто проверка на 0, чтоб не ушло в минус
1269
    jge   bcd_no_neg_value_HL
1270
    xor   ecx, ecx
1271
   bcd_no_neg_value_HL:
1272
    mov   [esi], cx
1273
    call  clear_tiles
1274
    ; проверка на попадание в зенитки
1275
    call ackack_check_bombing
1276
  bcd_damage_left_end:
1277
 
1278
    ; разрушение соседнего столбика справа
1279
    ; на данный момент имеем: eax - номер левого  столбика,
1280
    ; ebx - высота попадания бомбы, ecx - новая высота левого столбика, edx - прежняя высота левого столбика,
1281
    ; esi - указатель на значение высоты левого столбика в массиве
1282
    inc   eax
1283
    inc   eax
1284
    cmp   eax, 32
1285
    jge   bcd_damage_right_end
1286
    add   esi, 4
1287
    xor   ecx, ecx
1288
    mov   cx, [esi]	; в ecx высота правого столбика
1289
    mov   edx, ecx
1290
    push  ecx
1291
    sub   ecx, ebx
1292
    inc   ecx
1293
    cmp   ecx, 2
1294
    pop   ecx
1295
    ja	  bcd_damage_right_end	   ; условие  |ecx-ebx|<=1
1296
    dec   ecx
1297
    cmp   ecx, 0	     ; просто проверка на 0, чтоб не ушло в минус
1298
    jge   bcd_no_neg_value_HR
1299
    xor   ecx, ecx
1300
   bcd_no_neg_value_HR:
1301
    mov   [esi], cx
1302
    call  clear_tiles
1303
    ; проверка на попадание в зенитки
1304
    call ackack_check_bombing
1305
  bcd_damage_right_end:
1306
    call  check_level_complete
1307
  bcd_detonation:
1308
    mov   eax, 1
1309
    jmp   bcd_end
1310
  bcd_no_detonation:
1311
    mov   eax, 0
1312
    jmp   bcd_end
1313
  bcd_out_of_city:
1314
    mov   eax, 1
1315
    cmp   ebx, WINDOW_HEIGHT - GROUNG_HEIGHT
1316
    jge   bcd_end
1317
    mov   eax, 0
1318
  bcd_end:
1319
    pop   edx
1320
    pop   ecx
1321
 
1322
    ret
1323
 
1324
 
1325
bombfly_sound_start:	; ecx - номер бомбы в массиве
1326
 
1327
    push eax ebx ecx
1328
    cmp  [_flag_bomberdatabin_ok], 1
1329
    jne  @f
1330
    stdcall  ssmix_playtrack, [_array_sounds+8*((( 1 ))-1)], [_array_sounds+8*((( 1 ))-1)+4], VOLUME_BOMBFLY, VOLUME_BOMBFLY, SSMIX_CHANMODE_SINGLE_WITHOUT_RESET
1331
  @@:
1332
    mov  ebx, ecx
1333
    shl  ebx, 2
1334
    add  ebx,  _array_bombsoundchannels
1335
    mov  [ebx], eax
1336
    pop  ecx ebx eax
1337
 
1338
    ret
1339
 
1340
 
1341
bombfly_sound_stop:    ; ecx - номер бомбы в массиве
1342
 
1343
    push eax ebx ecx
1344
    mov  ebx, ecx
1345
    shl  ebx, 2
1346
    add  ebx,  _array_bombsoundchannels
1347
    mov  eax, [ebx]
1348
    cmp  [_flag_bomberdatabin_ok], 1
1349
    jne  @f
1350
    stdcall  ssmix_stoptrack, eax
1351
  @@:
1352
    inc  ecx
1353
  .delete_loop:
1354
    cmp  ecx, MAX_BOMBS
1355
    jae  .delete_loop_end
1356
    mov  ebx, ecx
1357
    shl  ebx, 2
1358
    add  ebx,  _array_bombsoundchannels
1359
    mov  eax, [ebx]
1360
    mov  [ebx-4], eax
1361
    inc  ecx
1362
    jmp  .delete_loop
1363
  .delete_loop_end:
1364
    pop  ecx ebx eax
1365
 
1366
    ret
1367
 
1368
; ==================================== ВЗРЫВЫ =======================================
1369
 
1370
 
1371
fill_circle:
1372
    ; построение заполненного круга    (алгоритм Брезенхема)
1373
    ; входные параметры:
1374
    ; eax - координата центра по X
1375
    ; ebx - координата центра по Y
1376
    ; ecx - радиус
1377
    ; edx - цвет
1378
    mov  edi, eax
1379
    mov  esi, ebx
1380
    push edx	     ; цвет в стек
1381
 
1382
    mov  eax, ecx
1383
    shl  eax, 1
1384
    mov  edx, 3
1385
    sub  edx, eax	  ; D:=3-2*R
1386
    xor  ebx, ebx   ; теперь в ebx будет коорд X, в ecx коорд Y, в edx переменная D, в eax - промежуточные данные
1387
 
1388
  fc_loop:
1389
    cmp  ebx, ecx
1390
    jg	 fc_loop_end
1391
    ; отрисовка линиями
1392
     pop  eax	    ; цвет из стека
1393
     push edx	    ; D в стек
1394
     mov  edx, eax  ; в edx - цвет
1395
     push ebx
1396
     push ecx
1397
     ; рисуем первый отрезок
1398
     mov  eax, edi
1399
     sub  eax, ebx
1400
     shl  eax, 16
1401
     add  ebx, edi
1402
     add  ebx, eax   ; получили концы отрезка по х
1403
     add  ecx, esi
1404
     mov  eax, ecx
1405
     shl  eax, 16
1406
     add  ecx, eax   ; получили концы отрезка по y
1407
     mov  eax, 38
1408
     int  0x40
1409
     pop  ecx
1410
     push ecx
1411
     ; рисуем второй отрезок
1412
     mov  eax, esi
1413
     sub  eax, ecx
1414
     mov  ecx, eax
1415
     shl  eax, 16
1416
     add  ecx, eax   ; получили концы отрезка по y
1417
     mov  eax, 38
1418
     int  0x40
1419
     pop  ecx
1420
     pop  ebx
1421
     push ecx
1422
     push ebx	; обратить внимание! порядок загрузки координат в стек поменялся!
1423
     ; рисуем третий отрезок
1424
     mov  eax, edi
1425
     sub  eax, ecx
1426
     shl  eax, 16
1427
     add  ecx, edi
1428
     add  ecx, eax
1429
     mov  eax, ebx
1430
     mov  ebx, ecx    ; получили концы отрезка по х
1431
     mov  ecx, eax    ; внимание! в ecx - координата x
1432
     add  ecx, esi
1433
     mov  eax, ecx
1434
     shl  eax, 16
1435
     add  ecx, eax   ; получили концы отрезка по y
1436
     mov  eax, 38
1437
     int  0x40
1438
     pop  ecx
1439
     push ecx
1440
     ; рисуем четвертый отрезок
1441
     mov  eax, esi
1442
     sub  eax, ecx
1443
     mov  ecx, eax
1444
     shl  eax, 16
1445
     add  ecx, eax   ; получили концы отрезка по y
1446
     mov  eax, 38
1447
     int  0x40
1448
     pop  ebx
1449
     pop  ecx
1450
 
1451
     mov  eax, edx	 ; в eax - цвет
1452
     pop  edx		 ; D из стека
1453
     push eax		 ; цвет в стек
1454
    ; переход в следующей точке
1455
    cmp  edx, 0
1456
    jge  fc_loop_D_more_0     ; если D<0
1457
  fc_loop_D_low_0:	      ; то
1458
    mov  eax, ebx
1459
    shl  eax, 2
1460
    add  edx, eax
1461
    add  edx, 4        ; D:=D+4*X+6
1462
    jmp  fc_loop_cmpD_end
1463
  fc_loop_D_more_0:	      ; иначе
1464
    mov  eax, ebx
1465
    sub  eax, ecx
1466
    shl  eax, 2
1467
    add  edx, eax
1468
    add  edx, 10      ; D:=D+4*(X-Y)+10
1469
    dec  ecx
1470
  fc_loop_cmpD_end:	      ; конец если
1471
    inc  ebx
1472
    jmp  fc_loop
1473
  fc_loop_end:
1474
 
1475
    pop  edx	   ; цвет из стека
1476
 
1477
    ret
1478
 
1479
 
1480
 
1481
 
1482
bang_add:   ; добавить взрыв от бомбы, eax - координата X, eab - координата Y
1483
 
1484
    push  eax
1485
    push  ebx
1486
    push  ecx
1487
    push  edx
1488
 
1489
    shl  eax, 16
1490
    add  eax, ebx
1491
    mov  ebx, _bang_array
1492
    xor  ecx, ecx
1493
  bang_add_loop:
1494
    cmp  ecx, MAX_BOMBS
1495
    jae  bang_add_loop_end
1496
    mov  edx, [ebx]
1497
    cmp  edx, -1
1498
    jne  bang_add_loop_freecheck_end
1499
    mov  edx,  5*65536 + 3
1500
    mov  [ebx], edx
1501
    add  ebx, 4
1502
    mov  [ebx], eax
1503
    cmp  [_flag_bomberdatabin_ok], 1
1504
    jne  @f
1505
    stdcall  ssmix_playtrack, [_array_sounds+8*((( 2 ))-1)], [_array_sounds+8*((( 2 ))-1)+4], VOLUME_BOMBBANG, VOLUME_BOMBBANG, SSMIX_CHANMODE_SINGLE
1506
  @@:
1507
    jmp  bang_add_loop_end
1508
  bang_add_loop_freecheck_end:
1509
    add  ebx, 8
1510
    inc  ecx
1511
    jmp  bang_add_loop
1512
  bang_add_loop_end:
1513
 
1514
 
1515
    pop   edx
1516
    pop   ecx
1517
    pop   ebx
1518
    pop   eax
1519
 
1520
    ret
1521
 
1522
 
1523
bang_proc:
1524
 
1525
    mov  ebx, _bang_array
1526
    xor  ecx, ecx
1527
  bang_proc_loop:
1528
    cmp  ecx, MAX_BOMBS
1529
    jae  bang_proc_loop_end
1530
    ; проверка на наличие взрыва
1531
    mov  edx, [ebx]
1532
    cmp  edx, -1
1533
    je	 bang_proc_loop_freecheck_end
1534
    ; проверка на завершение взрыва
1535
    and  edx, 0x0000FFFF
1536
    cmp  edx, 0
1537
    jne  bang_proc_loop_endcheck_end
1538
    ; здесь пишем обработку завершения взрыва
1539
    push  ebx
1540
    push  ecx
1541
    mov  ecx, [ebx]
1542
    shr  ecx, 16
1543
    add  ebx, 4
1544
    mov  eax, [ebx]
1545
    mov  ebx, eax
1546
    shr  eax, 16
1547
    and  ebx, 0x0000FFFF
1548
    mov  edx, BACK_COLOR
1549
    call fill_circle
1550
    pop   ecx
1551
    pop   ebx
1552
    mov  eax, -1
1553
    mov  [ebx], eax
1554
    jmp  bang_proc_loop_continue
1555
  bang_proc_loop_endcheck_end:
1556
    ; здесь пишем обработку взрыва
1557
    push  ebx
1558
    push  ecx
1559
    ; задаем радиус и считаем новый
1560
    mov  eax, [ebx]
1561
    mov  edx, eax
1562
    shr  eax, 16
1563
    mov  ecx, eax
1564
    and  edx, 0x0000FFFF
1565
    mov  eax, edx
1566
    shl  eax, 3
1567
    add  eax, ecx
1568
    shl  eax, 16
1569
    dec  edx
1570
    add  eax, edx
1571
    mov  [ebx], eax
1572
    ; задаем координаты
1573
    add  ebx, 4
1574
    mov  eax, [ebx]
1575
    mov  ebx, eax
1576
    shr  eax, 16
1577
    and  ebx, 0x0000FFFF
1578
    ;задаем цвет
1579
    mov  edx, BANG_COLOR
1580
    call fill_circle
1581
    pop   ecx
1582
    pop   ebx
1583
  bang_proc_loop_freecheck_end:
1584
  bang_proc_loop_continue:
1585
    add  ebx, 8
1586
    inc  ecx
1587
    jmp  bang_proc_loop
1588
  bang_proc_loop_end:
1589
 
1590
    ret
1591
 
1592
; ===================================== ЗЕНИТКИ =========================================
1593
; управление зенитками, добавление зениток, отрисовка зениток, стрельба
1594
 
1595
 
1596
ackack_draw:			   ; отрисовка зениток
1597
 
1598
    mov  ebx, _ackack
1599
    xor  ecx, ecx
1600
    xor  esi, esi	; флаг наличия хотя бы одной зенитки (действующей или в перспективе)
1601
  ackack_draw_loop:
1602
    cmp  ecx, 32
1603
    jae  ackack_draw_loop_end
1604
    xor  eax, eax
1605
    mov  ax, [ebx]
1606
    cmp  eax, 1
1607
    jne  ackack_draw_continue	   ; если значение текущей ячейки в массиве не 1 то не рисуем зенитку
1608
    push  ebx
1609
    push  ecx
1610
    ; в ebx получаем указатель на высоту постройки
1611
    mov   ebx, ecx
1612
    shl   ebx, 1
1613
    add   ebx, _city  ; получили указатель на высоту постройки
1614
    xor  eax, eax
1615
    mov  ax, [ebx]    ; получили высоту постройки
1616
    cmp   eax, 0
1617
    jle   ackack_draw_continue2      ; если постройки нет то не рисуем зенитку
1618
    mov   esi, 1
1619
    call  ackack_bullet_start
1620
    ; отрисовка зенитки
1621
    mov   ebx, bmp_ackack   ; получили указатель на картинку
1622
    cmp   edx, 0
1623
    je	  ackack_draw_no_start_bullet
1624
    add   ebx, 20*20*3	    ; картинка со треляющей зениткой
1625
  ackack_draw_no_start_bullet:
1626
    ; формирование координат картинки  в edx
1627
    mov   edx, ecx
1628
    shl   edx, 4
1629
    shl   ecx, 2
1630
    add   edx, ecx
1631
    add   edx, CITY_OFFSET
1632
    shl   edx, 16
1633
    mov   ecx, eax
1634
    shl   eax, 4
1635
    shl   ecx, 2
1636
    add   eax, ecx
1637
    mov   ecx, WINDOW_HEIGHT-GROUNG_HEIGHT
1638
    sub   ecx, eax
1639
    sub   ecx, 20  ; подняли координату на плитку выше постройки
1640
    add   edx, ecx ; получили координаты
1641
    mov   ecx, 20*0x00010000 + 20   ; задали размер картинки
1642
    mov   eax, 7
1643
    int   0x40		; выводим картинку
1644
  ackack_draw_continue2:
1645
    pop   ecx
1646
    pop   ebx
1647
  ackack_draw_continue:
1648
    add  ebx, 2
1649
    inc  ecx
1650
    jmp  ackack_draw_loop
1651
  ackack_draw_loop_end:
1652
 
1653
    cmp  esi, 0
1654
    jne  @f
1655
    ; выключить сирену
1656
    call  air_raid_warning_off
1657
  @@:
1658
 
1659
    ret
1660
 
1661
 
1662
ackack_check_bombing: ; проверка на подрыв зениток бомбами : eax - номер столбца
1663
 
1664
    push eax
1665
    push ebx
1666
    push ecx
1667
    push edx
1668
    ; проверка на попадание в столбец зенитки
1669
    mov  ebx, eax
1670
    shl  ebx, 1
1671
    push  ebx
1672
    add  ebx, _ackack
1673
    mov  edx, ebx	; запомним указатель состояния зенитки в edx
1674
    xor  eax, eax
1675
    mov  ax, [ebx]    ; в eax  получили состояние зенитки
1676
    cmp  eax, 1
1677
    jne  acb_no_bombing       ; проверка на наличие зенитки в данном столбце
1678
    xor  eax, eax
1679
    mov  [ebx], ax     ; убираем зенитку
1680
    call ackack_next_wave
1681
  acb_no_bombing:
1682
    ; проверка на полное уничножение столбца
1683
    pop  ebx
1684
    add  ebx, _city
1685
    xor  eax, eax
1686
    mov  ax, [ebx]    ; в eax  получили состояние зенитки
1687
    cmp  eax, 0
1688
    jg	 acb_no_destroy_building       ; проверка на наличие постройки в столбце
1689
    xor  eax, eax
1690
    mov  [ebx], ax     ; убираем зенитку даже в перспективе
1691
  acb_no_destroy_building:
1692
    pop  edx
1693
    pop  ecx
1694
    pop  ebx
1695
    pop  eax
1696
 
1697
    ret
1698
 
1699
 
1700
 
1701
ackack_next_wave:	 ; новая волна зениток
1702
 
1703
    push eax
1704
    push ebx
1705
    push ecx
1706
    push edx
1707
 
1708
  anw_begin:
1709
    mov  ebx, _ackack
1710
    xor  ecx, ecx
1711
    xor  edx, edx	; флаг контроля за зенитками
1712
  anw_loop:
1713
    cmp  ecx, 32
1714
    jae  anw_loop_end
1715
    xor  eax, eax
1716
    mov  ax, [ebx]
1717
    cmp  eax, 1
1718
    jle  anw_continue	   ; если значение текущей ячейки <=1 то пропускаем
1719
    dec  eax
1720
    mov  [ebx], ax
1721
    cmp  eax, 1
1722
    jg	 anw_no_active_ackack	  ; если значение текущей ячейки в массиве >1 то пропускаем
1723
    mov  edx, 1        ; показываем что есть действующая зенитка
1724
    jmp  anw_continue
1725
  anw_no_active_ackack:
1726
    cmp  edx, 1
1727
    je	 anw_continue	   ; если флага 1 то пропускаем
1728
    mov  edx, 2
1729
  anw_continue:
1730
    add  ebx, 2
1731
    inc  ecx
1732
    jmp  anw_loop
1733
  anw_loop_end:
1734
    cmp  edx, 2
1735
    je	 anw_begin
1736
 
1737
    pop  edx
1738
    pop  ecx
1739
    pop  ebx
1740
    pop  eax
1741
    ret
1742
 
1743
 
1744
 
1745
 
1746
 
1747
ackack_bullet_start:	 ; запуск снарядов  (входные: eax - высота столбца, ecx - номер столбца;
1748
			 ;                   выходные: edx - флаг нового запуска (0-нет, 1 -да)
1749
 
1750
    push  eax
1751
    push  ebx
1752
    push  ecx
1753
 
1754
    cmp   [_flag_air_raid_warning], 1
1755
    jne   abs_no_start_bullet
1756
 
1757
    ; в ebx получаем указатель на положение снаряда
1758
    mov   edx, eax
1759
    mov   ebx, ecx
1760
    shl   ebx, 2
1761
    add   ebx, _ackack_bullet  ; получили указатель на положение снаряда
1762
    mov   eax, [ebx]	; получили положение снаряда
1763
    cmp   eax, 0
1764
    jne   abs_no_start_bullet	   ; если не 0, то не запускаем новый
1765
    ; запуск снаряда
1766
    mov   eax, edx    ; помещаем в eax высоту постройки
1767
    ; считаем координату вершины
1768
    mov   ecx, eax
1769
    shl   eax, 4
1770
    shl   ecx, 2
1771
    add   eax, ecx
1772
    mov   ecx, WINDOW_HEIGHT-GROUNG_HEIGHT
1773
    sub   ecx, eax
1774
    sub   ecx, 20+BULLET_SIZE  ; подняли координату на плитку выше постройки + высота снаяряда (в ecx - начальная координата снаряда)
1775
    mov   [ebx], ecx  ; задали начальную координату снаряду
1776
 
1777
    cmp  [_flag_bomberdatabin_ok], 1
1778
    jne  @f
1779
    stdcall  ssmix_playtrack, [_array_sounds+8*((( 3 ))-1)], [_array_sounds+8*((( 3 ))-1)+4], VOLUME_ACKACK,VOLUME_ACKACK , SSMIX_CHANMODE_SINGLE
1780
  @@:
1781
 
1782
    mov   edx, 1
1783
    jmp   abs_end_start_bullet
1784
  abs_no_start_bullet:
1785
    mov   edx, 0
1786
  abs_end_start_bullet:
1787
 
1788
    pop   ecx
1789
    pop   ebx
1790
    pop   eax
1791
 
1792
    ret
1793
 
1794
 
1795
ackack_bullet_proc:	; процедура обработки и отрисовки снарядов
1796
 
1797
    mov  ebx, _ackack_bullet
1798
    xor  ecx, ecx
1799
  abp_loop:
1800
    cmp  ecx, 32
1801
    jae  abp_loop_end
1802
    mov  eax, [ebx]
1803
    cmp  eax, 0
1804
    je	 abp_continue
1805
    jl	 abp_low_zero
1806
    push  ebx
1807
    push  ecx
1808
    ; стирание старого изображения
1809
    mov   ebx, ecx
1810
    shl   ebx, 4
1811
    shl   ecx, 2
1812
    add   ebx, ecx
1813
    add   ebx, CITY_OFFSET
1814
    add   ebx, 7	     ; смещение снаряда
1815
    mov   edx, ebx
1816
    shl   ebx, 16
1817
    add   ebx, edx   ; в ebx координаты начала и конца отрезка по оси X
1818
    mov   ecx, eax
1819
    mov   edx, ecx
1820
    add   edx, BULLET_SIZE   ; прибавили длину снаряда
1821
    shl   ecx, 16
1822
    add   ecx, edx   ; в ebx координаты начала и конца отрезка по оси Y
1823
    mov   edx, BACK_COLOR
1824
    mov   eax, 38
1825
    int   0x40
1826
    add   ebx, 0x00050005
1827
    int   0x40
1828
 
1829
    pop   ecx
1830
    pop   ebx
1831
    push  ebx
1832
    push  ecx
1833
 
1834
    mov  eax, [ebx]
1835
    sub  eax, ACKACK_BULLET_SPEED
1836
    mov  [ebx], eax
1837
    cmp  eax, 0
1838
    jle  abp_end_draw_bullet
1839
 
1840
    call ackack_bullet_interaction_check
1841
    cmp  edx, 0
1842
    je	 abp_no_bullet_interaction	; если не было взаимодействие то рисуем снаряды
1843
    xor  eax, eax
1844
    mov  [ebx], eax
1845
    jmp  abp_end_draw_bullet
1846
  abp_no_bullet_interaction:
1847
 
1848
    ; рисуем снаряды
1849
    mov   ebx, ecx
1850
    shl   ebx, 4
1851
    shl   ecx, 2
1852
    add   ebx, ecx
1853
    add   ebx, CITY_OFFSET
1854
    add   ebx, 7	     ; смещение снаряда
1855
    mov   edx, ebx
1856
    shl   ebx, 16
1857
    add   ebx, edx   ; в ebx координаты начала и конца отрезка по оси X
1858
    mov   ecx, eax
1859
    mov   edx, ecx
1860
    add   edx, BULLET_SIZE   ; прибавили длину снаряда
1861
    shl   ecx, 16
1862
    add   ecx, edx   ; в ebx координаты начала и конца отрезка по оси Y
1863
    mov   edx, 0x00000000
1864
    mov   eax, 38
1865
    int   0x40
1866
    add   ebx, 0x00050005
1867
    int   0x40
1868
  abp_end_draw_bullet:
1869
 
1870
    pop   ecx
1871
    pop   ebx
1872
    jmp  abp_continue
1873
  abp_low_zero:
1874
    xor  eax, eax
1875
    mov  [ebx], eax
1876
  abp_continue:
1877
    add  ebx, 4
1878
    inc  ecx
1879
    jmp  abp_loop
1880
  abp_loop_end:
1881
 
1882
    ret
1883
 
1884
 
1885
ackack_bullet_interaction_check:       ; проверка взаимодействия снарядов
1886
				       ;  (входные: eax - координата снаряда по Y, ecx - номер столбца;
1887
				       ;  выходные: edx - флаг попадания (0-нет, 1 -да))
1888
 
1889
 
1890
    push  eax
1891
    push  ebx
1892
    push  ecx
1893
 
1894
    ; если самолет делает бочку то пропускаем
1895
    mov   ebx, [_plane_health]
1896
    cmp   ebx, 0
1897
    jle   abic_with_plane_no
1898
    mov   ebx, [_plane_state]
1899
    cmp   ebx, 4
1900
    je	  abic_with_plane_no
1901
    cmp   ebx, 5
1902
    je	  abic_with_plane_no
1903
    ; проверка на координаты
1904
    mov   ebx, [_Y_plane]
1905
    cmp   eax, ebx
1906
    jl	  abic_with_plane_no	 ; если сняряд выше координаты попадяния то пропускаем
1907
    add   ebx, 20     ; в ebx - координата попадания в самолет
1908
    cmp   eax, ebx
1909
    jg	  abic_with_plane_no	 ; если сняряд ниже координаты попадяния то пропускаем
1910
    ; считаем координату X вершины
1911
    mov   edx, ecx
1912
    shl   edx, 4
1913
    shl   ecx, 2
1914
    add   ecx, edx
1915
    add   ecx, CITY_OFFSET
1916
    add   ecx, 7    ; в ecx - координата X левого снаряда
1917
    mov   ebx, [_X_plane]
1918
    add   ebx, 32
1919
    cmp   ecx, ebx
1920
    jg	  abic_with_plane_no
1921
    mov   ebx, [_X_plane]
1922
    add   ecx, 5
1923
    cmp   ecx, ebx
1924
    jl	  abic_with_plane_no
1925
    ; есть попадание!!!
1926
    mov   ebx, [_plane_health]
1927
    sub   ebx, 20
1928
    mov   [_plane_health], ebx
1929
    cmp   ebx, 0		; проверка на game over
1930
    jg	  abic_no_plane_crash
1931
    mov   [_plane_health], 0
1932
    mov   eax, [_X_plane]
1933
    mov   ebx, [_Y_plane]
1934
    call  bang_add	    ; делаем взрыв
1935
    call  game_over	    ; завершение игры
1936
  abic_no_plane_crash:
1937
    mov   edx, 1
1938
    jmp   abic_with_plane_end
1939
  abic_with_plane_no:
1940
    mov   edx, 0
1941
  abic_with_plane_end:
1942
 
1943
    pop   ecx
1944
    pop   ebx
1945
    pop   eax
1946
    ret
1947
 
1948
; ===================================== МИР =========================================
1949
 
1950
ground_draw:
1951
 
1952
    mov  eax, 13
1953
    mov  ebx, 0*0x00010000 + (WINDOW_WIDTH-10)
1954
    mov  ecx, (WINDOW_HEIGHT-GROUNG_HEIGHT)*0x00010000 + (GROUNG_HEIGHT-5-20)
1955
    mov  edx, GROUND_COLOR
1956
    int  0x40
1957
 
1958
    mov  eax, 38
1959
    mov  ebx, 0*0x00010000 + (WINDOW_WIDTH-10)
1960
    mov  ecx, (WINDOW_HEIGHT-GROUNG_HEIGHT)*0x00010000 + (WINDOW_HEIGHT-GROUNG_HEIGHT)
1961
    mov  edx, 0x000000
1962
    int  0x40
1963
 
1964
    ret
1965
 
1966
 
1967
city_draw:	      ; отрисовка города
1968
 
1969
    mov  ebx, _city
1970
    xor  edx, edx
1971
  city_draw_loop:
1972
    cmp  edx, 32
1973
    jae  city_draw_loop_end
1974
    xor  eax, eax
1975
    mov  ax, [ebx]
1976
    push  ebx
1977
    push  edx
1978
    mov   ebx, bmp_tile
1979
  city_draw_loop2:
1980
    cmp  eax, 0
1981
    jle  city_draw_loop2_end
1982
    push  eax
1983
    push  edx
1984
    ; формирование координат картинки в edx
1985
    mov   ecx, edx
1986
    shl   edx, 4
1987
    shl   ecx, 2
1988
    add   edx, ecx
1989
    add   edx, CITY_OFFSET
1990
    shl   edx, 16
1991
    mov   ecx, eax
1992
    shl   eax, 4
1993
    shl   ecx, 2
1994
    add   eax, ecx
1995
    mov   ecx, WINDOW_HEIGHT-GROUNG_HEIGHT
1996
    sub   ecx, eax
1997
    add   edx, ecx ; получили координаты
1998
    mov   ecx, 20*0x00010000 + 20   ; задали размер картинки
1999
    mov   eax, 7
2000
    int   0x40		; выводим картинку
2001
    pop   edx
2002
    pop   eax
2003
    dec  eax
2004
    jmp  city_draw_loop2
2005
  city_draw_loop2_end:
2006
 
2007
    pop   edx
2008
    pop   ebx
2009
    add  ebx, 2
2010
    inc  edx
2011
    jmp  city_draw_loop
2012
  city_draw_loop_end:
2013
 
2014
    ret
2015
 
2016
 
2017
clear_tiles:	   ; зачистка взорванных плиток: eax - номер столбца, ecx - нижняя плитка из удаляемых, edx - верхняя плитка из удаляемых
2018
 
2019
    push eax
2020
    push ebx
2021
    push ecx
2022
    push edx
2023
    ; формирование координаты X угла прямоугольника
2024
    mov  ebx, eax
2025
    shl  eax, 4
2026
    shl  ebx, 2
2027
    add  eax, ebx
2028
    add  eax, CITY_OFFSET
2029
    ;  формирование координаты Y1 нижнего края нижней плитки
2030
    mov  ebx, ecx
2031
    shl  ecx, 4
2032
    shl  ebx, 2
2033
    add  ecx, ebx
2034
    mov  ebx, WINDOW_HEIGHT-GROUNG_HEIGHT
2035
    sub  ebx, ecx
2036
    mov  ecx, ebx
2037
    add  ecx, 20
2038
    ; формирование координаты Y2 верхнего края верхней плитки
2039
    mov  ebx, edx
2040
    shl  edx, 4
2041
    shl  ebx, 2
2042
    add  edx, ebx
2043
    mov  ebx, WINDOW_HEIGHT-GROUNG_HEIGHT
2044
    sub  ebx, edx
2045
    mov  edx, ebx
2046
    sub  edx, 20   ; чтоб и зенитки стирать, если они есть
2047
    ; задание координаты прямоугольника по Y=Y2 и его высоты H=Y1-Y2
2048
    sub  ecx, edx
2049
    shl  edx, 16
2050
    add  ecx, edx
2051
    ; задание координаты прямоугольника по X и его ширины 20
2052
    shl  eax, 16
2053
    add  eax, 20
2054
    mov  ebx, eax
2055
    ; отрисовка прямоугольника цвета фона
2056
    mov  eax, 13
2057
    mov  edx, BACK_COLOR
2058
    int  0x40
2059
 
2060
    pop  edx
2061
    pop  ecx
2062
    pop  ebx
2063
    pop  eax
2064
 
2065
    ret
2066
 
2067
 
2068
load_level:	   ; загрузка уровня, в eax номер загружаемого уровня
2069
 
2070
    mov  eax, [_level_num]
2071
    dec  eax
2072
    shl  eax, 7 	    ; умножить на размер данных для одного уровня (128 байт)
2073
    mov  ebx, levels
2074
    add  ebx, eax	    ; в ebx указатель на начало загружаемого уровня
2075
    mov  edx, cur_level
2076
    mov  ecx, 0
2077
  load_level_loop:
2078
    cmp  ecx, 128/4
2079
    jae  load_level_loop_end
2080
    mov  eax, [ebx]
2081
    mov  [edx], eax
2082
    add  ebx, 4
2083
    add  edx, 4
2084
    inc  ecx
2085
    jmp  load_level_loop
2086
  load_level_loop_end:
2087
 
2088
  load_level_end:
2089
 
2090
    ret
2091
 
2092
; =================================== РАЗНОЕ ========================================
2093
 
2094
timer_x4:
2095
    mov  eax, [_timer_x4]
2096
    inc  eax
2097
    mov  [_timer_x4],eax
2098
    cmp  eax, 4
2099
    ja	 timer_x4_do
2100
    jmp  timer_x4_end
2101
  timer_x4_do:
2102
    mov  [_timer_x4],0
2103
  timer_x4_end:
2104
    ret
2105
 
2106
 
2107
timer_x2:
2108
    mov  eax, [_timer_x2]
2109
    inc  eax
2110
    mov  [_timer_x2],eax
2111
    cmp  eax, 2
2112
    ja	 timer_x2_do
2113
    jmp  timer_x2_end
2114
  timer_x2_do:
2115
    mov  [_timer_x2],0
2116
  timer_x2_end:
2117
    ret
2118
 
2119
draw_window:			     ; отрисовка окна
2120
 
2121
    mov  eax,12
2122
    mov  ebx,1
2123
    int  0x40
2124
 
2125
    mov  eax,0
2126
    mov  ebx,100*65536+WINDOW_WIDTH
2127
    mov  ecx,100*65536+WINDOW_HEIGHT
2128
    mov  edx,0x34000000+BACK_COLOR
2129
    mov  edi,_window_caption
2130
    int  0x40
2131
 
2132
    mov  eax,12
2133
    mov  ebx,2
2134
    int  0x40
2135
 
2136
    ret
2137
 
2138
 
2139
 
2140
draw_intro:
2141
 
2142
    ;заголовок
2143
    mov  eax,4
2144
    mov  ebx,(WINDOW_WIDTH/2-80)*65536 + 60
2145
    mov  ecx,0x80000000
2146
    mov  edx,_text_intro_title
2147
    int  0x40
2148
 
2149
    ;описание игры
2150
    mov  eax,4
2151
    mov  ebx,(WINDOW_WIDTH/2-200)*65536 + 120
2152
    mov  ecx,0x80000000
2153
    mov  edx,_text_intro_description1
2154
    int  0x40
2155
 
2156
 
2157
    ;клавиши управления
2158
    mov  eax,4
2159
    mov  ebx,(WINDOW_WIDTH/2-60)*65536 + 200
2160
    mov  ecx,0x80000000
2161
    mov  edx,_text_intro_key_controls
2162
    int  0x40
2163
 
2164
    mov  eax,4
2165
    mov  ebx,(WINDOW_WIDTH/2-70)*65536 + 230
2166
    mov  ecx,0x80000000
2167
    mov  edx,_text_intro_key_ctrl
2168
    int  0x40
2169
 
2170
    mov  eax,4
2171
    mov  ebx,(WINDOW_WIDTH/2-70)*65536 + 245
2172
    mov  ecx,0x80000000
2173
    mov  edx,_text_intro_key_space
2174
    int  0x40
2175
 
2176
    ; выбор уровня
2177
 
2178
    mov  eax,4
2179
    mov  ebx,(WINDOW_WIDTH/2-175)*65536 + 300
2180
    mov  ecx,0x80000000
2181
    mov  edx,_text_intro_select_level
2182
    int  0x40
2183
 
2184
    mov  eax,4
2185
    mov  ebx,(WINDOW_WIDTH/2-25)*65536 + 320
2186
    mov  ecx,0x80000000
2187
    mov  edx,_text_intro_level_num
2188
    int  0x40
2189
 
2190
    call draw_level_num
2191
 
2192
    ; установка громкости
2193
 
2194
    mov  eax,4
2195
    mov  ebx,(WINDOW_WIDTH/2-175)*65536 + 350
2196
    mov  ecx,0x80000000
2197
    mov  edx,_text_intro_set_volume
2198
    int  0x40
2199
 
2200
    mov  eax,4
2201
    mov  ebx,(WINDOW_WIDTH/2-25)*65536 + 370
2202
    mov  ecx,0x80000000
2203
    mov  edx,_text_intro_volume_num
2204
    int  0x40
2205
    call draw_volume_num
2206
 
2207
    ; запуск игры и выход
2208
 
2209
    mov  eax,4
2210
    mov  ebx,(WINDOW_WIDTH/2-80)*65536 + 400
2211
    mov  ecx,0x80FF0000
2212
    mov  edx,_text_intro_start_space
2213
    int  0x40
2214
 
2215
    mov  eax,4
2216
    mov  ebx,(WINDOW_WIDTH/2-30)*65536 + 460
2217
    mov  ecx,0x80000000
2218
    mov  edx,_text_intro_exit_key
2219
    int  0x40
2220
 
2221
 
2222
   ret
2223
 
2224
 
2225
draw_level_num:
2226
 
2227
    mov  eax, 13
2228
    mov  ebx, (WINDOW_WIDTH/2+25)*0x00010000 + 30
2229
    mov  ecx, 320*0x00010000 + 15
2230
    mov  edx, BACK_COLOR
2231
    int  0x40
2232
 
2233
    mov  eax, 47
2234
    mov  ebx, 0x80020000
2235
    mov  ecx, [_level_num]
2236
    mov  edx, (WINDOW_WIDTH/2+25)*65536 + 320
2237
    mov  esi,0x00000000
2238
    int  0x40
2239
 
2240
    ret
2241
 
2242
draw_volume_num:
2243
 
2244
    mov  eax, 13
7670 leency 2245
    mov  ebx, (WINDOW_WIDTH/2+35)*0x00010000 + 30
4323 yogev_ezra 2246
    mov  ecx, 370*0x00010000 + 15
2247
    mov  edx, BACK_COLOR
2248
    int  0x40
2249
 
2250
    mov  eax, 47
2251
    mov  ebx, 0x80020000
2252
    mov  ecx, [_set_volume]
7670 leency 2253
    mov  edx, (WINDOW_WIDTH/2+35)*65536 + 370
4323 yogev_ezra 2254
    mov  esi,0x00000000
2255
    int  0x40
2256
 
2257
    ret
2258
 
2259
;---------------------------------------------------------------------------
2260
;-------------------------------- данные -----------------------------------
2261
;---------------------------------------------------------------------------
2262
 
2263
_game_state dd ?
2264
_delay dd 6
2265
_timer_x2 dd ?
2266
_timer_x4 dd ?
2267
_game_over_time  dd ?
2268
_flag_air_raid_warning dd ?
2269
_flag_bomberdatabin_ok dd ?
2270
_last_value_timecount dd ?
2271
 
2272
_X_plane dd ?
2273
_Y_plane dd ?
2274
_last_XY_plane dd ?
2275
_VX_plane dd ?
2276
_addit_VY_plane dd ?
2277
_plane_state dd ?  ; 0 - полет направо, 1- полет налево, 2-разворот справа-налево, 3-разворот слева-направо, 4 - бочка вправо, 5 - бочка влево
2278
_plane_state_step dd ?	 ; номер шага текущего состояния (нужно для синхнопизации с анимацией)
2279
_plane_health dd ?   ; здоровье самолета
2280
 
2281
_bomb_count dd ?
2282
_bomb_array rd 4*MAX_BOMBS
2283
_bomb_delay_time dd ?	; задержка времени на сброс бомбы
2284
 
2285
_bang_array rd 2*MAX_BOMBS
2286
 
2287
_anim_pos_plane dd ?
2288
; последовательности картинок анимации
2289
_anim_array_uturn_rl dd 0,1,2,3,4,5,6,7,8
2290
_anim_array_uturn_lr dd 8,7,6,9,10,11,2,1,0
2291
_anim_array_barrel_r dd 0,1,2,12,13,14,15,16,0
2292
_anim_array_barrel_l dd 8,17,18,19,20,21,6,7,8
2293
 
2294
 
2295
cur_level:
2296
; массив, в котором храниться текущее состояние города. изначально в него загрузаются уровни
2297
_city rw 32
2298
; массив, в котором храниться текущее состояние зениток. изначально в него загрузаются уровни
2299
_ackack rw 32
2300
; массив, в котором хранятся значения текущих координа снарядов от зениток
2301
_ackack_bullet rd 32
2302
 
2303
; номер текущего уровня
2304
_level_num dd 1
2305
; задание уровней: 32 числа означают высоту строений (высота "в квадратах") для _level?_city
2306
;                  и порядок появления зениток для _level?_ackack
2307
levels:
2308
_level1_city dw    0, 0, 0, 6, 5, 6, 5, 6, 3, 3, 3, 3, 3, 6, 7, 8,   8, 7, 6, 3, 3, 3, 3, 3, 6, 5, 6, 5, 6, 0, 0, 0
2309
_level1_ackack	dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,   1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2310
 
2311
_level2_city dw    0, 0, 0, 5, 5, 2, 5, 7, 7, 2, 7, 9, 9, 9, 2, 9,   9, 2, 9, 9, 9, 7, 2, 7, 7, 5, 2, 5, 5, 0, 0, 0
2312
_level2_ackack	dw 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0,   0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0
2313
 
2314
_level3_city dw    0, 0, 0,12,12,12, 9, 9, 9,12,12,12, 9, 7, 5, 3,   3, 5, 7, 9,12,12,12, 9, 9, 9,12,12,12, 0, 0, 0
2315
_level3_ackack	dw 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 4, 0, 3, 0, 2, 1,   1, 2, 0, 3, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0
2316
 
2317
_level4_city dw    0, 0, 0,12,12,12, 3,12,12,12, 3, 1, 1, 6,12,18,  18,12, 6, 1, 1, 3,12,12,12, 3,12,12,12, 0, 0, 0
2318
_level4_ackack	dw 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 1, 0, 3, 0, 0, 2,   6, 0, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0
2319
 
2320
_level5_city dw    0, 5,10,10,10,10,15,15,15,15,17,17,17,17, 1,15,  15, 1,17,17,17,17,15,15,15,15,10,10,10,10, 5, 0
2321
_level5_ackack	dw 0, 8, 0, 9, 9, 0, 3, 3, 3, 3, 0, 0, 0, 0, 5, 1,   2, 5, 0, 0, 0, 0, 4, 4, 4, 4, 0,10,10, 0, 7, 0
2322
 
2323
; звуки
2324
_count_sounds dd ?
2325
_array_sounds rd 2*MAX_SOUNDS
2326
 
2327
_channel_sound_plane dd ?    ; номер канала звука пропелера самолета
2328
_channel_sound_arw dd ?      ; номер канала звука сирены
2329
_array_bombsoundchannels rd MAX_BOMBS	 ; массив номеров звуковых каналов для бомб
2330
 
2331
_set_volume dd 8    ; громкость 0..8
2332
 
2333
; разное
2334
 
2335
_s_current_dir rb 4096	 ; путь к исполняемому файлу
2336
 
2337
file_info:	      ; информационная структура для работы с файлами
2338
  _fi_func dd ?
2339
  _fi_pos dd ?
2340
  dd 0
2341
  _fi_size dd ?
2342
  _fi_pbuff dd ?
2343
  db 0
2344
  _fi_pfilename dd ?
2345
 
5282 mario79 2346
if lang eq ru
2347
	include 'ruslang.inc'
2348
else
2349
	include 'englang.inc'
2350
end if
4323 yogev_ezra 2351
 
2352
bmp_plane:
2353
file "plane.bmp":54
2354
 
2355
bmp_bomb:
2356
file "bomb.bmp":54
2357
 
2358
bmp_tile:
2359
file "tile.bmp":54
2360
 
2361
bmp_ackack:
2362
file "ackack.bmp":54
2363
 
2364
 
2365
align 16
2366
rb 0x100 ; резерв памяти для стека.
2367
 
2368
i_end:
2369