Subversion Repositories Kolibri OS

Rev

Rev 4477 | Rev 4617 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
4477 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
3545 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  IRC client for KolibriOS                                       ;;
7
;;                                                                 ;;
8
;;   Written by hidnplayr@kolibrios.org,                           ;;
9
;;     text encoder/decoder by Clevermouse.                        ;;
10
;;                                                                 ;;
11
;;         GNU GENERAL PUBLIC LICENSE                              ;;
12
;;          Version 2, June 1991                                   ;;
13
;;                                                                 ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
4477 hidnplayr 16
version equ '0.16'
3545 hidnplayr 17
 
18
; connection status
19
STATUS_DISCONNECTED     = 0
20
STATUS_RESOLVING        = 1
21
STATUS_CONNECTING       = 2
22
STATUS_CONNECTED        = 3
23
 
24
; window flags
25
FLAG_UPDATED            = 1 shl 0
4143 hidnplayr 26
FLAG_RECEIVING_NAMES    = 1 shl 1
3545 hidnplayr 27
 
28
; window types
4143 hidnplayr 29
WINDOWTYPE_NONE         = 0
30
WINDOWTYPE_SERVER       = 1
31
WINDOWTYPE_CHANNEL      = 2
32
WINDOWTYPE_CHAT         = 3
33
WINDOWTYPE_LIST         = 4
34
WINDOWTYPE_DCC          = 5
3545 hidnplayr 35
 
36
; supported encodings
37
CP866                   = 0
38
CP1251                  = 1
39
UTF8                    = 2
40
 
41
; settings
42
USERCMD_MAX_SIZE        = 400
43
 
44
WIN_MIN_X               = 600
4143 hidnplayr 45
WIN_MIN_Y               = 170
3545 hidnplayr 46
 
47
TEXT_X                  = 5
4143 hidnplayr 48
TEXT_Y                  = TOP_Y + 2
3545 hidnplayr 49
 
4143 hidnplayr 50
TOP_Y                   = 24
51
BOTTOM_Y                = 15
3545 hidnplayr 52
 
53
MAX_WINDOWS             = 20
54
MAX_USERS               = 4096
4477 hidnplayr 55
TEXT_BUFFERSIZE         = 1024*1024
3545 hidnplayr 56
 
57
MAX_NICK_LEN            = 32
58
MAX_REAL_LEN            = 32    ; realname
59
MAX_SERVER_NAME         = 256
60
 
61
MAX_CHANNEL_LEN         = 40
62
MAX_CHANNELS            = 37
63
 
64
MAX_COMMAND_LEN         = 512
65
 
66
TIMESTAMP               = 3     ; 3 = hh:mm:ss, 2 = hh:mm, 0 = no timestamp
67
 
68
MAX_WINDOWNAME_LEN      = 256
69
 
70
WINDOW_BTN_START        = 100
3981 hidnplayr 71
WINDOW_BTN_CLOSE        = 2
72
WINDOW_BTN_LIST         = 3
3545 hidnplayr 73
 
4143 hidnplayr 74
SCROLLBAR_WIDTH         = 14
75
USERLIST_WIDTH          = 100
3545 hidnplayr 76
 
4143 hidnplayr 77
FONT_HEIGHT             = 9
78
FONT_WIDTH              = 6
3545 hidnplayr 79
 
80
format binary as ""
81
 
82
use32
83
 
84
        org     0x0
85
 
86
        db      'MENUET01'              ; 8 byte id
87
        dd      1                       ; header version
88
        dd      START                   ; program start
89
        dd      I_END                   ; program image size
90
        dd      IM_END+2048             ; required amount of memory
91
        dd      IM_END+2048
92
        dd      param
93
        dd      path
94
 
3618 hidnplayr 95
include "../../macros.inc"
96
include "../../proc32.inc"
97
include "../../dll.inc"
98
include "../../network.inc"
99
include "../../struct.inc"
4477 hidnplayr 100
include "../../develop/libraries/box_lib/trunk/box_lib.mac"
3545 hidnplayr 101
 
102
struct  window
4143 hidnplayr 103
        data_ptr        dd ?
3545 hidnplayr 104
        flags           db ?
105
        type            db ?
106
        name            rb MAX_WINDOWNAME_LEN
107
        users           dd ?
108
        users_scroll    dd ?
109
        selected        dd ?            ; selected user, 0 if none selected
4143 hidnplayr 110
 
111
        text_start      dd ?            ; pointer to current textbox data
112
        text_end        dd ?
113
        text_print      dd ?            ; pointer to first character to print on screen
114
        text_line_print dd ?            ; line number of that character
115
        text_write      dd ?            ; write pointer
116
        text_lines      dd ?            ; total number of lines
117
        text_scanned    dd ?            ; pointer to beginning of unscanned data (we still need to count number of lines, insert newline characters,..)
118
 
3545 hidnplayr 119
ends
120
 
121
struct  window_data
4143 hidnplayr 122
        text            rb TEXT_BUFFERSIZE
3545 hidnplayr 123
        names           rb MAX_NICK_LEN * MAX_USERS
124
ends
125
 
126
include "encodings.inc"
4143 hidnplayr 127
include "window.inc"
3545 hidnplayr 128
include "serverparser.inc"
129
include "userparser.inc"
130
include "socket.inc"
131
include "gui.inc"
132
include "users.inc"
4060 hidnplayr 133
include "textbox.inc"
3545 hidnplayr 134
 
135
 
136
START:
137
 
138
        mcall   68, 11                  ; init heap so we can allocate memory dynamically
139
 
140
; wanted events
3981 hidnplayr 141
        mcall   40, EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_STACK+EVM_MOUSE+EVM_MOUSE_FILTER
3545 hidnplayr 142
 
143
; load libraries
144
        stdcall dll.Load, @IMPORT
145
        test    eax, eax
146
        jnz     exit
147
 
148
; find path to main settings file (ircc.ini)
149
        mov     edi, path               ; Calculate the length of zero-terminated string
150
        xor     al, al
151
        mov     ecx, 1024
152
        repne   scasb
153
        dec     edi
154
        mov     eax, '.ini'
155
        stosd
156
        xor     al, al
157
        stosb
158
 
159
; Fill the window buffer with zeros
160
        mov     edi, windows
161
        mov     ecx, (sizeof.window*MAX_WINDOWS+3)/4
162
        xor     eax, eax
163
        rep     stosd
164
 
165
; clear command area too
166
        mov     edi, servercommand
167
        mov     ecx, 600/4
168
        rep     stosd
169
 
170
; allocate window data block
4143 hidnplayr 171
        mov     ebx, windows
4477 hidnplayr 172
        call    window_create_textbox
4143 hidnplayr 173
        test    eax, eax
174
        jz      error
3545 hidnplayr 175
        mov     [ebx + window.type], WINDOWTYPE_SERVER
176
 
177
; get system colors
178
        mcall   48, 3, colors, 40
179
 
180
; set edit box and scrollbar colors
181
        mov     eax, [colors.work]
182
        mov     [scroll1.bg_color], eax
4143 hidnplayr 183
        mov     [scroll2.bg_color], eax
3545 hidnplayr 184
 
185
        mov     eax, [colors.work_button]
186
        mov     [scroll1.front_color], eax
4143 hidnplayr 187
        mov     [scroll2.front_color], eax
3545 hidnplayr 188
 
189
        mov     eax, [colors.work_text]
190
        mov     [scroll1.line_color], eax
4143 hidnplayr 191
        mov     [scroll2.line_color], eax
3545 hidnplayr 192
 
4143 hidnplayr 193
        mov     [scroll1.type], 1               ; 0 = simple, 1 = skinned
194
        mov     [scroll2.type], 1
195
 
3545 hidnplayr 196
; get settings from ini
197
        invoke  ini.get_str, path, str_user, str_nick, user_nick, MAX_NICK_LEN, default_nick
198
        invoke  ini.get_str, path, str_user, str_real, user_real_name, MAX_REAL_LEN, default_real
3981 hidnplayr 199
        invoke  ini.get_str, path, str_user, str_quitmsg, quit_msg, 250, default_quit
3545 hidnplayr 200
 
201
; Welcome user
202
        mov     esi, str_welcome
203
        call    print_text2
204
 
4477 hidnplayr 205
; Check if parameter contains an URL
206
        cmp     byte[param], 0
207
        je      @f
208
        mov     esi, param
209
        mov     ecx, 1024
210
        call    cmd_usr_server.now
211
  @@:
3545 hidnplayr 212
 
4477 hidnplayr 213
; Draw window a first time, so we can figure out skin size
214
        call    draw_window
215
 
3545 hidnplayr 216
redraw:
217
        call    draw_window
218
 
4477 hidnplayr 219
mainloop:
220
        mcall   10              ; wait for event
3545 hidnplayr 221
 
222
        dec     eax
223
        jz      redraw
224
 
225
        dec     eax
226
        jz      main_window_key
227
 
228
        dec     eax
229
        jz      button
230
 
231
        cmp     al, 3
232
        je      mouse
233
 
234
        call    process_network_event
235
 
4143 hidnplayr 236
        mov     edi, [window_active]
237
        test    [edi + window.flags], FLAG_UPDATED
3545 hidnplayr 238
        jz      .no_update
239
        call    draw_channel_text
4143 hidnplayr 240
        mov     edi, [window_active]
241
        cmp     [edi + window.type], WINDOWTYPE_CHANNEL
242
        jne     .no_update
243
        call    draw_channel_list
3545 hidnplayr 244
  .no_update:
245
 
4477 hidnplayr 246
        jmp     mainloop
3545 hidnplayr 247
 
248
button:
249
 
250
        mcall   17              ; get id
3981 hidnplayr 251
        ror     eax, 8
3545 hidnplayr 252
 
253
        cmp     ax, 1           ; close program
254
        je      exit
255
 
3981 hidnplayr 256
        cmp     ax, WINDOW_BTN_CLOSE
3545 hidnplayr 257
        jne     @f
4143 hidnplayr 258
        call    cmd_usr_close_window
4477 hidnplayr 259
        jmp     mainloop
3981 hidnplayr 260
 
261
  @@:
262
        cmp     ax, WINDOW_BTN_LIST
263
        jne     @f
264
 
265
        push    eax
266
 
3545 hidnplayr 267
        mcall   37, 1           ; Get mouse position
268
        sub     ax, TEXT_Y
4143 hidnplayr 269
        mov     bl, FONT_HEIGHT
3545 hidnplayr 270
        div     bl
271
        and     eax, 0x000000ff
272
        inc     eax
273
        add     eax, [scroll1.position]
3981 hidnplayr 274
        mov     ebx, [window_active]
3545 hidnplayr 275
        mov     [ebx + window.selected], eax
276
 
4143 hidnplayr 277
        call    draw_channel_list
3545 hidnplayr 278
 
3981 hidnplayr 279
        pop     eax
280
        test    eax, 1 shl 25   ; Right mouse button pressed?
4477 hidnplayr 281
        jz      mainloop
3981 hidnplayr 282
 
4477 hidnplayr 283
; TODO: check if selected nick is my nick!
284
 
3981 hidnplayr 285
; Right mouse BTN was pressed, open chat window
286
        mov     ebx, [window_active]
287
        mov     eax, [ebx + window.selected]
288
        dec     eax
289
        imul    eax, MAX_NICK_LEN
290
        mov     ebx, [ebx + window.data_ptr]
291
        lea     esi, [ebx + window_data.names + eax]
292
        call    window_open
293
        push    [window_print]
294
        pop     [window_active]
295
        call    redraw
296
 
4477 hidnplayr 297
        jmp     mainloop
3545 hidnplayr 298
 
299
  @@:
300
        sub     ax, WINDOW_BTN_START
301
        jb      exit
302
 
303
        cmp     ax, MAX_WINDOWS
304
        ja      exit
305
 
4143 hidnplayr 306
; OK, time to switch to another window.
3545 hidnplayr 307
        mov     dx, sizeof.window
308
        mul     dx
309
        shl     edx, 16
310
        mov     dx, ax
311
        add     edx, windows
4143 hidnplayr 312
        cmp     [edx + window.type], WINDOWTYPE_NONE
3545 hidnplayr 313
        je      exit
3981 hidnplayr 314
        mov     [window_active], edx
4143 hidnplayr 315
 
316
        mov     [scroll2.position], 1           ;;; FIXME
3545 hidnplayr 317
        call    draw_window
318
 
4477 hidnplayr 319
        jmp     mainloop
3981 hidnplayr 320
 
3545 hidnplayr 321
exit:
3981 hidnplayr 322
 
323
        cmp     [socketnum], 0
324
        je      @f
325
        mov     esi, quit_msg
326
        call    cmd_usr_quit_server
327
  @@:
328
 
4143 hidnplayr 329
error:
330
 
3545 hidnplayr 331
        mcall   -1
332
 
333
 
334
 
335
main_window_key:
336
 
337
        mcall   2
338
 
339
        push    dword edit1
340
        call    [edit_box_key]
341
 
4143 hidnplayr 342
;        cmp     ah, 178
343
;        jne     .no_up
344
;
4477 hidnplayr 345
;        jmp     mainloop
4143 hidnplayr 346
;
347
;
348
;  .no_up:
349
;        cmp     ah, 177
350
;        jne     .no_down
351
;
4477 hidnplayr 352
;        jmp     mainloop
4143 hidnplayr 353
;
354
;  .no_down:
3545 hidnplayr 355
        cmp     ah, 13          ; enter
356
        jne     no_send2
357
 
358
        call    user_parser
359
 
4143 hidnplayr 360
        mov     eax, [edit1.size]
361
 
3545 hidnplayr 362
        mov     [edit1.size], 0
363
        mov     [edit1.pos], 0
364
 
365
        push    dword edit1
366
        call    [edit_box_draw]
367
 
368
        call    draw_channel_text
369
 
4477 hidnplayr 370
        jmp     mainloop
3545 hidnplayr 371
  no_send2:
372
 
4477 hidnplayr 373
        jmp     mainloop
3545 hidnplayr 374
 
375
mouse:
376
        push    dword edit1
377
        call    [edit_box_mouse]
378
 
4477 hidnplayr 379
;        mcall   37, 7
380
;        movsx   eax, ax
381
;        add     [scroll2.position], eax
382
 
4143 hidnplayr 383
; TODO: check if scrollbar is active?
384
        mov     edi, [window_active]
385
        cmp     [edi + window.type], WINDOWTYPE_CHANNEL
386
        jne     @f
3545 hidnplayr 387
        push    [scroll1.position]
388
        push    dword scroll1
4143 hidnplayr 389
        call    [scrollbar_mouse]
3545 hidnplayr 390
        pop     eax
391
        cmp     eax, [scroll1.position] ; did the scrollbar move?
392
        je      @f
4143 hidnplayr 393
        call    draw_channel_list
3545 hidnplayr 394
  @@:
395
 
4143 hidnplayr 396
; TODO: check if scrollbar is active?
397
        mov     edi, [window_active]
398
        mov     eax, [edi + window.text_lines]
399
        cmp     eax, [textbox_height]
400
        jbe     @f
401
        push    dword scroll2
402
        call    [scrollbar_mouse]
4477 hidnplayr 403
        mov     edi, [window_active]
4143 hidnplayr 404
        mov     edx, [scroll2.position]
405
        sub     edx, [edi + window.text_line_print]
406
        je      @f
407
        call    draw_channel_text.scroll_to_pos
408
  @@:
409
 
4477 hidnplayr 410
        jmp     mainloop
3545 hidnplayr 411
 
412
 
413
; DATA AREA
414
 
415
encoding_text:
416
db      'CP866 '
417
db      'CP1251'
418
db      'UTF-8 '
419
encoding_text_len = 6
420
 
4477 hidnplayr 421
join_header             db 3, '3* ', 0
422
quit_header             db 3, '5* ', 0
423
nick_header             db 3, '2* ', 0
424
kick_header             db 3, '5* ', 0
425
mode_header             db 3, '2* ', 0
426
part_header             db 3, '5* ', 0
427
topic_header            db 3, '3* ', 0
428
action_header           db 3, '6* ', 0
429
ctcp_header             db 3, '13-> [', 0
430
msg_header              db 3, '7-> *', 0
431
ctcp_version            db '] VERSION', 10, 0
432
ctcp_ping               db '] PING', 10, 0
433
ctcp_time               db '] TIME', 10, 0
434
 
3545 hidnplayr 435
has_left_channel        db ' has left ', 0
436
joins_channel           db ' has joined ', 0
437
is_now_known_as         db ' is now known as ', 0
438
has_quit_irc            db ' has quit IRC', 10, 0
4477 hidnplayr 439
 
3545 hidnplayr 440
sets_mode               db ' sets mode ', 0
4596 hidnplayr 441
str_kicked              db ' is kicked from ', 0
442
str_by                  db ' by ', 0
4477 hidnplayr 443
str_nickchange          db 'Nickname is now ', 0
444
str_realchange          db 'Real name is now ', 0
445
str_talking             db 'Now talking in ', 0
446
str_topic               db 'Topic is "', 0
447
str_topic_end           db '".', 10, 0
448
str_setby               db 'Set by ', 0
3545 hidnplayr 449
 
4477 hidnplayr 450
str_connecting          db 3, '3* Connecting to ', 0
451
str_sockerr             db 3, '5* Socket error', 10, 0
452
str_dnserr              db 3, '5* Unable to resolve hostname', 10, 0
453
str_refused             db 3, '5* Connection refused', 10, 0
454
str_disconnected        db 3, '5* Server disconnected', 10, 0
455
str_reconnect           db 3, '5* Connection reset by user', 10, 0
456
str_notconnected        db 3, '5* Not connected to server', 10, 0
457
 
458
str_dotnewline          db '.',10, 0
459
str_newline             db 10, 0
460
str_1                   db 3, '13 -', 0
461
str_2                   db '- ', 0
462
 
463
str_help                db 10, 'following commands are available:', 10
464
                        db 10
465
                        db '/nick         : change nickname to ', 10
466
                        db '/real    : change real name to ', 10
467
                        db '/server 
: connect to server
', 10
468
                        db '/code         : change codepage to cp866, cp1251, or utf8', 10, 0
469
 
470
str_welcome             db 3, '3 ___', 3, '7__________', 3, '6_________  ', 3, '4         __   __               __', 10
471
                        db 3, '3|   \', 3, '7______   \', 3, '6_   ___ \ ', 3, '4   ____ |  | |__| ____   _____/  |_', 10
472
                        db 3, '3|   |', 3, '7|       _/', 3, '6    \  \/ ', 3, '4 _/ ___\|  | |  |/ __ \ /    \   __\', 10
473
                        db 3, '3|   |', 3, '7|    |   \', 3, '6     \____', 3, '4 \  \___|  |_|  \  ___/|   |  \  |', 10
474
                        db 3, '3|___|', 3, '7|____|_  /', 3, '6\______  /', 3, '4  \___  >____/__|\___  >___|  /__|', 10
475
                        db 3, '3     ', 3, '7       \/ ', 3, '6       \/ ', 3, '4      \/             \/     \/', 10
476
                        db 10
477
                        db 'Welcome to the KolibriOS IRC client v', version, 10
478
                        db 10
479
                        db 'Type /help for help', 10, 10, 0
480
 
3545 hidnplayr 481
str_version             db 'VERSION '
4477 hidnplayr 482
str_programname         db 'KolibriOS IRC client v', version, 0
3545 hidnplayr 483
 
484
str_user                db 'user', 0
485
str_nick                db 'nick', 0
486
str_real                db 'realname', 0
487
str_email               db 'email', 0
3981 hidnplayr 488
str_quitmsg             db 'quitmsg', 0
3545 hidnplayr 489
 
490
default_nick            db 'kolibri_user', 0
491
default_real            db 'Kolibri User', 0
3981 hidnplayr 492
default_quit            db 'KolibriOS forever', 0
3545 hidnplayr 493
 
4143 hidnplayr 494
irc_colors              dd 0xffffff     ;  0 white
495
                        dd 0x000000     ;  1 black
496
                        dd 0x00007f     ;  2 blue (navy)
497
                        dd 0x009300     ;  3 green
498
                        dd 0xff0000     ;  4 red
499
                        dd 0x7f0000     ;  5 brown (maroon)
500
                        dd 0x9c009c     ;  6 purple
501
                        dd 0xfc7f00     ;  7 olive
502
                        dd 0xffff00     ;  8 yellow
503
                        dd 0x00fc00     ;  9 light green
504
                        dd 0x009393     ; 10 teal
505
                        dd 0x00ffff     ; 11 cyan
506
                        dd 0x0000fc     ; 12 royal blue
507
                        dd 0xff00ff     ; 13 pink
508
                        dd 0x7f7f7f     ; 14 grey
509
                        dd 0xd4d0c4     ; 15 light grey (silver)
510
 
3545 hidnplayr 511
sockaddr1:
512
        dw AF_INET4
4477 hidnplayr 513
.port   dw 0x0b1a       ; 6667          FIXMEEEEEE
3545 hidnplayr 514
.ip     dd 0
515
        rb 10
516
 
517
 
518
status                  dd STATUS_DISCONNECTED
519
 
520
 
4143 hidnplayr 521
textbox_height          dd 12                   ; in characters
522
textbox_width           dd 78                   ; in characters, not pixels ;)
523
 
3981 hidnplayr 524
window_active           dd windows
3545 hidnplayr 525
window_print            dd windows
526
 
527
align 4
528
@IMPORT:
529
 
530
library network,        'network.obj',\
531
        libini,         'libini.obj',\
532
        boxlib,         'box_lib.obj'
533
 
534
import  network,\
535
        getaddrinfo,    'getaddrinfo',\
536
        freeaddrinfo,   'freeaddrinfo',\
537
        inet_ntoa,      'inet_ntoa'
538
 
539
import  libini,\
540
        ini.get_str,    'ini_get_str',\
541
        ini.get_int,    'ini_get_int'
542
 
543
import  boxlib,\
4143 hidnplayr 544
        edit_box_draw,  'edit_box',\
545
        edit_box_key,   'edit_box_key',\
546
        edit_box_mouse, 'edit_box_mouse',\
547
        scrollbar_draw, 'scrollbar_v_draw',\
548
        scrollbar_mouse,'scrollbar_v_mouse'
3545 hidnplayr 549
 
550
        ;         width, left, top
551
edit1   edit_box  0, 0, 0, 0xffffff, 0x6f9480, 0, 0, 0, USERCMD_MAX_SIZE, usercommand, mouse_dd, ed_focus, 25, 25
4143 hidnplayr 552
        ;         xsize, xpos, ysize, ypos, btn_height, max, cur, pos, bgcol, frcol, linecol
553
scroll1 scrollbar SCROLLBAR_WIDTH, 0, 0, TOP_Y, SCROLLBAR_WIDTH, 0, 0, 0, 0, 0, 0, 1
554
scroll2 scrollbar SCROLLBAR_WIDTH, 0, 0, TOP_Y, SCROLLBAR_WIDTH, 0, 0, 0, 0, 0, 0, 1
3545 hidnplayr 555
 
3618 hidnplayr 556
usercommand     db '/server chat.freenode.net', 0
557
                rb MAX_COMMAND_LEN
558
 
4477 hidnplayr 559
I_END:
560
 
3545 hidnplayr 561
utf8_bytes_rest dd ?            ; bytes rest in current UTF8 sequence
562
utf8_char       dd ?            ; first bits of current UTF8 character
4477 hidnplayr 563
 
3545 hidnplayr 564
packetbuf       rb 1024         ; buffer for packets to server
565
path            rb 1024
566
param           rb 1024
567
 
568
servercommand   rb 600
569
 
570
thread_info     rb 1024
571
xsize           dd ?
572
ysize           dd ?
4477 hidnplayr 573
mouse_dd        dd ?
3545 hidnplayr 574
 
575
colors          system_colors
576
 
4477 hidnplayr 577
irc_server_name rb MAX_SERVER_NAME      ; TODO: move this server URL into window struct
578
socketnum       dd ?                    ; TODO: same for socket
3545 hidnplayr 579
 
580
user_nick       rb MAX_NICK_LEN
581
user_real_name  rb MAX_REAL_LEN
3981 hidnplayr 582
quit_msg        rb 250
3545 hidnplayr 583
 
4477 hidnplayr 584
diff16 "windows", 0, $ + 1*sizeof.window ;+ 6
3545 hidnplayr 585
windows         rb MAX_WINDOWS*sizeof.window
586
 
587
IM_END:
588