Subversion Repositories Kolibri OS

Rev

Rev 6184 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6184 Rev 7134
1
; SOKOBAN FOR MENUET v0.1
1
; SOKOBAN FOR MENUET v0.1
2
; Written in pure assembler by Ivushkin Andrey aka Willow
2
; Written in pure assembler by Ivushkin Andrey aka Willow
3
;
3
;
4
; Last changed: July 2, 2004
4
; Last changed: July 2, 2004
5
;
5
;
6
; Main idea, art & graphics
6
; Main idea, art & graphics
7
;   Sokofun for Windows 95 by Games 4 Brains
7
;   Sokofun for Windows 95 by Games 4 Brains
8
;   and Sokoban 2.3 by Björn Källmark
8
;   and Sokoban 2.3 by Björn Källmark
9
;
9
;
10
; Level designers:
10
; Level designers:
11
;
11
;
12
;   Alberto Garcia, Aymeric du Peloux, Brian Kent, David Holland,
12
;   Alberto Garcia, Aymeric du Peloux, Brian Kent, David Holland,
13
;   David W Skinner, Erim Sever, Evgeniy Grigoriev, François Marques,
13
;   David W Skinner, Erim Sever, Evgeniy Grigoriev, François Marques,
14
;   Frantisek Pokorny, Howard Abed,J franklin Mentzer, Jaques Duthen,
14
;   Frantisek Pokorny, Howard Abed,J franklin Mentzer, Jaques Duthen,
15
;   John C Davis, John Polhemus, Kobus Theron, Lee Haywood, Mario Bonenfant,
15
;   John C Davis, John Polhemus, Kobus Theron, Lee Haywood, Mario Bonenfant,
16
;   Martin P Holland, Mic (Jan Reineke), Phil Shapiro, Richard Weston,
16
;   Martin P Holland, Mic (Jan Reineke), Phil Shapiro, Richard Weston,
17
;   Sven Egevad, Ken'ichiro Takahashi (takaken), Thinking Rabbit,
17
;   Sven Egevad, Ken'ichiro Takahashi (takaken), Thinking Rabbit,
18
;   Yoshio Murase, ZICO (Zbigniew Kornas)
18
;   Yoshio Murase, ZICO (Zbigniew Kornas)
19
;
19
;
20
; Special thanks to Hirohiko Nakamiya
20
; Special thanks to Hirohiko Nakamiya
21
;
21
;
22
; More credits:
22
; More credits:
23
;   Masato Hiramatsu, Kazuo Fukushima, Klaus Clemens
23
;   Masato Hiramatsu, Kazuo Fukushima, Klaus Clemens
24
;
24
;
25
; Game uses its own format of levelset files *.LEV
25
; Game uses its own format of levelset files *.LEV
26
;   with simple run-length compression
26
;   with simple run-length compression
27
 
27
 
28
; COMPILE WITH FASM
28
; COMPILE WITH FASM
29
 
29
 
30
format binary as ""
30
format binary as ""
31
 
31
 
32
include '../../../macros.inc'    ; decrease code size (optional)
32
include 'macros.inc'    ; decrease code size (optional)
33
include 'CELLTYPE.INC'  ; object identifiers
33
include 'CELLTYPE.INC'  ; object identifiers
34
;include 'debug.inc'
-
 
35
;lang equ ru             ; russian interface; english if undefined
-
 
36
include 'lang.inc'
34
;include 'debug.inc'
37
 
35
 
38
CUR_DIR equ '/sys/games/'       ; change it to appropriate path
36
CUR_DIR equ '/sys/games/'       ; change it to appropriate path
39
 
37
 
40
SKIN_SIZE       = 11520         ; size of skin file (16x240)
38
SKIN_SIZE       = 11520         ; size of skin file (16x240)
41
 
39
 
42
; field dimensions
40
; field dimensions
43
FLD_LEFT        = 43
41
FLD_LEFT        = 43
44
FLD_LEFT2       = FLD_LEFT shl 16
42
FLD_LEFT2       = FLD_LEFT shl 16
45
FLD_TOP         = 40
43
FLD_TOP         = 40
46
FLD_TOP2        = FLD_TOP shl 16
44
FLD_TOP2        = FLD_TOP shl 16
47
IMG_SIZE        = 16 shl 16+16
45
IMG_SIZE        = 16 shl 16+16
48
SHIFT           = (16 shl 16)
46
SHIFT           = (16 shl 16)
49
WND_COLOR       = 0x00aabbcc
47
WND_COLOR       = 0x00aabbcc
50
 
48
 
51
; level list dimensions
49
; level list dimensions
52
LEVLIST_XY      = FLD_TOP shl 16+45
50
LEVLIST_XY      = FLD_TOP shl 16+45
53
LEVLIST_SPACING = 10
51
LEVLIST_SPACING = 10
54
LEVWND_X        = 320
52
LEVWND_X        = 320
55
LEVWND_Y        = 200
53
LEVWND_Y        = 200
56
 
54
 
57
; input line dimensions
55
; input line dimensions
58
INP_X           = 10 shl 16+300
56
INP_X           = 10 shl 16+300
59
INP_Y           = 160 shl 16+16
57
INP_Y           = 160 shl 16+16
60
INP_XY          = 15 shl 16+164
58
INP_XY          = 15 shl 16+164
61
 
59
 
62
; load button dimensions
60
; load button dimensions
63
LOAD_X          = 130 shl 16+65
61
LOAD_X          = 130 shl 16+65
64
LOAD_Y          = 180 shl 16+14
62
LOAD_Y          = 180 shl 16+14
65
LOAD_XY         = 135 shl 16+184
63
LOAD_XY         = 135 shl 16+184
66
CHOOSE_XY       = 40 shl 16+148
64
CHOOSE_XY       = 40 shl 16+148
67
 
65
 
68
 
66
 
69
WIN_XY          = 135 shl 16+25
67
WIN_XY          = 135 shl 16+25
70
 
68
 
71
; workmode constants, more defs in CELLTYPE.INC
69
; workmode constants, more defs in CELLTYPE.INC
72
WM_WINNER       = 0x10
70
WM_WINNER       = 0x10
73
WM_READSET      = 0
71
WM_READSET      = 0
74
WM_LOSE         = 0x20
72
WM_LOSE         = 0x20
75
 
73
 
76
use32
74
use32
77
  org    0x0
75
  org    0x0
78
  db     'MENUET01'
76
  db     'MENUET01'
79
  dd     0x01
77
  dd     0x01
80
  dd     START
78
  dd     START
81
  dd     I_END
79
  dd     I_END
82
  dd     0x100000
80
  dd     0x100000
83
  dd     0x7fff0
81
  dd     0x7fff0
84
  dd     0x0
82
  dd     0x0
85
  dd     0x0
83
  dd     0x0
86
 
84
 
87
START:
85
START:
88
    mov  eax,70         ; load skin image-it is in RAW 16x240 BGR
86
    mov  eax,70         ; load skin image-it is in RAW 16x240 BGR
89
    mov  ebx,file_info  ; IrfanView recommended
87
    mov  ebx,file_info  ; IrfanView recommended
90
    int  0x40
88
    int  0x40
91
    test ebx,ebx
89
    test ebx,ebx
92
;    jmp load_level
90
;    jmp load_level
93
;    jz   close
91
;    jz   close
94
  load_fail:            ; clear input line, also if levelset load failed
92
  load_fail:            ; clear input line, also if levelset load failed
95
    mov  [inp_pos],0
93
    mov  [inp_pos],0
96
  load_std:
94
  load_std:
97
    mov  esi,stdlev
95
    mov  esi,stdlev
98
    mov  edi,path_end
96
    mov  edi,path_end
99
    mov  ecx,stdlev_len-stdlev
97
    mov  ecx,stdlev_len-stdlev
100
    rep  movsb
98
    rep  movsb
101
    mov  ecx,10
99
    mov  ecx,10
102
  reset_fi:
100
  reset_fi:
103
    mov  dword[cnf_level],level_start
101
    mov  dword[cnf_level],level_start
104
    xor  eax,eax
102
    xor  eax,eax
105
    mov  [levpage],eax
103
    mov  [levpage],eax
106
    mov  word[ll_num],'00'   ; reset some counters
104
    mov  word[ll_num],'00'   ; reset some counters
107
  read_cnf:
105
  read_cnf:
108
    mov  eax,70
106
    mov  eax,70
109
    mov  ebx,file_info
107
    mov  ebx,file_info
110
    int  0x40
108
    int  0x40
111
    test ebx,ebx        ; load standard levels SOKO-?.LEV instead of custom
109
    test ebx,ebx        ; load standard levels SOKO-?.LEV instead of custom
112
    jz   nxt_cnf
110
    jz   nxt_cnf
113
    add  dword[cnf_level],ebx
111
    add  dword[cnf_level],ebx
114
  nxt_cnf:
112
  nxt_cnf:
115
    test ecx,ecx        ; this check is for loading a custom levelset
113
    test ecx,ecx        ; this check is for loading a custom levelset
116
    jz   no_increase
114
    jz   no_increase
117
    inc  byte[file_num] ; next standard levelset
115
    inc  byte[file_num] ; next standard levelset
118
    loop read_cnf
116
    loop read_cnf
119
  no_increase:
117
  no_increase:
120
    cmp  dword[cnf_level],level_start
118
    cmp  dword[cnf_level],level_start
121
    jne  go_on
119
    jne  go_on
122
    test ecx,ecx
120
    test ecx,ecx
123
    jz   load_fail
121
    jz   load_fail
124
    jmp  close          ; missing standard levels & exiting
122
    jmp  close          ; missing standard levels & exiting
125
  go_on:
123
  go_on:
126
    mov  eax,[cnf_level]
124
    mov  eax,[cnf_level]
127
    mov  byte[eax],0xf0 ; end-of-levels mark
125
    mov  byte[eax],0xf0 ; end-of-levels mark
128
 
126
 
129
    call read_levelset
127
    call read_levelset
130
  backto_set:
128
  backto_set:
131
    mov  byte[workmode],WM_READSET
129
    mov  byte[workmode],WM_READSET
132
    mov  byte[winmode],0
130
    mov  byte[winmode],0
133
    jmp  red
131
    jmp  red
134
restart_level:
132
restart_level:
135
    call decode_field   ; uncompress level
133
    call decode_field   ; uncompress level
136
 
134
 
137
red:
135
red:
138
    call draw_window
136
    call draw_window
139
 
137
 
140
still:
138
still:
141
 
139
 
142
    mov  eax,10
140
    mov  eax,10
143
    int  0x40
141
    int  0x40
144
    cmp  byte[winmode],WM_WINNER
142
    cmp  byte[winmode],WM_WINNER
145
    je   backto_set
143
    je   backto_set
146
    cmp  byte[winmode],WM_LOSE
144
    cmp  byte[winmode],WM_LOSE
147
    je   backto_set
145
    je   backto_set
148
    cmp  eax,1
146
    cmp  eax,1
149
    je   red
147
    je   red
150
    cmp  eax,2
148
    cmp  eax,2
151
    je   key
149
    je   key
152
    cmp  eax,3
150
    cmp  eax,3
153
    je   button
151
    je   button
154
 
152
 
155
    jmp  still
153
    jmp  still
156
 
154
 
157
  key:
155
  key:
158
    mov  eax,2
156
    mov  eax,2
159
    int  0x40
157
    int  0x40
160
 
158
 
161
    cmp  byte[workmode],WM_READSET
159
    cmp  byte[workmode],WM_READSET
162
    jne  key_move
160
    jne  key_move
163
    cmp  ah,32          ; Space moves focus to input line
161
    cmp  ah,32          ; Space moves focus to input line
164
    je   is_input
162
    je   is_input
165
    cmp  ah,184
163
    cmp  ah,184
166
    jne  no_prev
164
    jne  no_prev
167
    cmp  [levpage],0    ; PgUp
165
    cmp  [levpage],0    ; PgUp
168
    jz   still
166
    jz   still
169
    sub  [levpage],10
167
    sub  [levpage],10
170
    cmp  byte[ll_num+1],'0'
168
    cmp  byte[ll_num+1],'0'
171
    jnz  _pu
169
    jnz  _pu
172
    dec  byte[ll_num]
170
    dec  byte[ll_num]
173
    mov  byte[ll_num+1],'9'+1
171
    mov  byte[ll_num+1],'9'+1
174
  _pu:
172
  _pu:
175
    dec  byte[ll_num+1]
173
    dec  byte[ll_num+1]
176
    jmp  red
174
    jmp  red
177
  no_prev:
175
  no_prev:
178
    cmp  ah,183         ; PgDn
176
    cmp  ah,183         ; PgDn
179
    jne  no_next
177
    jne  no_next
180
    mov  eax,[levpage]
178
    mov  eax,[levpage]
181
    add  eax,10
179
    add  eax,10
182
    cmp  eax,[levelcount]
180
    cmp  eax,[levelcount]
183
    jae  still
181
    jae  still
184
    mov  [levpage],eax
182
    mov  [levpage],eax
185
    cmp  byte[ll_num+1],'9'
183
    cmp  byte[ll_num+1],'9'
186
    jnz  _pd
184
    jnz  _pd
187
    inc  byte[ll_num]
185
    inc  byte[ll_num]
188
    mov  byte[ll_num+1],'0'-1
186
    mov  byte[ll_num+1],'0'-1
189
  _pd:
187
  _pd:
190
    inc  byte[ll_num+1]
188
    inc  byte[ll_num+1]
191
    jmp  red
189
    jmp  red
192
  no_next:
190
  no_next:
193
    sub  ah,48
191
    sub  ah,48
194
    cmp  ah,9
192
    cmp  ah,9
195
    ja   still
193
    ja   still
196
    movzx eax,ah        ; user selects a level
194
    movzx eax,ah        ; user selects a level
197
    add  eax,[levpage]
195
    add  eax,[levpage]
198
    cmp  eax,[levelcount]
196
    cmp  eax,[levelcount]
199
    jae  still
197
    jae  still
200
    mov  eax,[levelmap+eax*4]
198
    mov  eax,[levelmap+eax*4]
201
    mov  [levptr],eax   ; current level pointer
199
    mov  [levptr],eax   ; current level pointer
202
    mov  al,byte[eax]
200
    mov  al,byte[eax]
203
    mov  byte[workmode],al
201
    mov  byte[workmode],al
204
    jmp  restart_level
202
    jmp  restart_level
205
 
203
 
206
    ; we're already in game
204
    ; we're already in game
207
  key_move:
205
  key_move:
208
    cmp  ah,180        ; Home
206
    cmp  ah,180        ; Home
209
    je   backto_set
207
    je   backto_set
210
    cmp  ah,176
208
    cmp  ah,176
211
    jb   no_arrows
209
    jb   no_arrows
212
    sub  ah,176
210
    sub  ah,176
213
    cmp  ah,3
211
    cmp  ah,3
214
    ja   no_arrows
212
    ja   no_arrows
215
    movzx ecx,ah
213
    movzx ecx,ah
216
    movzx edx,[player]
214
    movzx edx,[player]
217
    inc  ch
215
    inc  ch
218
    call valid_move
216
    call valid_move
219
    cmp  byte[winmode],WM_WINNER
217
    cmp  byte[winmode],WM_WINNER
220
    jne  no_winner
218
    jne  no_winner
221
    mov  ecx,0x00ac0000
219
    mov  ecx,0x00ac0000
222
    mov  edx,win_msg
220
    mov  edx,win_msg
223
    mov  esi,win_msg_end-win_msg   ; print victory congratulations
221
    mov  esi,win_msg_end-win_msg   ; print victory congratulations
224
  print_msg:
222
  print_msg:
225
    mov  ebx,WIN_XY
223
    mov  ebx,WIN_XY
226
    mov  eax,4
224
    mov  eax,4
227
    int  0x40
225
    int  0x40
228
    jmp  d_f
226
    jmp  d_f
229
  no_winner:
227
  no_winner:
230
    cmp  byte[winmode],WM_LOSE
228
    cmp  byte[winmode],WM_LOSE
231
    jne  d_f
229
    jne  d_f
232
  no_loser:
230
  no_loser:
233
    test  al,al         ; no move accepted
231
    test  al,al         ; no move accepted
234
    jnz   still
232
    jnz   still
235
  d_f:
233
  d_f:
236
    call draw_field     ; move performed-redraw
234
    call draw_field     ; move performed-redraw
237
    jmp  still
235
    jmp  still
238
  no_arrows:
236
  no_arrows:
239
    cmp  ah,27
237
    cmp  ah,27
240
    je   restart_level
238
    je   restart_level
241
 
239
 
242
    jmp  still
240
    jmp  still
243
 
241
 
244
  button:
242
  button:
245
    mov  eax,17
243
    mov  eax,17
246
    int  0x40
244
    int  0x40
247
 
245
 
248
    cmp  ah,1
246
    cmp  ah,1
249
    jne  noclose
247
    jne  noclose
250
  close:
248
  close:
251
    xor  eax,eax
249
    xor  eax,eax
252
    dec  eax
250
    dec  eax
253
    int  0x40           ; shutdown.
251
    int  0x40           ; shutdown.
254
 
252
 
255
  noclose:
253
  noclose:
256
    cmp  ah,2
254
    cmp  ah,2
257
    jne  no_input
255
    jne  no_input
258
  is_input:             ; simple input line with backspace feature
256
  is_input:             ; simple input line with backspace feature
259
    mov  ebx,[entered]  ; sorry - no cursor
257
    mov  ebx,[entered]  ; sorry - no cursor
260
    test ebx,ebx
258
    test ebx,ebx
261
    jnz  wait_input
259
    jnz  wait_input
262
    mov  [inp_pos],ebx
260
    mov  [inp_pos],ebx
263
    inc  [entered]
261
    inc  [entered]
264
  wait_input:
262
  wait_input:
265
    call draw_input
263
    call draw_input
266
    mov  eax,10
264
    mov  eax,10
267
    int  0x40
265
    int  0x40
268
    cmp  eax,2
266
    cmp  eax,2
269
    jne  still
267
    jne  still
270
    mov  edi,[inp_pos]
268
    mov  edi,[inp_pos]
271
    mov  eax,2
269
    mov  eax,2
272
    int  0x40
270
    int  0x40
273
    shr  eax,8
271
    shr  eax,8
274
    cmp  eax,27
272
    cmp  eax,27
275
    je   still
273
    je   still
276
    cmp  eax,13
274
    cmp  eax,13
277
    je   load_level
275
    je   load_level
278
    cmp  eax,8
276
    cmp  eax,8
279
    je   backsp
277
    je   backsp
280
    mov  [fn_input+edi],al
278
    mov  [fn_input+edi],al
281
    inc  [inp_pos]
279
    inc  [inp_pos]
282
    jmp  wait_input
280
    jmp  wait_input
283
  backsp:
281
  backsp:
284
    test edi,edi
282
    test edi,edi
285
    jz   wait_input
283
    jz   wait_input
286
    dec  [inp_pos]
284
    dec  [inp_pos]
287
    jmp  wait_input
285
    jmp  wait_input
288
  no_input:
286
  no_input:
289
    cmp  ah,3
287
    cmp  ah,3
290
    jne  no_load
288
    jne  no_load
291
  load_level:
289
  load_level:
292
    mov  ecx,[inp_pos]
290
    mov  ecx,[inp_pos]
293
    test ecx,ecx
291
    test ecx,ecx
294
    je   load_std
292
    je   load_std
295
    mov  esi,fn_input
293
    mov  esi,fn_input
296
    mov  byte[esi+ecx],0
294
    mov  byte[esi+ecx],0
297
    inc  ecx
295
    inc  ecx
298
    mov  edi,path_end
296
    mov  edi,path_end
299
    rep  movsb
297
    rep  movsb
300
    jmp  reset_fi
298
    jmp  reset_fi
301
  no_load:
299
  no_load:
302
    jmp  still
300
    jmp  still
303
 
301
 
304
 
302
 
305
;   *********************************************
303
;   *********************************************
306
;   ** FILLS LEVEL POINTER MAP ******************
304
;   ** FILLS LEVEL POINTER MAP ******************
307
;   *********************************************
305
;   *********************************************
308
read_levelset:
306
read_levelset:
309
 
307
 
310
    mov  dword[wnd_width],LEVWND_X
308
    mov  dword[wnd_width],LEVWND_X
311
    mov  dword[wnd_height],LEVWND_Y
309
    mov  dword[wnd_height],LEVWND_Y
312
    mov  [levelcount],0
310
    mov  [levelcount],0
313
    mov  edi,level_start
311
    mov  edi,level_start
314
    mov  esi,levelmap
312
    mov  esi,levelmap
315
    mov  al,0xff
313
    mov  al,0xff
316
  rls_cycle:
314
  rls_cycle:
317
    cmp  byte[edi],EOF
315
    cmp  byte[edi],EOF
318
    je   end_of_levelset
316
    je   end_of_levelset
319
    mov  [esi],edi
317
    mov  [esi],edi
320
    add  esi,4
318
    add  esi,4
321
    mov  ecx,1024
319
    mov  ecx,1024
322
    inc  [levelcount]
320
    inc  [levelcount]
323
    repne scasb
321
    repne scasb
324
    jecxz eol  ;end_of_levelset
322
    jecxz eol  ;end_of_levelset
325
    jmp  rls_cycle
323
    jmp  rls_cycle
326
  end_of_levelset:
324
  end_of_levelset:
327
    mov  eax,[levelcount]
325
    mov  eax,[levelcount]
328
;    debug_print_dec eax
326
;    debug_print_dec eax
329
    ret
327
    ret
330
  eol:
328
  eol:
331
;   debug_print '*** '
329
;   debug_print '*** '
332
    jmp  end_of_levelset
330
    jmp  end_of_levelset
333
 
331
 
334
;   *********************************************
332
;   *********************************************
335
;   *******  DEFINE & DRAW WINDOW & OTHER STUFF *
333
;   *******  DEFINE & DRAW WINDOW & OTHER STUFF *
336
;   *********************************************
334
;   *********************************************
337
 
335
 
338
draw_window:
336
draw_window:
339
 
337
 
340
    mov  eax,12
338
    mov  eax,12
341
    mov  ebx,1
339
    mov  ebx,1
342
    int  0x40
340
    int  0x40
343
 
341
 
344
    mov  eax,0
342
    mov  eax,0
345
    mov  ebx,150*65536
343
    mov  ebx,150*65536
346
    add  ebx,[wnd_width]
344
    add  ebx,[wnd_width]
347
    mov  ecx,50*65536
345
    mov  ecx,50*65536
348
    add  ecx,[wnd_height]
346
    add  ecx,[wnd_height]
349
    mov  edx,0x13000000 + WND_COLOR
347
    mov  edx,0x13000000 + WND_COLOR
350
    mov  esi,0x005080d0
348
    mov  esi,0x005080d0
351
    mov  edi,zagolovok
349
    mov  edi,zagolovok
352
    int  0x40
350
    int  0x40
353
 
351
 
354
    cmp  byte[workmode],WM_READSET
352
    cmp  byte[workmode],WM_READSET
355
    je   list_levels
353
    je   list_levels
356
 
354
 
357
    mov  edi,[levptr]   ; print custom level filename
355
    mov  edi,[levptr]   ; print custom level filename
358
    add  ebx,170*65536
356
    add  ebx,170*65536
359
    lea  edx,[edi+4]
357
    lea  edx,[edi+4]
360
    movzx  esi,byte[edi+3]
358
    movzx  esi,byte[edi+3]
361
    int  0x40
359
    int  0x40
362
 
360
 
363
    call draw_field
361
    call draw_field
364
    cmp  [entered],0
362
    cmp  [entered],0
365
    jz   end_of_draw
363
    jz   end_of_draw
366
    mov  edx,fn_input   ; print input line text
364
    mov  edx,fn_input   ; print input line text
367
    mov  esi,[inp_pos]
365
    mov  esi,[inp_pos]
368
    mov  ebx,FLD_LEFT2+FLD_TOP-15
366
    mov  ebx,FLD_LEFT2+FLD_TOP-15
369
    jmp  draw_level_file
367
    jmp  draw_level_file
370
 
368
 
371
  list_levels:
369
  list_levels:
372
 
370
 
373
    call draw_input
371
    call draw_input
374
 
372
 
375
    mov  eax,8          ; draw load button
373
    mov  eax,8          ; draw load button
376
    mov  ebx,LOAD_X
374
    mov  ebx,LOAD_X
377
    mov  ecx,LOAD_Y
375
    mov  ecx,LOAD_Y
378
    mov  edx,3
376
    mov  edx,3
379
    mov  esi,WND_COLOR
377
    mov  esi,WND_COLOR
380
    int  0x40
378
    int  0x40
381
 
379
 
382
    mov  eax,4
380
    mov  eax,4
383
    mov  ecx,0x00107a30
381
    mov  ecx,0x00107a30
384
    mov  ebx,LOAD_XY
382
    mov  ebx,LOAD_XY
385
    mov  edx,load_char
383
    mov  edx,load_char
386
    mov  esi,loadlen-load_char
384
    mov  esi,loadlen-load_char
387
    int  0x40
385
    int  0x40
388
 
386
 
389
    mov  ebx,LEVLIST_XY
387
    mov  ebx,LEVLIST_XY
390
    mov  edi,0x004e00e7
388
    mov  edi,0x004e00e7
391
    xor  esi,esi
389
    xor  esi,esi
392
    mov  ecx,10
390
    mov  ecx,10
393
  ll_cycle:
391
  ll_cycle:
394
    push ecx esi ebx esi
392
    push ecx esi ebx esi
395
    lea  ecx,[esi+'0']
393
    lea  ecx,[esi+'0']
396
    mov  [ll_num+2],cl
394
    mov  [ll_num+2],cl
397
    mov  ecx,edi
395
    mov  ecx,edi
398
    mov  edx,ll_num
396
    mov  edx,ll_num
399
    mov  esi,4
397
    mov  esi,4
400
    int  0x40
398
    int  0x40
401
    add  ebx,25 shl 16
399
    add  ebx,25 shl 16
402
    pop  esi
400
    pop  esi
403
    add  esi,[levpage]
401
    add  esi,[levpage]
404
    mov  edx,[levelmap+esi*4]
402
    mov  edx,[levelmap+esi*4]
405
    add  edx,4
403
    add  edx,4
406
    movzx esi,byte[edx-1]
404
    movzx esi,byte[edx-1]
407
    int  0x40
405
    int  0x40
408
    pop  ebx esi ecx
406
    pop  ebx esi ecx
409
    inc  esi
407
    inc  esi
410
    mov  edx,[levelcount]
408
    mov  edx,[levelcount]
411
    sub  edx,[levpage]
409
    sub  edx,[levpage]
412
    cmp  edx,esi
410
    cmp  edx,esi
413
    jbe  choose_print
411
    jbe  choose_print
414
    add  ebx,LEVLIST_SPACING
412
    add  ebx,LEVLIST_SPACING
415
    loop ll_cycle
413
    loop ll_cycle
416
  choose_print:
414
  choose_print:
417
    mov  edx,ll_msg
415
    mov  edx,ll_msg
418
    mov  esi,ll_msg_end-ll_msg
416
    mov  esi,ll_msg_end-ll_msg
419
    mov  ebx,CHOOSE_XY
417
    mov  ebx,CHOOSE_XY
420
  draw_level_file:
418
  draw_level_file:
421
    mov  eax,4
419
    mov  eax,4
422
    int  0x40
420
    int  0x40
423
 
421
 
424
  end_of_draw:
422
  end_of_draw:
425
    mov  eax,12
423
    mov  eax,12
426
    mov  ebx,2
424
    mov  ebx,2
427
    int  0x40
425
    int  0x40
428
 
426
 
429
    ret
427
    ret
430
 
428
 
431
;   *********************************************
429
;   *********************************************
432
;   ******* DRAW CELL IMAGES WITHIN FIELD *******
430
;   ******* DRAW CELL IMAGES WITHIN FIELD *******
433
;   *********************************************
431
;   *********************************************
434
 
432
 
435
draw_field:
433
draw_field:
436
    cmp  byte[workmode],sSokonex
434
    cmp  byte[workmode],sSokonex
437
    jne  no_chl
435
    jne  no_chl
438
    call check_lasers   ; Sokonex game
436
    call check_lasers   ; Sokonex game
439
  no_chl:
437
  no_chl:
440
    mov  eax,13         ; clear field area
438
    mov  eax,13         ; clear field area
441
    mov  edx,WND_COLOR
439
    mov  edx,WND_COLOR
442
    mov  edi,[levptr]
440
    mov  edi,[levptr]
443
    movzx ebx,byte[edi+1]
441
    movzx ebx,byte[edi+1]
444
    shl  ebx,4
442
    shl  ebx,4
445
    lea  ebx, [FLD_LEFT2+ebx]
443
    lea  ebx, [FLD_LEFT2+ebx]
446
    movzx ecx,byte[edi+2]
444
    movzx ecx,byte[edi+2]
447
    shl  ecx,4
445
    shl  ecx,4
448
    lea  ecx, [FLD_TOP shl 16+ecx]
446
    lea  ecx, [FLD_TOP shl 16+ecx]
449
    int  0x40
447
    int  0x40
450
 
448
 
451
    mov  edx, FLD_LEFT2+FLD_TOP
449
    mov  edx, FLD_LEFT2+FLD_TOP
452
    movzx edi,byte[edi+1]
450
    movzx edi,byte[edi+1]
453
    shl  edi,20
451
    shl  edi,20
454
    add  edi, FLD_LEFT2
452
    add  edi, FLD_LEFT2
455
 
453
 
456
    xor  eax,eax
454
    xor  eax,eax
457
    mov  ecx,[fld_size]
455
    mov  ecx,[fld_size]
458
    mov  esi,field
456
    mov  esi,field
459
  fld_cycle:
457
  fld_cycle:
460
    lodsb
458
    lodsb
461
    call draw_img
459
    call draw_img
462
    add  edx,SHIFT
460
    add  edx,SHIFT
463
    cmp  edx,edi
461
    cmp  edx,edi
464
    jl  no_nl
462
    jl  no_nl
465
    add  edx,16
463
    add  edx,16
466
    and  edx,0xffff
464
    and  edx,0xffff
467
    add  edx,FLD_LEFT2
465
    add  edx,FLD_LEFT2
468
  no_nl:
466
  no_nl:
469
    loop fld_cycle
467
    loop fld_cycle
470
    cmp  byte[workmode],sSokonex
468
    cmp  byte[workmode],sSokonex
471
    jne  end_of_df
469
    jne  end_of_df
472
    call draw_lasers
470
    call draw_lasers
473
  end_of_df:
471
  end_of_df:
474
    ret
472
    ret
475
 
473
 
476
;   *********************************************
474
;   *********************************************
477
;   *********** DRAW CELL IMAGE *****************
475
;   *********** DRAW CELL IMAGE *****************
478
;   *********************************************
476
;   *********************************************
479
 
477
 
480
draw_img:               ; in: eax-object index, edx-coordinates
478
draw_img:               ; in: eax-object index, edx-coordinates
481
    pusha
479
    pusha
482
    cmp  eax,tWall
480
    cmp  eax,tWall
483
    jbe  no_adjust
481
    jbe  no_adjust
484
    cmp  [workmode],sSokolor
482
    cmp  [workmode],sSokolor
485
    jne  no_di_color
483
    jne  no_di_color
486
    add  eax,pm_col-pm_nex
484
    add  eax,pm_col-pm_nex
487
    jmp  no_adjust
485
    jmp  no_adjust
488
  no_di_color:
486
  no_di_color:
489
    cmp  [workmode],sSokonex
487
    cmp  [workmode],sSokonex
490
    jne  no_adjust
488
    jne  no_adjust
491
    inc  eax
489
    inc  eax
492
  no_adjust:
490
  no_adjust:
493
    movzx  ebx,byte [pic_map+eax]
491
    movzx  ebx,byte [pic_map+eax]
494
    cmp  ebx,0xf
492
    cmp  ebx,0xf
495
    je   no_img
493
    je   no_img
496
  bl_place:
494
  bl_place:
497
    mov  ecx, IMG_SIZE
495
    mov  ecx, IMG_SIZE
498
    imul ebx, 256*3
496
    imul ebx, 256*3
499
    add  ebx,strip
497
    add  ebx,strip
500
    mov  eax,7          ; draw_image sysfunc
498
    mov  eax,7          ; draw_image sysfunc
501
    int  0x40
499
    int  0x40
502
  no_img:
500
  no_img:
503
    popa
501
    popa
504
    ret
502
    ret
505
 
503
 
506
;****************************************
504
;****************************************
507
;******* DRAW CONTENTS OF INPUT LINE ****
505
;******* DRAW CONTENTS OF INPUT LINE ****
508
;****************************************
506
;****************************************
509
draw_input:
507
draw_input:
510
    push edi
508
    push edi
511
    cmp  eax,4
509
    cmp  eax,4
512
    jne  highlight
510
    jne  highlight
513
    mov  esi,WND_COLOR
511
    mov  esi,WND_COLOR
514
    jmp  di_draw
512
    jmp  di_draw
515
  highlight:
513
  highlight:
516
    mov  esi,0xe0e0e0
514
    mov  esi,0xe0e0e0
517
  di_draw:
515
  di_draw:
518
    mov  eax,8
516
    mov  eax,8
519
    mov  ebx,INP_X
517
    mov  ebx,INP_X
520
    mov  ecx,INP_Y
518
    mov  ecx,INP_Y
521
    mov  edx,2
519
    mov  edx,2
522
    int  0x40
520
    int  0x40
523
    mov  eax,4
521
    mov  eax,4
524
    mov  ecx,0x00107a30            ; èà¨äâ 1 ¨ 梥â ( 0xF0RRGGBB )
522
    mov  ecx,0x00107a30            ; èà¨äâ 1 ¨ 梥â ( 0xF0RRGGBB )
525
    mov  ebx,INP_XY
523
    mov  ebx,INP_XY
526
    mov  edx,fn_input
524
    mov  edx,fn_input
527
    mov  esi,[inp_pos]
525
    mov  esi,[inp_pos]
528
    int  0x40
526
    int  0x40
529
    pop  edi
527
    pop  edi
530
    ret
528
    ret
531
 
529
 
532
;   ********************************************************
530
;   ********************************************************
533
;   * DECOMPRESS LEVEL & FILL SOME TABLES TO CHECK VICTORY *
531
;   * DECOMPRESS LEVEL & FILL SOME TABLES TO CHECK VICTORY *
534
;   ********************************************************
532
;   ********************************************************
535
 
533
 
536
decode_field:
534
decode_field:
537
;    debug_print <13,10>
535
;    debug_print <13,10>
538
    xor  eax,eax
536
    xor  eax,eax
539
    mov  dword[checkpoint],eax
537
    mov  dword[checkpoint],eax
540
    mov  dword[checkpoint+4],eax
538
    mov  dword[checkpoint+4],eax
541
    mov  byte[checkcount],al
539
    mov  byte[checkcount],al
542
    mov  edi,[levptr]
540
    mov  edi,[levptr]
543
    mov  dl,[edi]
541
    mov  dl,[edi]
544
    mov  [workmode],dl
542
    mov  [workmode],dl
545
    movzx  edx,byte[edi+1]
543
    movzx  edx,byte[edi+1]
546
    mov  esi,edx
544
    mov  esi,edx
547
    shl  esi,4
545
    shl  esi,4
548
    add  esi,FLD_LEFT*2-25
546
    add  esi,FLD_LEFT*2-25
549
    mov  [wnd_width],esi
547
    mov  [wnd_width],esi
550
    neg  edx
548
    neg  edx
551
    mov  [move_map+8],edx
549
    mov  [move_map+8],edx
552
    neg  edx
550
    neg  edx
553
    mov  [move_map+4],edx
551
    mov  [move_map+4],edx
554
    movzx eax,byte[edi+2]
552
    movzx eax,byte[edi+2]
555
    mov  esi,eax
553
    mov  esi,eax
556
    shl  esi,4
554
    shl  esi,4
557
    add  esi,FLD_TOP*2-18
555
    add  esi,FLD_TOP*2-18
558
    mov  [wnd_height],esi
556
    mov  [wnd_height],esi
559
    imul edx,eax
557
    imul edx,eax
560
    mov  [fld_size],edx
558
    mov  [fld_size],edx
561
    lea  esi,[edi+4]
559
    lea  esi,[edi+4]
562
    movzx ecx,byte[edi+3]
560
    movzx ecx,byte[edi+3]
563
    add  esi,ecx
561
    add  esi,ecx
564
    cmp  byte[esi],0xff
562
    cmp  byte[esi],0xff
565
    je   backto_set
563
    je   backto_set
566
    xor  edi,edi
564
    xor  edi,edi
567
    cld
565
    cld
568
 dec_cycle:
566
 dec_cycle:
569
    lodsb
567
    lodsb
570
    movzx ecx,al
568
    movzx ecx,al
571
    and  ecx,0xf                   ; ecx-count of objects
569
    and  ecx,0xf                   ; ecx-count of objects
572
    shr  al,4                      ; eax-index of object
570
    shr  al,4                      ; eax-index of object
573
    inc  ecx
571
    inc  ecx
574
    sub  edx,ecx
572
    sub  edx,ecx
575
  dc_cycle:
573
  dc_cycle:
576
    mov  [field+edi],al
574
    mov  [field+edi],al
577
    call chk_win_obj
575
    call chk_win_obj
578
    jne  no_register
576
    jne  no_register
579
    push eax ecx esi
577
    push eax ecx esi
580
    movzx ecx,al
578
    movzx ecx,al
581
    shl  eax,12
579
    shl  eax,12
582
    or   eax,edi
580
    or   eax,edi
583
    inc  byte[checkcount]
581
    inc  byte[checkcount]
584
    cmp  [workmode],sSokolor
582
    cmp  [workmode],sSokolor
585
    jne  chk_sokoban
583
    jne  chk_sokoban
586
;    debug_print ':'
584
;    debug_print ':'
587
;    debug_print_dec ecx
585
;    debug_print_dec ecx
588
    sub  ecx,tRedB
586
    sub  ecx,tRedB
589
    shl  ecx,1
587
    shl  ecx,1
590
    cmp  word[checkpoint+ecx],0
588
    cmp  word[checkpoint+ecx],0
591
    jnz  no_new_check
589
    jnz  no_new_check
592
    mov  [checkpoint+ecx],ax
590
    mov  [checkpoint+ecx],ax
593
    and  eax,0xfff
591
    and  eax,0xfff
594
;    debug_print_dec eax
592
;    debug_print_dec eax
595
    jmp  no_new_check
593
    jmp  no_new_check
596
  chk_sokoban:
594
  chk_sokoban:
597
    cmp  [workmode],sSokonex
595
    cmp  [workmode],sSokonex
598
    jne  no_nex
596
    jne  no_nex
599
    cmp  byte[checkcount],1
597
    cmp  byte[checkcount],1
600
    ja   no_new_check
598
    ja   no_new_check
601
  no_nex:
599
  no_nex:
602
    movzx ecx,byte[checkcount]
600
    movzx ecx,byte[checkcount]
603
    mov  word[checkpoint-2+ecx*2],ax
601
    mov  word[checkpoint-2+ecx*2],ax
604
  no_new_check:
602
  no_new_check:
605
    pop  esi ecx eax
603
    pop  esi ecx eax
606
  no_register:
604
  no_register:
607
    inc  edi
605
    inc  edi
608
    loop dc_cycle
606
    loop dc_cycle
609
    cmp  edx,0
607
    cmp  edx,0
610
    jg   dec_cycle
608
    jg   dec_cycle
611
    mov  ecx,[fld_size]
609
    mov  ecx,[fld_size]
612
    xor  edx,edx
610
    xor  edx,edx
613
  fp_cycle:
611
  fp_cycle:
614
    mov  al,[field+edx]
612
    mov  al,[field+edx]
615
    and  al,0xfe
613
    and  al,0xfe
616
    cmp  al,tPlayer
614
    cmp  al,tPlayer
617
    je   pl_found
615
    je   pl_found
618
    inc  edx
616
    inc  edx
619
    loop fp_cycle
617
    loop fp_cycle
620
  pl_found:
618
  pl_found:
621
    mov  [player],dx
619
    mov  [player],dx
622
    movzx eax,byte[checkcount]
620
    movzx eax,byte[checkcount]
623
;    debug_print_dec eax
621
;    debug_print_dec eax
624
    ret
622
    ret
625
 
623
 
626
;   *********************************************
624
;   *********************************************
627
;   * WHETHER OBJECT IS VICTORY DEPENDENT *******
625
;   * WHETHER OBJECT IS VICTORY DEPENDENT *******
628
;   *********************************************
626
;   *********************************************
629
 
627
 
630
chk_win_obj:             ; al-object in a cell
628
chk_win_obj:             ; al-object in a cell
631
    push ecx eax
629
    push ecx eax
632
    and  al,0xf
630
    and  al,0xf
633
    mov  cl,[workmode]
631
    mov  cl,[workmode]
634
    cmp  cl,sSokoban
632
    cmp  cl,sSokoban
635
    jne  nota_sokoban
633
    jne  nota_sokoban
636
    cmp  al,tBlock
634
    cmp  al,tBlock
637
    jmp  cwo_exit
635
    jmp  cwo_exit
638
  nota_sokoban:
636
  nota_sokoban:
639
    cmp  cl,sSokonex
637
    cmp  cl,sSokonex
640
    jne  nota_sokonex
638
    jne  nota_sokonex
641
    cmp  al,tConnect
639
    cmp  al,tConnect
642
    je   cwo_exit
640
    je   cwo_exit
643
    cmp  al,tStConnect
641
    cmp  al,tStConnect
644
    jmp  cwo_exit
642
    jmp  cwo_exit
645
  nota_sokonex:
643
  nota_sokonex:
646
    push eax
644
    push eax
647
    and  eax,tRedB
645
    and  eax,tRedB
648
    cmp  eax,tRedB
646
    cmp  eax,tRedB
649
    pop  eax
647
    pop  eax
650
  cwo_exit:
648
  cwo_exit:
651
    pop  eax ecx
649
    pop  eax ecx
652
    ret
650
    ret
653
 
651
 
654
;   *********************************************
652
;   *********************************************
655
;   ***** GET CELL AT CERTAIN DIRECTION *********
653
;   ***** GET CELL AT CERTAIN DIRECTION *********
656
;   *********************************************
654
;   *********************************************
657
 
655
 
658
get_cell_at:            ; in:  dx - current cell, cl - direction
656
get_cell_at:            ; in:  dx - current cell, cl - direction
659
    mov  ebx,edx        ; out: al - object at direction, bx - new position
657
    mov  ebx,edx        ; out: al - object at direction, bx - new position
660
    movzx eax,cl
658
    movzx eax,cl
661
    and  eax,11b
659
    and  eax,11b
662
    mov  eax, [move_map+eax*4]
660
    mov  eax, [move_map+eax*4]
663
    add  ebx,eax
661
    add  ebx,eax
664
    mov  al,[field+ebx]
662
    mov  al,[field+ebx]
665
    ret
663
    ret
666
 
664
 
667
;   *********************************************
665
;   *********************************************
668
;   *** WHETHER A MOVE CAN BE DONE, & DO IT *****
666
;   *** WHETHER A MOVE CAN BE DONE, & DO IT *****
669
;   *********************************************
667
;   *********************************************
670
 
668
 
671
valid_move:                         ; in:  dx - current cell, cl - direction
669
valid_move:                         ; in:  dx - current cell, cl - direction
672
    push edx esi
670
    push edx esi
673
    call get_cell_at                ; if ch>0 perform all moves
671
    call get_cell_at                ; if ch>0 perform all moves
674
    cmp  al,tWall
672
    cmp  al,tWall
675
    jb   result_ok
673
    jb   result_ok
676
    je   vm_exit
674
    je   vm_exit
677
    cmp  [workmode],sSokonex
675
    cmp  [workmode],sSokonex
678
    jne  n_vm_nex
676
    jne  n_vm_nex
679
    cmp  al,tStConnect
677
    cmp  al,tStConnect
680
    je   vm_exit
678
    je   vm_exit
681
    cmp  al,tHole
679
    cmp  al,tHole
682
    je   vm_exit
680
    je   vm_exit
683
  n_vm_nex:
681
  n_vm_nex:
684
    push edx ebx
682
    push edx ebx
685
    mov  edx,ebx
683
    mov  edx,ebx
686
    movzx esi,al
684
    movzx esi,al
687
    call get_cell_at
685
    call get_cell_at
688
    cmp  al,tPlace
686
    cmp  al,tPlace
689
    jbe  push_it
687
    jbe  push_it
690
    cmp  [workmode],sSokonex
688
    cmp  [workmode],sSokonex
691
    jne  no_plate
689
    jne  no_plate
692
    cmp  al,tHole
690
    cmp  al,tHole
693
    jne  no_plate
691
    jne  no_plate
694
    cmp  esi,tBroken
692
    cmp  esi,tBroken
695
    jae  vm_sink
693
    jae  vm_sink
696
    cmp  esi,tPlate
694
    cmp  esi,tPlate
697
    jne  no_plate
695
    jne  no_plate
698
    and  byte[field+ebx],0
696
    and  byte[field+ebx],0
699
  vm_sink:
697
  vm_sink:
700
    and  byte[field+edx],0
698
    and  byte[field+edx],0
701
    jmp  vm_hole
699
    jmp  vm_hole
702
  no_plate:
700
  no_plate:
703
    pop  ebx edx esi edx
701
    pop  ebx edx esi edx
704
    ret
702
    ret
705
  push_it:
703
  push_it:
706
    call do_move
704
    call do_move
707
  vm_hole:
705
  vm_hole:
708
    pop  ebx edx
706
    pop  ebx edx
709
  result_ok:
707
  result_ok:
710
    call do_move
708
    call do_move
711
    xor  al,al
709
    xor  al,al
712
  vm_exit:
710
  vm_exit:
713
    pop  esi edx
711
    pop  esi edx
714
    ret
712
    ret
715
 
713
 
716
;   *********************************************
714
;   *********************************************
717
;   ******* ACTUALLY PERFORM MOVES **************
715
;   ******* ACTUALLY PERFORM MOVES **************
718
;   *********************************************
716
;   *********************************************
719
 
717
 
720
do_move:                            ; in: dx - source cell
718
do_move:                            ; in: dx - source cell
721
    test ch,ch                      ;     bx - target cell
719
    test ch,ch                      ;     bx - target cell
722
    jz   dm_exit                    ;     ch = 0 don't perform moves
720
    jz   dm_exit                    ;     ch = 0 don't perform moves
723
    mov  al,byte[field+edx]
721
    mov  al,byte[field+edx]
724
    cmp  byte[workmode],sSokoban
722
    cmp  byte[workmode],sSokoban
725
    jne  no_dm_ban
723
    jne  no_dm_ban
726
    and  al,0xfe
724
    and  al,0xfe
727
  no_dm_ban:
725
  no_dm_ban:
728
    xor  byte[field+edx],al
726
    xor  byte[field+edx],al
729
    or   byte[field+ebx],al
727
    or   byte[field+ebx],al
730
    call chk_win_obj
728
    call chk_win_obj
731
    jne  no_check_win
729
    jne  no_check_win
732
    pusha
730
    pusha
733
    movzx ecx,byte[checkcount]
731
    movzx ecx,byte[checkcount]
734
    xor  edi,edi
732
    xor  edi,edi
735
  dm_cycle:
733
  dm_cycle:
736
    movzx esi,word[checkpoint+edi*2]
734
    movzx esi,word[checkpoint+edi*2]
737
    and  esi,0xfff
735
    and  esi,0xfff
738
    and  edx,0xfff
736
    and  edx,0xfff
739
    cmp  esi,edx
737
    cmp  esi,edx
740
    jnz  not_an_obj
738
    jnz  not_an_obj
741
    movzx eax,dl
739
    movzx eax,dl
742
    movzx eax,byte[field+ebx]
740
    movzx eax,byte[field+ebx]
743
    shl  eax,12
741
    shl  eax,12
744
    or   eax,ebx
742
    or   eax,ebx
745
    mov  word[checkpoint+edi*2],ax
743
    mov  word[checkpoint+edi*2],ax
746
    jmp  dm_ex
744
    jmp  dm_ex
747
  not_an_obj:
745
  not_an_obj:
748
    inc  edi
746
    inc  edi
749
    loop dm_cycle
747
    loop dm_cycle
750
  dm_ex:
748
  dm_ex:
751
    popa
749
    popa
752
    call check_win
750
    call check_win
753
    jne  no_check_win
751
    jne  no_check_win
754
    mov  byte[winmode],WM_WINNER
752
    mov  byte[winmode],WM_WINNER
755
  no_check_win:
753
  no_check_win:
756
    cmp  al,tPlayer
754
    cmp  al,tPlayer
757
    jne  dm_exit
755
    jne  dm_exit
758
    mov  [player],bx
756
    mov  [player],bx
759
  dm_exit:
757
  dm_exit:
760
    ret
758
    ret
761
 
759
 
762
;   *********************************************
760
;   *********************************************
763
;   ******* CHECK VICTORY CONDITIONS ************
761
;   ******* CHECK VICTORY CONDITIONS ************
764
;   *********************************************
762
;   *********************************************
765
 
763
 
766
check_win:
764
check_win:
767
;    debug_print <13,10>
765
;    debug_print <13,10>
768
    push eax ebx ecx esi
766
    push eax ebx ecx esi
769
    xor  eax,eax
767
    xor  eax,eax
770
    movzx ecx,byte[checkcount]
768
    movzx ecx,byte[checkcount]
771
    mov  esi,checkpoint
769
    mov  esi,checkpoint
772
    mov  bl,byte[workmode]
770
    mov  bl,byte[workmode]
773
    xor  bh,bh
771
    xor  bh,bh
774
    mov  [colcount],bh
772
    mov  [colcount],bh
775
    cld
773
    cld
776
  cw_cycle:
774
  cw_cycle:
777
    lodsw
775
    lodsw
778
    cmp  bl,sSokoban
776
    cmp  bl,sSokoban
779
    jne  nocw_sokoban
777
    jne  nocw_sokoban
780
    test ax,1 shl 12
778
    test ax,1 shl 12
781
    jz   cw_not_inplace
779
    jz   cw_not_inplace
782
    inc  bh
780
    inc  bh
783
  cw_not_inplace:
781
  cw_not_inplace:
784
    loop cw_cycle
782
    loop cw_cycle
785
;    movzx eax,bh
783
;    movzx eax,bh
786
    cmp  [checkcount],bh
784
    cmp  [checkcount],bh
787
    jmp  cw_exit
785
    jmp  cw_exit
788
  nocw_sokoban:
786
  nocw_sokoban:
789
    cmp  bl,sSokonex
787
    cmp  bl,sSokonex
790
    jne  nocw_sokonex
788
    jne  nocw_sokonex
791
    mov  dx,ax
789
    mov  dx,ax
792
    call scan_root
790
    call scan_root
793
    cmp  al,[checkcount]
791
    cmp  al,[checkcount]
794
    jmp  cw_exit
792
    jmp  cw_exit
795
 
793
 
796
  nocw_sokonex:
794
  nocw_sokonex:
797
    cmp  esi,checkpoint+8
795
    cmp  esi,checkpoint+8
798
    ja   cwlor_exit
796
    ja   cwlor_exit
799
;    debug_print '*'
797
;    debug_print '*'
800
    test ax,ax
798
    test ax,ax
801
    jz   cw_cycle
799
    jz   cw_cycle
802
    mov  dx,ax
800
    mov  dx,ax
803
    call scan_root
801
    call scan_root
804
    add  [colcount],al
802
    add  [colcount],al
805
;    debug_print '*->'
803
;    debug_print '*->'
806
;    debug_print_dec eax
804
;    debug_print_dec eax
807
    jmp  cw_cycle
805
    jmp  cw_cycle
808
  cwlor_exit:
806
  cwlor_exit:
809
    mov  al,[colcount]
807
    mov  al,[colcount]
810
    cmp  al,[checkcount]
808
    cmp  al,[checkcount]
811
  cw_exit:
809
  cw_exit:
812
;    debug_print <13,10>
810
;    debug_print <13,10>
813
    pop esi ecx ebx eax
811
    pop esi ecx ebx eax
814
    ret
812
    ret
815
 
813
 
816
;   *********************************************
814
;   *********************************************
817
;   **** WHETHER LASERS DESTROY SOMETHING *******
815
;   **** WHETHER LASERS DESTROY SOMETHING *******
818
;   *********************************************
816
;   *********************************************
819
 
817
 
820
check_lasers:
818
check_lasers:
821
    pusha
819
    pusha
822
    xor  edx,edx
820
    xor  edx,edx
823
    mov  ecx,[fld_size]
821
    mov  ecx,[fld_size]
824
  cl_loop:
822
  cl_loop:
825
    push ecx edx
823
    push ecx edx
826
    mov  cl,[field+edx]
824
    mov  cl,[field+edx]
827
    sub  cl,tLaserW
825
    sub  cl,tLaserW
828
    jl   cl_exit
826
    jl   cl_exit
829
  cl_begin:
827
  cl_begin:
830
    call get_cell_at
828
    call get_cell_at
831
    cmp  al,tLaserW
829
    cmp  al,tLaserW
832
    jae  cl_destroy
830
    jae  cl_destroy
833
    cmp  al,tBroken
831
    cmp  al,tBroken
834
    je   cl_destroy
832
    je   cl_destroy
835
    cmp  al,tEmpty
833
    cmp  al,tEmpty
836
    je   no_cl_destroy
834
    je   no_cl_destroy
837
    cmp  al,tHole
835
    cmp  al,tHole
838
    je   no_cl_destroy
836
    je   no_cl_destroy
839
    cmp  al,tPlayer
837
    cmp  al,tPlayer
840
    jne  cl_exit
838
    jne  cl_exit
841
    mov  ecx,0x00ac0000
839
    mov  ecx,0x00ac0000
842
    mov  edx,lose_msg
840
    mov  edx,lose_msg
843
    mov  esi,lose_msg_end-lose_msg  ; print loose message
841
    mov  esi,lose_msg_end-lose_msg  ; print loose message
844
    mov  byte[winmode],WM_LOSE
842
    mov  byte[winmode],WM_LOSE
845
    mov  ebx,WIN_XY
843
    mov  ebx,WIN_XY
846
    mov  eax,4
844
    mov  eax,4
847
    int  0x40
845
    int  0x40
848
    jmp  cl_exit
846
    jmp  cl_exit
849
  cl_destroy:
847
  cl_destroy:
850
    mov  byte[field+ebx],0
848
    mov  byte[field+ebx],0
851
  no_cl_destroy:
849
  no_cl_destroy:
852
    mov  edx,ebx
850
    mov  edx,ebx
853
    jmp  cl_begin
851
    jmp  cl_begin
854
  cl_exit:
852
  cl_exit:
855
    pop  edx ecx
853
    pop  edx ecx
856
    inc  edx
854
    inc  edx
857
    loop cl_loop
855
    loop cl_loop
858
    popa
856
    popa
859
    ret
857
    ret
860
 
858
 
861
;   *********************************************
859
;   *********************************************
862
;   *** USED BY CHECK_WIN IN SOKONEX & SOKOLOR **
860
;   *** USED BY CHECK_WIN IN SOKONEX & SOKOLOR **
863
;   *********************************************
861
;   *********************************************
864
 
862
 
865
scan_root:                ; input:   dx-beginning cell, ebx-what to search
863
scan_root:                ; input:   dx-beginning cell, ebx-what to search
866
    push esi
864
    push esi
867
    mov  edi,srch         ; output:  eax-number of win_obj found
865
    mov  edi,srch         ; output:  eax-number of win_obj found
868
    mov  eax,0xfff
866
    mov  eax,0xfff
869
    movzx ecx,[checkcount]
867
    movzx ecx,[checkcount]
870
    inc  ecx
868
    inc  ecx
871
    cld
869
    cld
872
    rep  stosw            ; clearing area for scan
870
    rep  stosw            ; clearing area for scan
873
    movzx ebx,dx
871
    movzx ebx,dx
874
    and  edx,eax          ; dx-cell number to compare with
872
    and  edx,eax          ; dx-cell number to compare with
875
    shr  ebx,12           ; bl-obj id
873
    shr  ebx,12           ; bl-obj id
876
    mov  [color],bl
874
    mov  [color],bl
877
    mov  esi,srch
875
    mov  esi,srch
878
    mov  edi,eax          ; mask to extract cell
876
    mov  edi,eax          ; mask to extract cell
879
    mov  word[srch],dx
877
    mov  word[srch],dx
880
  sr_loop:
878
  sr_loop:
881
    lodsw
879
    lodsw
882
    push esi              ; saving scan pointer
880
    push esi              ; saving scan pointer
883
       movzx edx,ax       ; edx-[dirs*4][cell*12]
881
       movzx edx,ax       ; edx-[dirs*4][cell*12]
884
       and  edx,edi
882
       and  edx,edi
885
;       debug_print ' >'
883
;       debug_print ' >'
886
       mov  ecx,4
884
       mov  ecx,4
887
  sr_dir_loop1:
885
  sr_dir_loop1:
888
;       debug_print '.'
886
;       debug_print '.'
889
       push ecx           ; saving dir counter
887
       push ecx           ; saving dir counter
890
         lea  ebx,[ecx+11]
888
         lea  ebx,[ecx+11]
891
         bts  word[esi-2],bx
889
         bts  word[esi-2],bx
892
         jc   sr_endloop      ; this entry is already processed
890
         jc   sr_endloop      ; this entry is already processed
893
;         debug_print '^'
891
;         debug_print '^'
894
         dec  ecx             ; cl-direction
892
         dec  ecx             ; cl-direction
895
         call get_cell_at     ; bx-new position, al-object
893
         call get_cell_at     ; bx-new position, al-object
896
;         cmp  [workmode],sSokonex
894
;         cmp  [workmode],sSokonex
897
;         jne  no_sr_nex
895
;         jne  no_sr_nex
898
         call chk_win_obj
896
         call chk_win_obj
899
         jne  sr_endloop      ; not a win_obj there
897
         jne  sr_endloop      ; not a win_obj there
900
;         debug_print '@'
898
;         debug_print '@'
901
         cmp  [workmode],sSokolor
899
         cmp  [workmode],sSokolor
902
         jne  no_sr_lor
900
         jne  no_sr_lor
903
         cmp  al,[color]
901
         cmp  al,[color]
904
         jne  sr_endloop
902
         jne  sr_endloop
905
       no_sr_lor:
903
       no_sr_lor:
906
         push esi
904
         push esi
907
         mov  esi,srch        ; let us search for existing entries
905
         mov  esi,srch        ; let us search for existing entries
908
       sr_loop1:
906
       sr_loop1:
909
         lodsw
907
         lodsw
910
         and  eax,edi         ; eax-cell w/o dirs
908
         and  eax,edi         ; eax-cell w/o dirs
911
         cmp  eax,ebx
909
         cmp  eax,ebx
912
         je   sr_foundentry   ; this is the entry we're seeking for
910
         je   sr_foundentry   ; this is the entry we're seeking for
913
         cmp  word[esi],0xfff
911
         cmp  word[esi],0xfff
914
         jnz  sr_loop1        ; next entry
912
         jnz  sr_loop1        ; next entry
915
    ; we reached empty area
913
    ; we reached empty area
916
         mov  [esi],bx
914
         mov  [esi],bx
917
         add  esi,2
915
         add  esi,2
918
       sr_foundentry:
916
       sr_foundentry:
919
         mov  eax,15
917
         mov  eax,15
920
         sub  eax,ecx
918
         sub  eax,ecx
921
         bts  [esi-2],ax      ; mark entry as used
919
         bts  [esi-2],ax      ; mark entry as used
922
         pop  esi
920
         pop  esi
923
;         inc  [e_fnd]         ; one more obj found
921
;         inc  [e_fnd]         ; one more obj found
924
     sr_endloop:
922
     sr_endloop:
925
       pop  ecx
923
       pop  ecx
926
       loop sr_dir_loop1
924
       loop sr_dir_loop1
927
;       jmp  tttt
925
;       jmp  tttt
928
;     sr_dir_loop:
926
;     sr_dir_loop:
929
;       jmp  sr_dir_loop1
927
;       jmp  sr_dir_loop1
930
;     tttt:
928
;     tttt:
931
    pop esi
929
    pop esi
932
    cmp  word[esi],0xfff
930
    cmp  word[esi],0xfff
933
    jne  sr_loop
931
    jne  sr_loop
934
    mov  eax,esi
932
    mov  eax,esi
935
    sub  eax,srch
933
    sub  eax,srch
936
    shr  eax,1
934
    shr  eax,1
937
    pop  esi
935
    pop  esi
938
;    debug_print_dec eax
936
;    debug_print_dec eax
939
    ret
937
    ret
940
 
938
 
941
;   *********************************************
939
;   *********************************************
942
;   *** SPECIAL ROUTINE TO DRAW LASERS **********
940
;   *** SPECIAL ROUTINE TO DRAW LASERS **********
943
;   *********************************************
941
;   *********************************************
944
 
942
 
945
draw_lasers:
943
draw_lasers:
946
    xor  edx,edx
944
    xor  edx,edx
947
    mov  ecx,[fld_size]
945
    mov  ecx,[fld_size]
948
  dl_loop:
946
  dl_loop:
949
    push ecx edx
947
    push ecx edx
950
    mov  cl,[field+edx]
948
    mov  cl,[field+edx]
951
    sub  cl,tLaserW
949
    sub  cl,tLaserW
952
    jl   dl_eloop
950
    jl   dl_eloop
953
    inc  ch
951
    inc  ch
954
  dl_gca:
952
  dl_gca:
955
    call get_cell_at
953
    call get_cell_at
956
    cmp  al,tEmpty
954
    cmp  al,tEmpty
957
    je   dl_draw
955
    je   dl_draw
958
    cmp  al,tHole
956
    cmp  al,tHole
959
    jne  dl_eloop
957
    jne  dl_eloop
960
  dl_draw:
958
  dl_draw:
961
    call draw_beams
959
    call draw_beams
962
    mov  edx,ebx
960
    mov  edx,ebx
963
    jmp  dl_gca
961
    jmp  dl_gca
964
  dl_eloop:
962
  dl_eloop:
965
    pop  edx
963
    pop  edx
966
    inc  edx
964
    inc  edx
967
    pop  ecx
965
    pop  ecx
968
    loop dl_loop
966
    loop dl_loop
969
    ret
967
    ret
970
 
968
 
971
;   *********************************************
969
;   *********************************************
972
;   *** DRAWS LASER BEAMS IN CERTAIN DIRECTION **
970
;   *** DRAWS LASER BEAMS IN CERTAIN DIRECTION **
973
;   *********************************************
971
;   *********************************************
974
 
972
 
975
draw_beams:
973
draw_beams:
976
    pusha
974
    pusha
977
    mov esi,[levptr]
975
    mov esi,[levptr]
978
    movzx esi,byte[esi+1]
976
    movzx esi,byte[esi+1]
979
    mov  eax,ebx
977
    mov  eax,ebx
980
    xor  edx,edx
978
    xor  edx,edx
981
    div  esi
979
    div  esi
982
    movzx esi,cl
980
    movzx esi,cl
983
    dec  esi
981
    dec  esi
984
    shr  esi,1
982
    shr  esi,1
985
    and  esi,1
983
    and  esi,1
986
    shl  edx,20
984
    shl  edx,20
987
    mov  ebx,edx
985
    mov  ebx,edx
988
    shl  eax,20
986
    shl  eax,20
989
    mov  ecx,eax
987
    mov  ecx,eax
990
    add  ebx,dword[beam_xy+esi*8]
988
    add  ebx,dword[beam_xy+esi*8]
991
    add  ecx,dword[beam_xy+esi*8+4]
989
    add  ecx,dword[beam_xy+esi*8+4]
992
    mov  edx,0xe9e25c
990
    mov  edx,0xe9e25c
993
    mov  eax,13
991
    mov  eax,13
994
    int  0x40
992
    int  0x40
995
    popa
993
    popa
996
    ret
994
    ret
997
 
995
 
998
ud:
996
ud:
999
   ud2  ; debugging purposes only
997
   ud2  ; debugging purposes only
1000
 
998
 
1001
 
999
 
1002
;   *********************************************
1000
;   *********************************************
1003
;   *** COMPRESS LEVEL - NOT READY YET **********
1001
;   *** COMPRESS LEVEL - NOT READY YET **********
1004
;   *********************************************
1002
;   *********************************************
1005
 
1003
 
1006
;    push    esi ebx ;ecx
1004
;    push    esi ebx ;ecx
1007
;    xchg    ebx,edi
1005
;    xchg    ebx,edi
1008
;    mov     esi,edi                 ; esi,edi - beginning
1006
;    mov     esi,edi                 ; esi,edi - beginning
1009
;; ebx - end of unpacked field
1007
;; ebx - end of unpacked field
1010
;  first_enc:
1008
;  first_enc:
1011
;    lodsb                           ; al - first byte
1009
;    lodsb                           ; al - first byte
1012
;    shl     ax,8                    ; ah - this byte, al=0
1010
;    shl     ax,8                    ; ah - this byte, al=0
1013
;  next_enc:
1011
;  next_enc:
1014
;    cmp     esi,ebx
1012
;    cmp     esi,ebx
1015
;    jae     exit_enc
1013
;    jae     exit_enc
1016
;;    movzx   ecx,byte[esi]
1014
;;    movzx   ecx,byte[esi]
1017
;;    debug_print_dec ecx
1015
;;    debug_print_dec ecx
1018
;    cmp     ah,byte[esi]
1016
;    cmp     ah,byte[esi]
1019
;    jne     newchar
1017
;    jne     newchar
1020
;    inc     esi
1018
;    inc     esi
1021
;    inc     al
1019
;    inc     al
1022
;    cmp     al,15
1020
;    cmp     al,15
1023
;    jb      next_enc
1021
;    jb      next_enc
1024
;  newchar:
1022
;  newchar:
1025
;    shl     al,4
1023
;    shl     al,4
1026
;    shr     ax,4
1024
;    shr     ax,4
1027
;    stosb
1025
;    stosb
1028
;    jmp     first_enc
1026
;    jmp     first_enc
1029
;  exit_enc:
1027
;  exit_enc:
1030
;    shl     al,4
1028
;    shl     al,4
1031
;    shr     ax,4
1029
;    shr     ax,4
1032
;    stosb
1030
;    stosb
1033
;    mov     al,0xff
1031
;    mov     al,0xff
1034
;    stosb
1032
;    stosb
1035
;    pop     ebx esi ecx
1033
;    pop     ebx esi ecx
1036
;
1034
;
1037
;    dec     ecx
1035
;    dec     ecx
1038
;    jcxz    outcycle
1036
;    jcxz    outcycle
1039
;    jmp     next_lev
1037
;    jmp     next_lev
1040
;  outcycle:
1038
;  outcycle:
1041
 
1039
 
1042
 
1040
 
1043
; ‡¤¥áì ­ å®¤ïâáï ¤ ­­ë¥ ¯à®£à ¬¬ë:
1041
; ‡¤¥áì ­ å®¤ïâáï ¤ ­­ë¥ ¯à®£à ¬¬ë:
1044
 
1042
 
1045
; ¨­â¥àä¥©á ¯à®£à ¬¬ë ¤¢ãï§ëç­ë© - § ¤ ©â¥ ï§ëª ¢ macros.inc
1043
; ¨­â¥àä¥©á ¯à®£à ¬¬ë ¤¢ãï§ëç­ë© - § ¤ ©â¥ ï§ëª ¢ macros.inc
1046
load_char:
1044
load_char:
1047
if lang eq ru
1045
if lang eq ru
1048
     db '‡ £à㧨âì'
1046
     db '‡ £à㧨âì'
1049
else
1047
else
1050
     db 'Open file'
1048
     db 'Open file'
1051
end if
1049
end if
1052
loadlen:
1050
loadlen:
1053
 
1051
 
1054
ll_msg:
1052
ll_msg:
1055
if lang eq ru
1053
if lang eq ru
1056
     db '‚ë¡¥à¨â¥ ã஢¥­ì'
1054
     db '‚ë¡¥à¨â¥ ã஢¥­ì'
1057
else
1055
else
1058
     db 'Choose a level'
1056
     db 'Choose a level'
1059
end if
1057
end if
1060
     db ' (0-9, PgUp, PgDn)'
1058
     db ' (0-9, PgUp, PgDn)'
1061
ll_msg_end:
1059
ll_msg_end:
1062
 
1060
 
1063
fn_input:
1061
fn_input:
1064
;   db 'cnf'
1062
;   db 'cnf'
1065
;    db 'soko-4.lev'
1063
;    db 'soko-4.lev'
1066
if lang eq ru
1064
if lang eq ru
1067
     db '¨«¨ ¢¢¥¤¨â¥ ¨¬ï ä ©« '
1065
     db '¨«¨ ¢¢¥¤¨â¥ ¨¬ï ä ©« '
1068
else
1066
else
1069
     db 'or enter a filename'
1067
     db 'or enter a filename'
1070
end if
1068
end if
1071
inp_end:
1069
inp_end:
1072
     rb 256-(inp_end-fn_input)
1070
     rb 256-(inp_end-fn_input)
1073
 
1071
 
1074
win_msg:
1072
win_msg:
1075
if lang eq ru
1073
if lang eq ru
1076
     db '“à !!! ‚ë ¯à®è«¨ ã஢¥­ì!'
1074
     db '“à !!! ‚ë ¯à®è«¨ ã஢¥­ì!'
1077
else
1075
else
1078
     db "You've completed the level!"
1076
     db "You've completed the level!"
1079
end if
1077
end if
1080
win_msg_end:
1078
win_msg_end:
1081
 
1079
 
1082
lose_msg:
1080
lose_msg:
1083
if lang eq ru
1081
if lang eq ru
1084
     db '‚ë ¯ à «¨§®¢ ­ë! à®¨£àëè...'
1082
     db '‚ë ¯ à «¨§®¢ ­ë! à®¨£àëè...'
1085
else
1083
else
1086
     db "You're paralized! Game over..."
1084
     db "You're paralized! Game over..."
1087
end if
1085
end if
1088
lose_msg_end:
1086
lose_msg_end:
1089
 
1087
 
1090
zagolovok:
1088
zagolovok:
1091
     db   'Sokoban', 0
1089
     db   'Sokoban', 0
1092
 
1090
 
1093
 
1091
 
1094
pic_map:
1092
pic_map:
1095
    db 0xf,9,0,0,1,1,5,6
1093
    db 0xf,9,0,0,1,1,5,6
1096
pm_nex:
1094
pm_nex:
1097
    db 2,7,8,3,4,0xa,0xa,0xa,0xa
1095
    db 2,7,8,3,4,0xa,0xa,0xa,0xa
1098
pm_col:
1096
pm_col:
1099
    db 0xb,0xc,0xd,0xe
1097
    db 0xb,0xc,0xd,0xe
1100
 
1098
 
1101
beam_xy:
1099
beam_xy:
1102
    dd (FLD_LEFT+7) shl 16+2, FLD_TOP2+16
1100
    dd (FLD_LEFT+7) shl 16+2, FLD_TOP2+16
1103
    dd FLD_LEFT2+16, (FLD_TOP+7) shl 16+2
1101
    dd FLD_LEFT2+16, (FLD_TOP+7) shl 16+2
1104
 
1102
 
1105
ll_num db '00x.'
1103
ll_num db '00x.'
1106
 
1104
 
1107
move_map dd -1,+0,-0,1      ; 0 - W, 1 - S, 2 - N, 3 - E
1105
move_map dd -1,+0,-0,1      ; 0 - W, 1 - S, 2 - N, 3 - E
1108
 
1106
 
1109
stdlev     db 'SOKO-0.LEV',0
1107
stdlev     db 'SOKO-0.LEV',0
1110
stdlev_len:
1108
stdlev_len:
1111
 
1109
 
1112
inp_pos    dd inp_end-fn_input
1110
inp_pos    dd inp_end-fn_input
1113
entered    dd 0
1111
entered    dd 0
1114
 
1112
 
1115
file_info:
1113
file_info:
1116
           dd 0                 ; subfunction - read
1114
           dd 0                 ; subfunction - read
1117
           dd 0, 0              ; file offset
1115
           dd 0, 0              ; file offset
1118
           dd 0x20000           ; number of bytes to read
1116
           dd 0x20000           ; number of bytes to read
1119
cnf_level  dd strip             ; data buffer
1117
cnf_level  dd strip             ; data buffer
1120
file_name  db CUR_DIR           ; Filename
1118
file_name  db CUR_DIR           ; Filename
1121
path_end   db 'SKIN.'
1119
path_end   db 'SKIN.'
1122
file_num   db 'RAW',0
1120
file_num   db 'RAW',0
1123
 
1121
 
1124
           rb 256-($-file_name)
1122
           rb 256-($-file_name)
1125
 
1123
 
1126
I_END:  ; ª®­¥æ ¯à®£à ¬¬ë
1124
I_END:  ; ª®­¥æ ¯à®£à ¬¬ë
1127
 
1125
 
1128
winmode         db ?
1126
winmode         db ?
1129
scanptr         dd ?
1127
scanptr         dd ?
1130
levpage         dd ?
1128
levpage         dd ?
1131
workmode        db ?
1129
workmode        db ?
1132
player          dw ?
1130
player          dw ?
1133
fld_size        dd ?
1131
fld_size        dd ?
1134
levptr          dd ?
1132
levptr          dd ?
1135
wnd_height      dd ?
1133
wnd_height      dd ?
1136
wnd_width       dd ?
1134
wnd_width       dd ?
1137
color           db ?
1135
color           db ?
1138
colcount        db ?
1136
colcount        db ?
1139
levelcount      dd ?
1137
levelcount      dd ?
1140
checkcount      db ?
1138
checkcount      db ?
1141
checkpoint      rw 256
1139
checkpoint      rw 256
1142
levelmap        rd 1024
1140
levelmap        rd 1024
1143
strip           rb SKIN_SIZE
1141
strip           rb SKIN_SIZE
1144
 
1142
 
1145
workarea:
1143
workarea:
1146
  srch  rb 0x10000-($-workarea)
1144
  srch  rb 0x10000-($-workarea)
1147
 
1145
 
1148
level_start rb 0x20000
1146
level_start rb 0x20000
1149
field:
1147
field: