; box.s
; 推箱子,运行不需操作系统,自有引导扇区,软盘引导
; 玩法:W S A D 上下左右,Q 退出,R 重玩当前一关
; 初学汇编,求师友
; NASM 16位 实模式
; Ubuntu
; nasm -o box.bin box.s
; sudo dd if=box.bin of=/dev/fd0 bs=512 count=15 conv=notrunc
; Bochs 模拟
; 函数调用约定
; 参数从右向左压栈,由调用函数平衡栈
; 被调用函数返回后与调用前相比,栈中元素及栈大小不改变
; 被调用方不维护 ax, bx, cx, dx,但保证维护其它寄存器
; 函数返回值 ax, bx, cx, dx
; 代码为将来改进做好了准备(常数, 变量 和 未实现的函数)
; 如 人物各方向不同,移动动画,使用斜视图实现3D效果
; 常数
; 程序占用扇区总数,不超过 0xFFFF 字节
%define SEC_NUM 15
; 每个扇区大小 字节
%define SEC_SIZE 0x200
; 显示
%define VIDEO_ID 0x13
%define VIDEO_HORZ_P 320
%define VIDEO_VERT_P 200
%define VIDEO_P (VIDEO_HORZ_P*VIDEO_VERT_P)
%define VIDEO_SEG 0xA000
%define VIDEO_PAL_PORT 0x03C8
%define VIDEO_COL_PORT 0x03C9
; 栈,考虑对齐
%define STACK_TOP 0xFF00
%define STACK_SEG 0x8000
; 引导
%define BOOT_SEG 0x7C0
; 级别总数(级别为 1 .. LEVEL_MAX )
%define LEVEL_MAX 4
; 按键虚拟键码
%define VK_NULL 0xFFFF
%define VK_W ('W')
%define VK_A ('A')
%define VK_S ('S')
%define VK_D ('D')
%define VK_Q ('Q')
%define VK_R ('R')
; 游戏状态
%define GS_WIN 0x1
%define GS_QUIT 0x2
%define GS_REPLAY 0x3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 设置
[bits 16]
; org 0x7C00
; 初始化 cs, ip
jmp BOOT_SEG : BOOT
BOOT :
; 初始化段寄存器
mov ax, cs
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; 初始化 栈
mov ax, STACK_SEG
mov ss, ax
mov ax, STACK_TOP
mov sp, ax
; 读入整个程序
; 偷懒,假设要读取的扇区都在 0 磁道,若扇区数增加,需修改此段代码
mov ah, 0x2
mov al, SEC_NUM
dec al
; mov cx, 0x0001 悲剧!!!!
mov cx, 0x0002
mov dx, 0x0000
mov bx, SEC_SIZE
int 0x13
; 初始化显示方式
call initVideo
; 跳入 main 执行
call main
; 跳入 shutdown 关机
call shutdown
times (0x200-2-($-$$)) db 0
db 0x55
db 0xAA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 地图
;
; 地图单元
;
; * ------------
; ***** ^
; ********* |
; *************
; | *********|
; | + ***** | UNIT_VERT_P
; |+ * |
; + | +
; + | + |
; + |+ V
; 位置点--> @ ----------
;
; | |
; |UNIT_HORZ_P|
;
;
;
; 地图布局
; 单元点坐标以单元为单位,常量 *_U
; 像素点坐标以像素为单位,常量 *_P
; 坐标点格式(x,y),先水平,后垂直
; 单元点的像素坐标为其右下角像素的像素坐标
; 水平 MAP_HORZ_U 个单元
; 垂直 MAP_VERT_U 个单元
; 单元点(xu,yu) in [0 .. MAP_HORZ_U)*[0 .. MAP_VERT_U)
; 像素点(xp,yp) in [0 .. VIDEO_HORZ_P)*[0 .. VIDEO_VERT_P)
; 二维图片实现3D效果,暂未使用,待扩充
; 绘制从左上角单元开始,至右下角单元结束,实现3D效果
; 地图原点为地图左上角单元(xu=0,yu=0)的像素坐标
;
; +--------------------------> xu in [0 .. MAP_HORZ_U)
; | xp in [0 .. VIDEO_HORZ_P)
; | *
; | * *
; | * *
; yu | * *
; yp | * *
; v ----------* *------------
; | * *|
; DY_HORZ_P | * * | DY_VERT_P
; | * * |
; | * * |
; ----------+--------------@----+-------------
; | | |
; | DX_HORZ_P | |
; | | |
; DX_VERT_P
;
; 注意正负号,作为增量
%define DX_VERT_P (0)
%define DY_VERT_P (22)
%define DX_HORZ_P (22)
%define DY_HORZ_P (0)
%define UNIT_HORZ_P (22)
%define UNIT_VERT_P (22)
%define UNIT_P (UNIT_HORZ_P*UNIT_VERT_P)
%define MAP_HORZ_U 8
%define MAP_VERT_U 8
%define MAP_U (MAP_HORZ_U*MAP_VERT_U)
; 单元 id,一字节,使用位或,一个单元可以为 BOX+DEST 或BOX+FLOOR
%define UID_SPACE 0x01
%define UID_FLOOR 0x02
%define UID_WALL 0x04
%define UID_BOX 0x08
%define UID_DEST 0x10
%define UID_PLAYER 0x20
; 一字节
%define DIR_UP 0x0
%define DIR_DOWN 0x1
%define DIR_LEFT 0x2
%define DIR_RIGHT 0x3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void main()
; 主程序
main :
mov byte[level], 0x1
.PLAY :
movzx ax, byte[level]
cmp ax, LEVEL_MAX
ja .COMPLETE
call initOneLevel
call playOneLevel
cmp ax, GS_QUIT
je .QUIT
cmp ax, GS_REPLAY
je .REPLAY
cmp ax, GS_WIN
jne .ERR
inc byte[level]
.REPLAY :
jmp .PLAY
.COMPLETE :
call initOneLevel
jmp .EXIT
.QUIT :
mov byte[level], LEVEL_MAX+1
call initOneLevel
jmp .EXIT
.ERR :
jmp .EXIT
.EXIT :
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void shutdown()
; 关机
shutdown :
; 暂时死循环吧
jmp $
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void initOneLevel()
; 初始化 level 级别
initOneLevel :
push si
push di
movzx ax, byte[level]
mov cx, MAP_SIZE
mul cx
mov si, MAP_CUR
add si, ax
mov di, MAP_CUR
cld
rep movsb
pop di
pop si
call eraseAll
call drawAll
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax playOneLevel()
; 玩 level 级别
; 返回 GS_WIN GS_REPLAY GS_QUIT
playOneLevel :
.PLAY :
call getKey
cmp ax, VK_Q
je .QUIT
cmp ax, VK_R
je .REPLAY
movzx cx, byte[px_u]
movzx dx, byte[py_u]
cmp ax, VK_W
je .UP
cmp ax, VK_S
je .DOWN
cmp ax, VK_A
je .LEFT
cmp ax, VK_D
je .RIGHT
jmp .PLAY
.UP :
mov byte[dir], DIR_UP
sub dx, 2
push dx
push cx
inc dx
push dx
push cx
jmp .TMOVE
.DOWN :
mov byte[dir], DIR_DOWN
add dx, 2
push dx
push cx
dec dx
push dx
push cx
jmp .TMOVE
.LEFT :
mov byte[dir], DIR_LEFT
sub cx, 2
push dx
push cx
inc cx
push dx
push cx
jmp .TMOVE
.RIGHT :
mov byte[dir], DIR_RIGHT
add cx, 2
push dx
push cx
dec cx
push dx
push cx
.TMOVE :
; BOX
mov ax, UID_BOX
push ax
call isUidU
add sp, 2
test ax, ax
jnz .BOX
; FLOOR
mov ax, UID_FLOOR
push ax
call isUidU
add sp, 2
test ax, ax
jnz .WALK
; DEST
mov ax, UID_DEST
push ax
call isUidU
add sp, 2
test ax, ax
jnz .WALK
jmp .CANTMOVE
.BOX :
push bp
mov bp, sp
mov ax, [bp+8]
push ax
mov ax, [bp+6]
push ax
call isInMapU
test ax, ax
jz .ENDBOX
mov ax, UID_BOX
push ax
call isUidU
add sp, 2
test ax, ax
jnz .ENDBOX
mov ax, UID_WALL
push ax
call isUidU
add sp, 2
test ax, ax
jz .PUSHBOX
.ENDBOX :
mov sp, bp
pop bp
add sp, 8
jmp .MOVED
.PUSHBOX :
mov ax, [bp+8]
mov cx, MAP_HORZ_U
mul cx
add ax, [bp+6]
push si
mov si, MAP_CUR
add si, ax
; movzx ax, [si] 悲剧!!!!
mov al, [si]
xor al, UID_BOX
mov [si], al
pop si
mov ax, [bp+4]
mov cx, MAP_HORZ_U
mul cx
add ax, [bp+2]
push si
mov si, MAP_CUR
add si, ax
mov al, [si]
xor al, UID_BOX
mov [si], al
pop si
mov ax, [bp+2]
mov [px_u], al
mov ax, [bp+4]
mov [py_u], al
jmp .ENDBOX
.WALK :
pop ax
mov [px_u], al
pop ax
mov [py_u], al
add sp, 4
jmp .MOVED
.CANTMOVE :
add sp, 8
.MOVED :
call drawAll
call judgeWin
test ax, ax
jnz .WIN
jmp .PLAY
.WIN :
mov ax, GS_WIN
jmp .EXIT
.REPLAY :
mov ax, GS_REPLAY
jmp .EXIT
.QUIT :
mov ax, GS_QUIT
.EXIT :
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax isUidU( uid, xu, yu )
; 判断单元点(xu,yu)是否为uid
; ax!=0 是, ax==0 否
; 若此单元点不在地图中,返回 否
isUidU :
push bp
mov bp, sp
mov ax, [bp+8]
push ax
mov ax, [bp+6]
push ax
call isInMapU
add sp, 4
test ax, ax
jz .EXIT
mov ax, [bp+8]
mov cx, MAP_HORZ_U
mul cx
add ax, [bp+6]
push si
mov si, MAP_CUR
add si, ax
movzx ax, byte[si]
pop si
and ax, [bp+4]
.EXIT :
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax isInMapU( xu, yu )
; 判断单元点(xu,yu)是否在地图中(所在点为SPACE算不在地图中)
; ax!=0 在, ax==0 不在
isInMapU :
push bp
mov bp, sp
mov bx, [bp+4]
cmp bx, MAP_HORZ_U
jae .NO
mov ax, [bp+6]
cmp ax, MAP_VERT_U
jae .NO
mov cx, MAP_HORZ_U
mul cx
add ax, bx
push si
mov si, MAP_CUR
add si, ax
mov al, [si]
pop si
test al, UID_SPACE
jnz .NO
.YES :
mov ax, 1
jmp .EXIT
.NO :
mov ax, 0
.EXIT :
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax judgeWin()
; 判断是否胜利,ax==0 否,ax!=0 胜
; 简单化,扫描整个地图
judgeWin :
push si
mov si, MAP_CUR
mov cx, MAP_U
.judgeWin :
xor bx, bx
movzx ax, byte[si]
test ax, UID_DEST
jz .skip1
inc bx
.skip1 :
test ax, UID_BOX
jz .skip2
inc bx
.skip2 :
cmp bx, 1
je .LOSE
inc si
loop .judgeWin
.WIN :
mov ax, 1
jmp .EXIT
.LOSE :
mov ax, 0
.EXIT :
pop si
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void eraseAll()
; 清除所有图像
eraseAll :
mov ax, 01
mov cx, VIDEO_P
push es
mov bx, VIDEO_SEG
mov es, bx
push di
mov di, 0
cld
rep stosb
pop di
pop es
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void drawAll()
; 直接重绘地图,无关背景
; 兼容3D效果,从左上角到右下角顺序绘制
drawAll :
push si
mov si, MAP_CUR
mov bx, 0 ; yu
mov cx, MAP_VERT_U
.drawAll1 :
push cx
mov ax, 0 ; xu
mov cx, MAP_HORZ_U
.drawAll2 :
push cx
push bx
push ax
movzx cx, byte[si]
inc si
push cx
call drawUidU
pop cx
pop ax
pop bx
inc ax
pop cx
loop .drawAll2
inc bx
pop cx
loop .drawAll1
pop si
movzx ax, byte[py_u]
push ax
movzx ax, byte[px_u]
push ax
mov ax, UID_PLAYER
push ax
call drawUidU
add sp, 6
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void drawUidU( uid, xu, yu )
; 绘制单元坐标为(xu,yu)的单元uid
; uid == UID_FLOOR,
drawUidU :
push bp
mov bp, sp
mov ax, [bp+8]
push ax
mov ax, [bp+6]
push ax
call convU2P
add sp, 4
push bx
push ax
mov ax, [bp+4]
push ax
call drawUid
add sp, 6
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax, bx convU2P( xu, yu )
; 单元坐标转换为像素坐标,依据 orgx_p, orgy_p
; 返回 ax==xp, bx=yp
; 适应3D侧视图
convU2P :
push bp
mov bp, sp
movzx ax, byte[orgx_p]
movzx bx, byte[orgy_p]
.convU2P_L1 :
mov cx, [bp+4]
test cx, cx
jz .convU2P_L2
.convU2P1 :
add ax, DX_HORZ_P
add bx, DY_HORZ_P
loop .convU2P1
.convU2P_L2 :
mov cx, [bp+6]
test cx, cx
jz .EXIT
.convU2P2 :
add ax, DX_VERT_P
add bx, DY_VERT_P
loop .convU2P2
.EXIT :
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void drawUid( uid, xp, yp )
; 绘制像素点为(xp,yp)且类型为uid的单元点
; uid == UID_SPACE, UID_FLOOR,
drawUid :
push bp
mov bp, sp
mov ax, [bp+4]
push ax
call convUid2Uoff
pop bx
mov bx, [bp+8]
push bx
mov bx, [bp+6]
push bx
push ax
call drawUoff
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax convUid2Uoff( uid )
; uid == UID_FLOOR, uoff = UOFF_FLOOR,
; 不依赖 uid 和 uoff 的定义,无跳表,大量比较
; 处理了player的方向dir
; BOX+DEST或BOX+FLOOR 按BOX处理,所以注意测试顺序
convUid2Uoff :
push bp
mov bp, sp
mov ax, [bp+4]
.SPACE :
test ax, UID_SPACE
jz .BOX
mov ax, UOFF_SPACE
jmp .EXIT
.BOX :
test ax, UID_BOX
jz .FLOOR
mov ax, UOFF_BOX
jmp .EXIT
.FLOOR :
test ax, UID_FLOOR
jz .WALL
mov ax, UOFF_FLOOR
jmp .EXIT
.WALL :
test ax, UID_WALL
jz .DEST
mov ax, UOFF_WALL
jmp .EXIT
.DEST :
test ax, UID_DEST
jz .PLAYER
mov ax, UOFF_DEST
jmp .EXIT
.PLAYER :
test ax, UID_PLAYER
jz .ELSE
mov al, [dir]
.UP :
cmp al, DIR_UP
jne .DOWN
mov ax, UOFF_PLAYER_UP
jmp .EXIT
.DOWN :
cmp al, DIR_DOWN
jne .LEFT
mov ax, UOFF_PLAYER_DOWN
jmp .EXIT
.LEFT :
cmp al, DIR_LEFT
jne .RIGHT
mov ax, UOFF_PLAYER_LEFT
jmp .EXIT
.RIGHT :
cmp al, DIR_RIGHT
jne .ELSE
mov ax, UOFF_PLAYER_RIGHT
jmp .EXIT
.ELSE :
mov ax, UOFF_SPACE
.EXIT :
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void drawUoff( uoff, xp, yp )
; 绘制像素点为(xp,yp)且地图单元位图偏移为uoff的单元点
; off == UOFF_SPACE, UOFF_FLOOR,
drawUoff :
; 悲剧!!!!
push bp
mov bp, sp
push si
push di
push es
mov si, [bp+4]
mov cx, VIDEO_SEG
mov es, cx
mov ax, [bp+8]
sub ax, UNIT_VERT_P
inc ax
mov cx, VIDEO_HORZ_P
mul cx
mov bx, [bp+6]
sub bx, UNIT_HORZ_P
inc bx
add ax, bx
mov di, ax
mov cx, UNIT_VERT_P
.drawUoff1 :
push cx
mov cx, UNIT_HORZ_P
.drawUoff2 :
mov al, [ds:si]
test al, al
jz .drawUoff3
mov [es:di], al
.drawUoff3 :
inc si
inc di
loop .drawUoff2
sub di, UNIT_HORZ_P
add di, VIDEO_HORZ_P
pop cx
loop .drawUoff1
pop es
pop di
pop si
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax peekKey()
; 获取键盘输入,不阻塞
; 若无输入返回 VK_NULL
; 若有输入,取出,且不将其从缓冲区中清除
peekKey :
mov ah, 1
int 0x16
jz .VK_NULL
push ax
call convKey2Vk
add sp, 2
jmp .EXIT
.VK_NULL :
mov ax, VK_NULL
.EXIT :
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax getKey()
; 获取键盘输入,阻塞
; 若无输入,阻塞
; 若有输入,取出,且将其从缓冲区中清除
getKey :
mov ah, 0
int 0x16
push ax
call convKey2Vk
add sp, 2
cmp ax, VK_NULL
je getKey
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func ax convKey2Vk( bios_ax )
; 将BIOS键盘输入转换为虚拟键码
; 不依赖任何编码,大量比较
convKey2Vk :
push bp
mov bp, sp
mov ax, [bp+4]
cmp al, 'W'
je .VK_W
cmp al, 'w'
je .VK_W
cmp al, 'A'
je .VK_A
cmp al, 'a'
je .VK_A
cmp al, 'S'
je .VK_S
cmp al, 's'
je .VK_S
cmp al, 'D'
je .VK_D
cmp al, 'd'
je .VK_D
cmp al, 'Q'
je .VK_Q
cmp al, 'q'
je .VK_Q
cmp al, 'R'
je .VK_R
cmp al, 'r'
je .VK_R
jmp .VK_NULL
.VK_W :
mov ax, VK_W
jmp .EXIT
.VK_A :
mov ax, VK_A
jmp .EXIT
.VK_S :
mov ax, VK_S
jmp .EXIT
.VK_D :
mov ax, VK_D
jmp .EXIT
.VK_Q :
mov ax, VK_Q
jmp .EXIT
.VK_R :
mov ax, VK_R
jmp .EXIT
.VK_NULL :
mov ax, VK_NULL
.EXIT :
mov sp, bp
pop bp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void sleep( t )
; 等待 t 毫秒,等待中的输入被清除(清空输入缓冲区)
; 移动动画使用
sleep :
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 调色板
BOX_PAL :
; r g b
db 63, 63, 00 ; 00 透明色
; SPACE
db 00, 00, 00 ; 01 背景色
db 00, 00, 00 ; 02
db 00, 00, 00 ; 03
db 00, 00, 00 ; 04
db 00, 00, 00 ; 05
; FLOOR
db 16, 22, 28 ; 06
db 21, 26, 32 ; 07
db 00, 07, 15 ; 08
db 00, 00, 00 ; 09
db 00, 00, 00 ; 10
; WALL
db 00, 07, 15 ; 11
db 63, 63, 63 ; 12
db 14, 20, 22 ; 13
db 30, 31, 38 ; 14
db 37, 42, 45 ; 15
; BOX
db 60, 60, 60 ; 16
db 25, 30, 06 ; 17
db 44, 47, 21 ; 18
db 55, 56, 37 ; 19
db 00, 07, 15 ; 20
; DEST
db 60, 60, 30 ; 21
db 00, 07, 15 ; 22
db 00, 00, 00 ; 23
db 00, 00, 00 ; 24
db 00, 00, 00 ; 25
; PLAYER
db 00, 07, 15 ; 26
db 60, 60, 60 ; 27
db 00, 00, 00 ; 28
db 60, 44, 62 ; 29
db 63, 28, 62 ; 30
db 00, 32, 63 ; 31
db 00, 00, 00 ; 32
db 00, 00, 00 ; 33
BOX_PAL_NUM : equ $-BOX_PAL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; func void initVideo()
; 初始化显示方式
initVideo :
; 设置显示方式
mov ax, 0x0013
int 0x10
; 设置调色板
xor bx, bx ; rgbrgbrgb
xor cx, cx ; index 0
.iVset :
cmp bx, BOX_PAL_NUM
je .iVexit
; 调色板 index
mov dx, VIDEO_PAL_PORT
mov ax, cx
out dx, al
inc cx
; 调色板颜色
mov dx, VIDEO_COL_PORT
mov al, [ds:BOX_PAL+bx]
out dx, al
inc bx
mov al, [ds:BOX_PAL+bx]
out dx, al
inc bx
mov al, [ds:BOX_PAL+bx]
out dx, al
inc bx
jmp .iVset
.iVexit :
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 地图单元位图
; (繁琐的工作,还好有 Vim + 自制的MageX )
UOFF_SPACE :
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
db 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01
UOFF_FLOOR :
db 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 07, 07, 07, 07, 06, 06, 07, 07, 07, 07, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 08
db 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08, 08
UOFF_WALL :
db 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11
db 11, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 11
db 11, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 11
db 11, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11
db 11, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11
db 11, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11
db 11, 12, 12, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11
db 11, 12, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11
db 11, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11
db 11, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11
db 11, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11
db 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11
UOFF_BOX :
db 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
db 20, 06, 06, 06, 06, 06, 06, 06, 18, 18, 18, 18, 18, 18, 06, 06, 06, 06, 06, 06, 06, 20
db 20, 06, 06, 06, 06, 06, 18, 18, 16, 16, 16, 16, 18, 18, 18, 18, 06, 06, 06, 06, 06, 20
db 20, 06, 06, 06, 18, 18, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 06, 06, 06, 20
db 20, 06, 06, 18, 18, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 06, 06, 20
db 20, 06, 06, 18, 16, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16, 16, 16, 18, 18, 06, 06, 20
db 20, 06, 18, 18, 16, 16, 16, 16, 16, 16, 17, 17, 16, 16, 16, 16, 18, 18, 18, 18, 06, 20
db 20, 06, 18, 18, 18, 16, 16, 16, 16, 17, 17, 17, 17, 18, 16, 18, 18, 18, 18, 18, 06, 20
db 20, 18, 18, 18, 18, 18, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 20
db 20, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 20
db 20, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 20
db 20, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 20
db 20, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 20
db 20, 18, 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 18, 18, 19, 19, 18, 18, 18, 18, 20
db 20, 06, 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 18, 19, 19, 19, 18, 18, 18, 06, 20
db 20, 06, 18, 18, 18, 18, 18, 18, 18, 18, 17, 17, 18, 19, 19, 19, 19, 18, 18, 18, 06, 20
db 20, 06, 06, 18, 18, 18, 18, 18, 18, 19, 19, 17, 18, 19, 19, 19, 18, 18, 18, 06, 06, 20
db 20, 06, 06, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 18, 18, 18, 18, 06, 06, 20
db 20, 06, 06, 06, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 18, 18, 18, 18, 06, 06, 06, 20
db 20, 06, 06, 06, 06, 06, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 06, 06, 06, 06, 06, 20
db 20, 06, 06, 06, 06, 06, 06, 06, 18, 18, 18, 18, 18, 18, 06, 06, 06, 06, 06, 06, 06, 20
db 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
UOFF_DEST :
db 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 21, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 06, 06, 22
db 22, 06, 06, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 21, 21, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 21, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 22
db 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22
UOFF_PLAYER_UP :
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 31, 27, 27, 31, 29, 29, 31, 27, 27, 31, 29, 29, 29, 06, 06, 26
db 26, 06, 29, 29, 29, 31, 28, 28, 31, 31, 31, 31, 28, 28, 31, 31, 31, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 27, 31, 31, 31, 31, 31, 27, 31, 31, 31, 31, 31, 31, 27, 29, 29, 06, 26
db 26, 29, 29, 29, 27, 27, 31, 31, 31, 31, 27, 27, 31, 31, 31, 31, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 27, 27, 27, 31, 31, 27, 27, 27, 27, 31, 31, 27, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 27, 27, 27, 30, 30, 30, 30, 27, 27, 27, 29, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 29, 29, 27, 30, 30, 30, 30, 27, 29, 29, 29, 29, 29, 29, 29, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
UOFF_PLAYER_DOWN :
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 31, 27, 27, 31, 29, 29, 31, 27, 27, 31, 29, 29, 29, 06, 06, 26
db 26, 06, 29, 29, 29, 31, 28, 28, 31, 31, 31, 31, 28, 28, 31, 31, 31, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 27, 31, 31, 31, 31, 31, 27, 31, 31, 31, 31, 31, 31, 27, 29, 29, 06, 26
db 26, 29, 29, 29, 27, 27, 31, 31, 31, 31, 27, 27, 31, 31, 31, 31, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 27, 27, 27, 31, 31, 27, 27, 27, 27, 31, 31, 27, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 27, 27, 27, 30, 30, 30, 30, 27, 27, 27, 29, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 29, 29, 27, 30, 30, 30, 30, 27, 29, 29, 29, 29, 29, 29, 29, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
UOFF_PLAYER_LEFT :
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 31, 27, 27, 31, 29, 29, 31, 27, 27, 31, 29, 29, 29, 06, 06, 26
db 26, 06, 29, 29, 29, 31, 28, 28, 31, 31, 31, 31, 28, 28, 31, 31, 31, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 27, 31, 31, 31, 31, 31, 27, 31, 31, 31, 31, 31, 31, 27, 29, 29, 06, 26
db 26, 29, 29, 29, 27, 27, 31, 31, 31, 31, 27, 27, 31, 31, 31, 31, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 27, 27, 27, 31, 31, 27, 27, 27, 27, 31, 31, 27, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 27, 27, 27, 30, 30, 30, 30, 27, 27, 27, 29, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 29, 29, 27, 30, 30, 30, 30, 27, 29, 29, 29, 29, 29, 29, 29, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
UOFF_PLAYER_RIGHT :
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 31, 31, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 31, 27, 27, 31, 29, 29, 31, 27, 27, 31, 29, 29, 29, 06, 06, 26
db 26, 06, 29, 29, 29, 31, 28, 28, 31, 31, 31, 31, 28, 28, 31, 31, 31, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 27, 31, 31, 31, 31, 31, 27, 31, 31, 31, 31, 31, 31, 27, 29, 29, 06, 26
db 26, 29, 29, 29, 27, 27, 31, 31, 31, 31, 27, 27, 31, 31, 31, 31, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 27, 27, 27, 31, 31, 27, 27, 27, 27, 31, 31, 27, 27, 27, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 27, 27, 27, 27, 27, 30, 30, 27, 27, 27, 27, 27, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 27, 27, 27, 30, 30, 30, 30, 27, 27, 27, 29, 29, 29, 29, 29, 26
db 26, 29, 29, 29, 29, 29, 29, 29, 27, 30, 30, 30, 30, 27, 29, 29, 29, 29, 29, 29, 29, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 26
db 26, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 06, 06, 26
db 26, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 26
db 26, 06, 06, 06, 06, 06, 06, 06, 29, 29, 29, 29, 29, 29, 06, 06, 06, 06, 06, 06, 06, 26
db 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 变量
level : db 1
; 当前地图
MAP_CUR :
times MAP_U db 0
orgx_p : db 0
orgy_p : db 0
px_u : db 0
py_u : db 0
dir : db 0
MAP_SIZE : equ $-MAP_CUR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 地图,级别从低到高按顺序,相对 MAP_CUR 定位
%define SPACE UID_SPACE
%define FLOOR UID_FLOOR
%define WALL UID_WALL
%define DEST UID_DEST
%define BOX (UID_FLOOR|UID_BOX)
%define BOXDE (UID_DEST|UID_BOX)
%define PLAYE UID_FLOOR
MAP_LEVEL_1 :
db SPACE, SPACE, WALL, WALL, WALL, SPACE, SPACE, SPACE
db SPACE, SPACE, WALL, DEST, WALL, SPACE, SPACE, SPACE
db SPACE, SPACE, WALL, FLOOR, WALL, WALL, WALL, WALL
db WALL, WALL, WALL, BOX, FLOOR, BOX, DEST, WALL
db WALL, DEST, FLOOR, BOX, FLOOR, WALL, WALL, WALL
db WALL, WALL, WALL, WALL, BOX, WALL, SPACE, SPACE
db SPACE, SPACE, SPACE, WALL, DEST, WALL, SPACE, SPACE
db SPACE, SPACE, SPACE, WALL, WALL, WALL, SPACE, SPACE
db 90, 30, 4, 4, DIR_UP
MAP_LEVEL_2 :
db SPACE, SPACE, WALL, WALL, WALL, WALL, SPACE, SPACE
db SPACE, WALL, WALL, FLOOR, FLOOR, WALL, SPACE, SPACE
db SPACE, WALL, FLOOR, BOX, FLOOR, WALL, SPACE, SPACE
db SPACE, WALL, WALL, BOX, FLOOR, WALL, WALL, SPACE
db SPACE, WALL, WALL, FLOOR, BOX, FLOOR, WALL, SPACE
db SPACE, WALL, DEST, BOX, FLOOR, FLOOR, WALL, SPACE
db SPACE, WALL, DEST, DEST, BOXDE, DEST, WALL, SPACE
db SPACE, WALL, WALL, WALL, WALL, WALL, WALL, SPACE
db 90, 30, 2, 2, DIR_UP
MAP_LEVEL_3 :
db SPACE, WALL, WALL, WALL, WALL, WALL, SPACE, SPACE
db SPACE, WALL, FLOOR, FLOOR, WALL, WALL, WALL, SPACE
db SPACE, WALL, FLOOR, BOX, FLOOR, FLOOR, WALL, SPACE
db WALL, WALL, WALL, FLOOR, WALL, FLOOR, WALL, WALL
db WALL, DEST, WALL, FLOOR, WALL, FLOOR, FLOOR, WALL
db WALL, DEST, BOX, FLOOR, FLOOR, WALL, FLOOR, WALL
db WALL, DEST, FLOOR, FLOOR, FLOOR, BOX, FLOOR, WALL
db WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL
db 90, 30, 2, 2, DIR_UP
MAP_LEVEL_4 :
db SPACE, SPACE, WALL, WALL, WALL, WALL, WALL, WALL
db SPACE, WALL, WALL, FLOOR, FLOOR, WALL, FLOOR, FLOOR
db SPACE, WALL, FLOOR, FLOOR, FLOOR, WALL, FLOOR, FLOOR
db SPACE, WALL, BOX, FLOOR, BOX, FLOOR, BOX, FLOOR
db SPACE, WALL, FLOOR, BOX, WALL, WALL, FLOOR, FLOOR
db WALL, WALL, FLOOR, BOX, FLOOR, WALL, FLOOR, WALL
db DEST, DEST, DEST, DEST, DEST, FLOOR, FLOOR, WALL
db WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL
db 90, 30, 7, 1, DIR_UP
MAP_LEVEL_COMPELETE :
db FLOOR, FLOOR, FLOOR, SPACE, SPACE, FLOOR, FLOOR, SPACE
db FLOOR, SPACE, SPACE, SPACE, SPACE, FLOOR, SPACE, FLOOR
db FLOOR, SPACE, SPACE, SPACE, SPACE, FLOOR, SPACE, FLOOR
db FLOOR, FLOOR, FLOOR, SPACE, SPACE, FLOOR, SPACE, FLOOR
db FLOOR, SPACE, SPACE, SPACE, SPACE, FLOOR, SPACE, FLOOR
db FLOOR, SPACE, SPACE, SPACE, SPACE, FLOOR, SPACE, FLOOR
db FLOOR, FLOOR, FLOOR, SPACE, SPACE, FLOOR, FLOOR, SPACE
db SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE
db 95, 40, 1, 3, DIR_UP