├── .gitignore ├── LICENSE ├── README.md ├── convert_font.py ├── convert_tiles.py ├── font.png ├── font.tal ├── make_chords.py ├── note.tal ├── shanghai.tal ├── sus2.tal ├── tiles.png └── tiles.tal /.gitignore: -------------------------------------------------------------------------------- 1 | *.rom 2 | *.exe 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Lynn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shanghai 2 | 3 | A [mahjong solitaire](https://en.wikipedia.org/wiki/Mahjong_solitaire) (aka Shanghai solitaire) game for [Uxn](https://100r.co/site/uxn.html). 4 | 5 | Uxn is an ultra-portable personal computing stack. You write little apps in an assembly language, and run them on [any platform](https://github.com/hundredrabbits/awesome-uxn#emulators) — web, iOS, Amiga, Nintendo DS, you name it. 6 | 7 | ![screenshot](https://user-images.githubusercontent.com/16232127/193089463-84915373-c202-478f-b5e7-e41c94ff6ed2.png) 8 | 9 | ## TODO 10 | 11 | - [x] Draw tiles in a turtle shape 12 | - [x] Select tiles with the mouse 13 | - [x] Click and match tiles 14 | - [x] See number of open matches 15 | - [ ] Controller support 16 | - [ ] Title screen, timer/restart/win UI 17 | - [ ] Sound effects! Animations! 18 | - [ ] ~~Make it riichi mahjong instead~~ 19 | -------------------------------------------------------------------------------- /convert_font.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | 3 | img = Image.open("font.png") 4 | 5 | lines = [] 6 | lines.append("@font") 7 | 8 | for x in range(128): 9 | bs = [] 10 | for ty in range(2): 11 | for tx in range(1): 12 | for by in range(8): 13 | byte = 0 14 | for bx in range(8): 15 | xx = 8*x + bx 16 | yy = 8*ty + by 17 | if img.getpixel((xx, yy)) == 2: 18 | byte |= 1 << 7-bx 19 | bs.append(byte) 20 | lines.append(" " + " ".join("%02x" % b for b in bs)) 21 | 22 | with open("font.tal", "w") as f: 23 | f.write("\n".join(lines) + "\n") 24 | -------------------------------------------------------------------------------- /convert_tiles.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | 3 | img = Image.open("tiles.png") 4 | 5 | rows = [ 6 | ("dot", 9), 7 | ("bamboo", 9), 8 | ("char", 9), 9 | ("honor", 7), 10 | ("bonus", 8), 11 | ] 12 | 13 | lines = [] 14 | lines.append("@s-blank") 15 | lines.append(" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") 16 | lines.append(" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") 17 | lines.append(" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") 18 | lines.append(" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") 19 | lines.append(" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") 20 | lines.append(" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") 21 | 22 | for y, (row_name, tile_count) in enumerate(rows): 23 | for x in range(tile_count): 24 | lines.append(f"( @s-{row_name}-{x+1} )") 25 | img.putpixel((16*x, 24*y+1), 0) 26 | img.putpixel((16*x+15, 24*y+1), 0) 27 | for ty in range(3): 28 | for tx in range(2): 29 | bs = [] 30 | for bit in [1, 2]: 31 | for by in range(8): 32 | byte = 0 33 | for bx in range(8): 34 | xx = 16*x + 8*tx + bx 35 | yy = 24*y + 8*ty + by 36 | if img.getpixel((xx, yy)) & bit: 37 | byte |= 1 << 7-bx 38 | bs.append(byte) 39 | lines.append(" " + " ".join("%02x" % b for b in bs)) 40 | 41 | with open("tiles.tal", "w") as f: 42 | f.write("\n".join(lines) + "\n") 43 | -------------------------------------------------------------------------------- /font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lynn/shanghai/a47743f02b25555632a79e7195864bd1af09dd35/font.png -------------------------------------------------------------------------------- /font.tal: -------------------------------------------------------------------------------- 1 | @font 2 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 | 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19 | 00 00 00 00 00 03 0c 18 30 20 20 30 1f 00 00 00 20 | 00 00 00 00 e0 80 00 00 00 00 03 0c f0 00 00 00 21 | 00 03 03 02 06 0f 19 30 60 80 00 00 00 00 00 00 22 | 00 00 00 00 00 00 80 c0 3f 00 00 00 00 00 00 00 23 | 00 00 00 00 00 00 00 00 ff 00 00 00 00 00 00 00 24 | 01 03 02 06 04 05 06 0c f4 04 02 01 00 00 00 00 25 | d8 08 18 30 60 80 00 00 00 00 00 00 c0 38 07 00 26 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 27 | 00 00 00 00 00 00 00 00 00 00 00 00 01 1e e0 00 28 | 00 00 00 00 38 2c 34 0c 0f 08 10 60 80 00 00 00 29 | 00 00 00 00 00 00 00 00 e0 1f 00 00 00 00 00 00 30 | 00 00 00 00 00 00 00 00 00 c0 3f 00 00 00 00 00 31 | 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 00 00 32 | 07 1c 10 10 11 13 12 16 1c 30 c8 0c 06 03 01 00 33 | 00 80 80 80 00 00 00 00 00 00 00 00 00 00 80 80 34 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 35 | 00 00 60 60 60 60 60 60 60 60 00 60 60 00 00 00 36 | 00 00 66 66 24 00 00 00 00 00 00 00 00 00 00 00 37 | 00 00 04 24 16 3e 34 14 17 3c 10 00 00 00 00 00 38 | 00 08 3c 6e 48 48 78 38 1e 12 12 12 72 3e 0c 00 39 | 00 00 30 52 72 26 04 04 0c 08 08 18 13 17 07 00 40 | 00 00 1c 14 14 14 14 14 18 18 38 78 5c 76 00 00 41 | 00 10 10 10 18 00 00 00 00 00 00 00 00 00 00 00 42 | 00 04 08 08 08 08 08 08 08 08 08 0c 06 03 00 00 43 | 00 00 30 18 0c 04 06 02 02 02 02 02 06 04 04 04 44 | 00 00 00 00 60 36 7c 18 6c 44 06 00 00 00 00 00 45 | 00 00 00 00 10 10 10 16 7c 10 18 00 00 00 00 00 46 | 00 00 00 00 00 00 00 00 00 00 00 08 18 10 30 00 47 | 00 00 00 00 00 00 00 00 7e 00 00 00 00 00 00 00 48 | 00 00 00 00 00 00 00 00 00 00 00 00 18 18 00 00 49 | 00 00 00 00 02 02 06 04 0c 08 18 10 30 60 40 00 50 | 00 00 00 00 7c c6 c6 c6 c6 c6 c6 c6 7c 00 00 00 51 | 00 00 00 00 18 38 18 18 18 18 18 18 3c 00 00 00 52 | 00 00 00 00 7c c6 06 06 0c 18 30 60 fe 00 00 00 53 | 00 00 00 00 7c c6 06 06 3c 06 06 c6 7c 00 00 00 54 | 00 00 00 00 0e 1e 36 66 c6 fe 06 06 06 00 00 00 55 | 00 00 00 00 fe c0 c0 c0 fc 06 06 06 f8 00 00 00 56 | 00 00 00 00 1e 30 60 c0 fc c6 c6 c6 7c 00 00 00 57 | 00 00 00 00 fe 06 06 0c 18 30 60 c0 c0 00 00 00 58 | 00 00 00 00 7c c6 c6 c6 7c c6 c6 c6 7c 00 00 00 59 | 00 00 00 00 7c c6 c6 c6 7e 06 06 0c f8 00 00 00 60 | 00 00 00 00 00 00 30 30 00 00 00 30 30 00 00 00 61 | 00 00 00 08 00 00 00 00 00 00 00 08 18 10 00 00 62 | 00 00 00 00 0c 18 10 30 20 20 38 00 00 00 00 00 63 | 00 00 00 00 00 3c 20 00 00 02 3e 00 00 00 00 00 64 | 00 00 00 20 30 0c 06 06 0c 30 60 00 00 00 00 00 65 | 00 00 10 2c 44 04 08 18 10 00 00 00 00 18 00 00 66 | 00 00 00 3c 64 44 5c e4 ac b8 c0 42 46 6c 38 00 67 | 00 00 7c c6 c6 c6 fe c6 c6 c6 c6 c6 c6 00 00 00 68 | 00 00 fc c6 c6 c6 fc c6 c6 c6 c6 c6 fc 00 00 00 69 | 00 00 3e 66 c0 c0 c0 c0 c0 c0 c0 60 3e 00 00 00 70 | 00 00 f8 cc c6 c6 c6 c6 c6 c6 c6 cc f8 00 00 00 71 | 00 00 fe c0 c0 c0 fc c0 c0 c0 c0 c0 fe 00 00 00 72 | 00 00 fe c0 c0 c0 fc c0 c0 c0 c0 c0 c0 00 00 00 73 | 00 00 7c c6 c6 c0 de c6 c6 c6 c6 c6 7c 00 00 00 74 | 00 00 c6 c6 c6 c6 fe c6 c6 c6 c6 c6 c6 00 00 00 75 | 00 00 3c 18 18 18 18 18 18 18 18 18 3c 00 00 00 76 | 00 00 1e 06 06 06 06 06 06 06 c6 c6 7c 00 00 00 77 | 00 00 c6 c6 c6 cc f8 cc c6 c6 c6 c6 c6 00 00 00 78 | 00 00 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 fe 00 00 00 79 | 00 00 c6 ee fe d6 c6 c6 c6 c6 c6 c6 c6 00 00 00 80 | 00 00 c6 e6 d6 ce c6 c6 c6 c6 c6 c6 c6 00 00 00 81 | 00 00 7c c6 c6 c6 c6 c6 c6 c6 c6 c6 7c 00 00 00 82 | 00 00 fc c6 c6 c6 fc c0 c0 c0 c0 c0 c0 00 00 00 83 | 00 00 7c c6 c6 c6 c6 c6 c6 c6 d6 ce 7c 06 00 00 84 | 00 00 fc c6 c6 c6 fc c6 c6 c6 c6 c6 c6 00 00 00 85 | 00 00 3e 60 c0 c0 7c 06 06 06 06 0c f8 00 00 00 86 | 00 00 fc 30 30 30 30 30 30 30 30 30 30 00 00 00 87 | 00 00 c6 c6 c6 c6 c6 c6 c6 c6 c6 c6 7c 00 00 00 88 | 00 00 c6 c6 c6 c6 c6 c6 c6 c6 6c 38 10 00 00 00 89 | 00 00 c6 c6 c6 c6 c6 c6 d6 d6 fe ee c6 00 00 00 90 | 00 00 c6 c6 6c 38 10 38 6c c6 c6 c6 c6 00 00 00 91 | 00 00 c6 c6 c6 c6 7e 06 06 06 06 0c f8 00 00 00 92 | 00 00 fe 06 0c 18 30 60 c0 c0 c0 c0 fe 00 00 00 93 | 00 00 1c 10 10 10 10 10 10 18 08 08 0e 00 00 00 94 | 00 00 00 40 40 60 20 20 20 30 10 18 0c 00 00 00 95 | 00 00 00 7e 02 02 02 02 02 02 02 02 02 3e 00 00 96 | 00 00 00 10 18 38 08 00 00 00 00 00 00 00 00 00 97 | 00 00 00 00 00 00 00 00 00 00 00 00 00 7f 00 00 98 | 00 00 10 18 00 00 00 00 00 00 00 00 00 00 00 00 99 | 00 00 00 00 00 00 7c c6 06 7e c6 ce 76 00 00 00 100 | 00 00 c0 c0 c0 c0 fc c6 c6 c6 c6 e6 dc 00 00 00 101 | 00 00 00 00 00 00 7c c6 c0 c0 c0 c6 7c 00 00 00 102 | 00 00 06 06 06 06 7e c6 c6 c6 c6 ce 76 00 00 00 103 | 00 00 00 00 00 00 7c c6 c6 fe c0 c6 7c 00 00 00 104 | 00 00 3c 66 60 60 f8 60 60 60 60 60 60 00 00 00 105 | 00 00 00 00 00 00 76 ce c6 c6 c6 c6 7e 06 c6 7c 106 | 00 00 c0 c0 c0 c0 dc e6 c6 c6 c6 c6 c6 00 00 00 107 | 00 00 00 18 18 00 78 18 18 18 18 18 18 00 00 00 108 | 00 00 00 0c 0c 00 3c 0c 0c 0c 0c 0c 0c 0c cc 78 109 | 00 00 c0 c0 c0 c0 c6 cc d8 f0 d8 cc c6 00 00 00 110 | 00 00 78 18 18 18 18 18 18 18 18 18 0e 00 00 00 111 | 00 00 00 00 00 00 ec d6 d6 d6 d6 d6 c6 00 00 00 112 | 00 00 00 00 00 00 dc e6 c6 c6 c6 c6 c6 00 00 00 113 | 00 00 00 00 00 00 7c c6 c6 c6 c6 c6 7c 00 00 00 114 | 00 00 00 00 00 00 dc e6 c6 c6 c6 c6 fc c0 c0 c0 115 | 00 00 00 00 00 00 76 ce c6 c6 c6 c6 7e 06 06 06 116 | 00 00 00 00 00 00 de e6 c0 c0 c0 c0 c0 00 00 00 117 | 00 00 00 00 00 00 7c c6 c0 7c 06 c6 7c 00 00 00 118 | 00 00 30 30 30 30 fc 30 30 30 30 30 1e 00 00 00 119 | 00 00 00 00 00 00 c6 c6 c6 c6 c6 ce 76 00 00 00 120 | 00 00 00 00 00 00 c6 c6 c6 c6 6c 38 10 00 00 00 121 | 00 00 00 00 00 00 c6 c6 d6 d6 d6 d6 7e 00 00 00 122 | 00 00 00 00 00 00 c6 c6 6c 38 6c c6 c6 00 00 00 123 | 00 00 00 00 00 00 c6 c6 c6 c6 c6 c6 7e 06 0c f8 124 | 00 00 00 00 00 00 fe 0c 18 30 60 c0 fe 00 00 00 125 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 126 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 127 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 128 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 129 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 130 | -------------------------------------------------------------------------------- /make_chords.py: -------------------------------------------------------------------------------- 1 | import math 2 | def sin(x): 3 | return math.sin(2*math.pi*x) 4 | def wave(x): 5 | return (sin(x) + sin(2*x) + sin(3*x) + sin(4*x)) / 4 6 | 7 | chords = [ 8 | #("min", [16, 20, 27]), 9 | #("maj", [16, 20, 24]), 10 | ("sus2", [8, 9, 12]), 11 | #("dom", [14, 16, 20]), 12 | ("note", [1]), 13 | ] 14 | 15 | for name, notes in chords: 16 | L = 256 17 | buf = [] 18 | for i in range(L): 19 | f = sin if name == "note" else wave 20 | s = sum(f(k*i/L) for k in notes) / len(notes) 21 | buf.append(int(s * 126 + 128)) 22 | buf = bytes(buf) 23 | #with open(f"{name}.pcm", "wb") as f: 24 | # f.write(buf) 25 | with open(f"{name}.tal", "w") as f: 26 | f.write(f"@wave-{name}\n") 27 | for i in range(0, L, 16): 28 | f.write(f" " + buf[i:i+16].hex(" ") + "\n") 29 | -------------------------------------------------------------------------------- /note.tal: -------------------------------------------------------------------------------- 1 | @wave-note 2 | 80 83 86 89 8c 8f 92 95 98 9b 9e a1 a4 a7 aa ad 3 | b0 b3 b5 b8 bb be c0 c3 c6 c8 cb cd cf d2 d4 d6 4 | d9 db dd df e1 e3 e5 e7 e8 ea ec ed ef f0 f1 f3 5 | f4 f5 f6 f7 f8 f9 fa fa fb fc fc fd fd fd fd fd 6 | fe fd fd fd fd fd fc fc fb fa fa f9 f8 f7 f6 f5 7 | f4 f3 f1 f0 ef ed ec ea e8 e7 e5 e3 e1 df dd db 8 | d9 d6 d4 d2 cf cd cb c8 c6 c3 c0 be bb b8 b5 b3 9 | b0 ad aa a7 a4 a1 9e 9b 98 95 92 8f 8c 89 86 83 10 | 80 7c 79 76 73 70 6d 6a 67 64 61 5e 5b 58 55 52 11 | 4f 4c 4a 47 44 41 3f 3c 39 37 34 32 30 2d 2b 29 12 | 26 24 22 20 1e 1c 1a 18 17 15 13 12 10 0f 0e 0c 13 | 0b 0a 09 08 07 06 05 05 04 03 03 02 02 02 02 02 14 | 02 02 02 02 02 02 03 03 04 05 05 06 07 08 09 0a 15 | 0b 0c 0e 0f 10 12 13 15 17 18 1a 1c 1e 20 22 24 16 | 26 29 2b 2d 30 32 34 37 39 3c 3f 41 44 47 4a 4c 17 | 4f 52 55 58 5b 5e 61 64 67 6a 6d 70 73 76 79 7c 18 | -------------------------------------------------------------------------------- /shanghai.tal: -------------------------------------------------------------------------------- 1 | |00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 2 | |10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1 3 | |20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 4 | |30 @Audio0 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 5 | |40 @Audio1 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 6 | |50 @Audio2 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 7 | |60 @Audio3 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 8 | |80 @Controller &vector $2 &button $1 &key $1 &func $1 9 | |90 @Mouse &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2 10 | |a0 @File &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 11 | |b0 @File1 &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 12 | |c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 13 | 14 | %Ext { #00 SWP } 15 | %Mod { DIVk MUL SUB } 16 | %Mod2 { DIV2k MUL2 SUB2 } 17 | %Dbg { #01 .System/debug DEO } 18 | %Gsx { .Screen/x DEI2 } 19 | %Gsy { .Screen/y DEI2 } 20 | %Ssx { .Screen/x DEO2 } 21 | %Ssy { .Screen/y DEO2 } 22 | %Ssa { .Screen/addr DEO2 } 23 | %Spr { .Screen/sprite DEO } 24 | %Sprr { .Screen/sprite DEOk DEO } 25 | %Sprrr { .Screen/sprite DEOk DEOk DEO } 26 | %Aut0 { #00 .Screen/auto DEO } 27 | %Aut0ay { #06 .Screen/auto DEO } 28 | %Aut1ay { #16 .Screen/auto DEO } 29 | %Aut2ay { #26 .Screen/auto DEO } 30 | %Aut1y { #12 .Screen/auto DEO } 31 | %Ovrsb { ROTk NIP SWP } ( ss b -- ss b ss ) 32 | %Swpsb { ROT ROT } ( ss b -- b ss ) 33 | 34 | %Bd { ;board ADD2 LDA } 35 | 36 | ( 37 | !!! All numbers here are in hex. !!! 38 | 39 | Tiles are 10x18 pixels. 40 | The board is 20x10x5, accessed as board[z<<9 | y<<5 | x]. 41 | 42 | The tiles are: 43 | 44 | 01 02 03 04 05 06 07 08 09 dots 45 | 0a 0b 0c 0d 0e 0f 10 11 12 bamboo 46 | 13 14 15 16 17 18 19 1a 1b chars 47 | 1c 1d 1e 1f 20 21 22 honors 48 | 23 24 25 26 flowers 49 | 27 28 29 2a seasons 50 | 51 | Tiles 01-22 match up with themselves: there's four of each. 52 | Tiles 23-26 and 27-2a match up freely with each other: there's one of each. 53 | Trick: When comparing tile IDs, if x>22 { x=x+1|3 }. 54 | 55 | Sprite address: @s-blank + 60*x. 56 | 57 | Tile x,y,z is rendered at [8*x+10, b*y-4*z+10] 58 | 59 | So mouse mx,my is tile [ [mx-10]>>3, [[my-10+4*z]/b], z ] for z=4..0 60 | ...also checking one tile left and one or two tiles up 61 | ) 62 | 63 | 64 | ( variables ) 65 | 66 | |0000 67 | @i $2 68 | @j $2 69 | @mx $2 70 | @my $2 71 | @hovered $2 &old $2 72 | @picked $2 &old $2 73 | 74 | @pointer &x $2 &y $2 75 | 76 | ( program ) 77 | 78 | |0100 ( -> ) 79 | #03ed .System/r DEO2 80 | #70e7 .System/g DEO2 81 | #6be7 .System/b DEO2 82 | ;load-theme JSR2 83 | #0110 .Screen/width DEO2 84 | #00e0 .Screen/height DEO2 85 | 86 | #1111 .Audio2/adsr DEO2 87 | #0100 .Audio2/length DEO2 88 | ;wave-sus2 .Audio2/addr DEO2 89 | #00 .Audio2/volume DEO 90 | #01 .Audio2/pitch DEO 91 | 92 | ;on-mouse .Mouse/vector DEO2 93 | ;prng-init JSR2 94 | ;new-game JSR2 95 | ;make-turtle JSR2 96 | ;example-text #0004 #0000 ;draw-text JSR2 97 | ;redraw-board JSR2 98 | BRK 99 | 100 | @example-text 101 | "matches: 20 00 102 | 103 | @draw-text ( ptr* x* y* -- ) 104 | Ssy Ssx Aut0ay 105 | &next 106 | LDAk ( ptr* ch ) 107 | DUP ,&ok JCN 108 | POP POP2 JMP2r 109 | &ok ( ptr* ch ) 110 | ;putchar JSR2 111 | INC2 112 | Gsx #0008 ADD2 Ssx 113 | ,&next JMP 114 | 115 | @draw-number ( num x* y* -- ) 116 | Ssy Ssx Aut0ay 117 | DUP #00 EQU #02 ADD ;text-color STA 118 | 119 | DUP #64 LTH ,&no-hundreds JCN 120 | DUP #64 DIV DUP #30 ADD ;putchar JSR2 #64 MUL SUB 121 | Gsx #0008 ADD2 Ssx 122 | &no-hundreds 123 | 124 | DUP #0a LTH ,&no-tens JCN 125 | DUP #0a DIV DUP #30 ADD ;putchar JSR2 #0a MUL SUB 126 | Gsx #0008 ADD2 Ssx 127 | &no-tens 128 | #30 ADD ;putchar JSR2 129 | 130 | Gsx #0008 ADD2 Ssx 131 | #20 ;putchar JSR2 132 | JMP2r 133 | 134 | @putchar ( ch -- ) 135 | Ext #40 SFT2 ;font ADD2 Ssa 136 | LIT @text-color 02 Sprr 137 | Gsy #0010 SUB2 Ssy 138 | JMP2r 139 | 140 | @s1x1_mouse 141 | 80c0 e0f0 c020 0000 142 | @on-mouse 143 | ;s1x1_mouse Ssa Aut0 144 | .pointer/x LDZ2 Ssx 145 | .pointer/y LDZ2 Ssy 146 | #40 Spr 147 | .Mouse/x DEI2 DUP2 .pointer/x STZ2 Ssx 148 | .Mouse/y DEI2 DUP2 .pointer/y STZ2 Ssy 149 | #42 Spr 150 | 151 | .hovered LDZ2 .hovered/old STZ2 152 | .picked LDZ2 .picked/old STZ2 153 | 154 | .Mouse/x DEI2 .Mouse/y DEI2 155 | ;mouse-to-tile JSR2 156 | DUP2 ;is-free JSR2 ,&free JCN 157 | POP2 158 | #0000 .hovered STZ2 159 | ,&highlight JMP 160 | &free 161 | .hovered STZ2 162 | &highlight 163 | .Mouse/state DEI #00 EQU ,¬-pressed JCN 164 | .hovered LDZ2 .picked STZ2 165 | ;try-match JSR2 166 | 167 | ¬-pressed 168 | 169 | .hovered LDZ2 .hovered/old LDZ2 EQU2 170 | .hovered LDZ2 .picked/old LDZ2 EQU2 ORA 171 | ,&no-on-hovered JCN 172 | .hovered LDZ2 #83 ;draw-tile-cover JSR2 173 | &no-on-hovered 174 | 175 | .picked LDZ2 .hovered/old LDZ2 EQU2 176 | .picked LDZ2 .picked/old LDZ2 EQU2 ORA 177 | ,&no-on-picked JCN 178 | .picked LDZ2 #83 ;draw-tile-cover JSR2 179 | &no-on-picked 180 | 181 | .hovered/old LDZ2 .hovered LDZ2 EQU2 182 | .hovered/old LDZ2 .picked LDZ2 EQU2 ORA 183 | ,&no-off-hovered JCN 184 | .hovered/old LDZ2 #81 ;draw-tile-cover JSR2 185 | &no-off-hovered 186 | 187 | .picked/old LDZ2 .hovered LDZ2 EQU2 188 | .picked/old LDZ2 .picked LDZ2 EQU2 ORA 189 | ,&no-off-picked JCN 190 | .picked/old LDZ2 #81 ;draw-tile-cover JSR2 191 | &no-off-picked 192 | 193 | BRK 194 | 195 | @try-match 196 | .picked LDZ2 .picked/old LDZ2 NEQ2 ,&ok JCN JMP2r &ok 197 | 198 | .picked LDZ2 ;board ADD2 LDA DUP #23 LTH ,&h1 JCN INC #03 ORA &h1 199 | .picked/old LDZ2 ;board ADD2 LDA DUP #23 LTH ,&h2 JCN INC #03 ORA &h2 200 | EQU ,&match JCN JMP2r &match 201 | 202 | #00 .picked LDZ2 ;board ADD2 STA 203 | #00 .picked/old LDZ2 ;board ADD2 STA 204 | .picked LDZ2 ;natural-draw-tile JSR2 205 | .picked/old LDZ2 ;natural-draw-tile JSR2 206 | 207 | #0000 .hovered STZ2 208 | #0000 .hovered/old STZ2 209 | #0000 .picked STZ2 210 | #0000 .picked/old STZ2 211 | 212 | #ff1f .Audio2/adsr DEO2 213 | #0100 .Audio2/length DEO2 214 | ;wave-sus2 .Audio2/addr DEO2 215 | #11 .Audio2/volume DEO 216 | ;prng JSR2 #0005 Mod2 NIP #07 MUL #03 DIV #10 ADD .Audio2/pitch DEO 217 | 218 | ( Play a sound: ) 219 | #0105 .Audio0/adsr DEO2 220 | #0100 .Audio0/length DEO2 221 | ;wave-note .Audio0/addr DEO2 222 | #a6 .Audio0/volume DEO 223 | ;prng JSR2 #0005 Mod2 NIP #07 MUL #03 DIV #40 ADD .Audio0/pitch DEO 224 | 225 | #2105 .Audio1/adsr DEO2 226 | #0100 .Audio1/length DEO2 227 | ;wave-note .Audio1/addr DEO2 228 | #6a .Audio1/volume DEO 229 | ;prng JSR2 #0005 Mod2 NIP #07 MUL #03 DIV #4c ADD .Audio1/pitch DEO 230 | 231 | ;redraw-board JSR2 232 | JMP2r 233 | 234 | @match-array 235 | $30 236 | 237 | @redraw-board 238 | ;turtle 239 | LIT2r 0000 240 | 241 | #0030 242 | &next-clear 243 | #0001 SUB2 244 | DUP2 ;match-array ADD2 #00 ROT ROT STA 245 | ORAk ,&next-clear JCN 246 | POP2 247 | 248 | &next-turtle-entry 249 | LDA2k ( turtle nxyz / i ) 250 | &next-tile 251 | ORAk ,&yes JCN POP2 POP2 POP2r ,&draw-counter JMP &yes 252 | DUP2 #0fff AND2 ( turtle nxyz xyz ) 253 | DUP2 Bd #00 EQU ,&nah JCN 254 | DUP2 ;is-free JSR2 ( turtle nxyz xyz isfree ) 255 | #00 EQU ,¬-free JCN 256 | ( turtle nxyz xyz ) 257 | DUP2 Bd DUP #23 LTH ,&h1 JCN INC #03 ORA &h1 258 | Ext ;match-array ADD2 259 | LDAk INC ROT ROT STA 260 | 261 | ¬-free 262 | #81 ;draw-tile JSR2 ( turtle nxyz ) ,&whatevs JMP &nah POP2 &whatevs 263 | #0ffe SUB2 ( turtle n-1,x+2,y,z ) 264 | INC2r ( i++ ) 265 | DUP2 #0fff GTH2 ,&next-tile JCN 266 | POP2 267 | INC2 INC2 268 | ,&next-turtle-entry JMP 269 | &draw-counter 270 | #00 271 | #0030 272 | &next-count 273 | #0001 SUB2 274 | DUP2 ;match-array ADD2 LDA #01 GTH ( total idx* ismatch ) 275 | STH ROT STHr ADD ( idx* total+match ) 276 | ROT ROT 277 | ORAk ,&next-count JCN 278 | POP2 279 | #0048 #0000 ;draw-number JSR2 280 | JMP2r 281 | 282 | @new-game 283 | ( Play a new-game-y sound: ) 284 | #2209 .Audio0/adsr DEO2 #0100 .Audio0/length DEO2 ;wave-sus2 .Audio0/addr DEO2 #55 .Audio0/volume DEO #18 .Audio0/pitch DEO 285 | #020c .Audio1/adsr DEO2 #0100 .Audio1/length DEO2 ;wave-note .Audio1/addr DEO2 #84 .Audio1/volume DEO #30 .Audio1/pitch DEO 286 | #420c .Audio2/adsr DEO2 #0100 .Audio2/length DEO2 ;wave-note .Audio2/addr DEO2 #66 .Audio2/volume DEO #37 .Audio2/pitch DEO 287 | #820c .Audio3/adsr DEO2 #0100 .Audio3/length DEO2 ;wave-note .Audio3/addr DEO2 #48 .Audio3/volume DEO #3e .Audio3/pitch DEO 288 | 289 | ( Deal tiles into an array: ) 290 | ;deal 291 | #01 292 | &next-tile 293 | ( ptr* tile ) 294 | DUP 295 | #23 LTH #03 MUL INC ( ptr* tile count ) 296 | &next-copy 297 | STH ROTk ROT STA STHr ( ptr* tile count ) 298 | SWP2 INC2 SWP2 ( ptr* tile count ) 299 | #01 SUB 300 | DUP ,&next-copy JCN POP 301 | INC 302 | DUP #2b LTH ,&next-tile JCN POP 303 | ;deal #0090 ;shuffle JSR2 304 | JMP2r 305 | 306 | @shuffle ( arr* len* -- ) ( Fisher-Yates shuffle ) 307 | SWP2 STH2 ( len* ) 308 | &next-swap 309 | ;prng JSR2 OVR2 Mod2 ( i+1* j* ) 310 | SWP2 #0001 SUB2 ( j* i* ) 311 | .i STZ2 .j STZ2 ( ) 312 | STH2rk .i LDZ2 ADD2 LDA ( arr[i] ) 313 | STH2rk .j LDZ2 ADD2 LDA ( arr[i] arr[j] ) 314 | STH2rk .i LDZ2 ADD2 STA ( arr[i] ) 315 | STH2rk .j LDZ2 ADD2 STA ( ) 316 | .i LDZ2 ( i* ) 317 | ORAk ,&next-swap JCN 318 | POP2 POP2r 319 | JMP2r 320 | 321 | @make-turtle 322 | ;turtle 323 | LIT2r 0000 324 | &next-turtle-entry 325 | LDA2k ( turtle nxyz / i ) 326 | &next-tile 327 | ORAk ,&yes JCN POP2 POP2 POP2r JMP2r &yes 328 | DUP2 #0fff AND2 ( turtle nxyz xyz ) 329 | STH2rk ;deal ADD2 LDA ( turtle nxyz xyz t ) 330 | Ovrsb ;board ADD2 STA ( turtle nxyz xyz ) 331 | ( #81 ;draw-tile JSR2 ) POP2 ( turtle nxyz ) 332 | #0ffe SUB2 ( turtle n-1,x+2,y,z ) 333 | INC2r ( i++ ) 334 | DUP2 #0fff GTH2 ,&next-tile JCN 335 | POP2 336 | INC2 INC2 337 | ,&next-turtle-entry JMP 338 | @turtle 339 | ( Array of xyz|n<<12 ) 340 | c002 8046 a084 c0c2 10e0 20fa c102 a144 8186 c1c2 341 | 6248 6288 62c8 6308 6348 6388 342 | 448a 44ca 450a 454a 343 | 26cc 270c 344 | 18ed 345 | 0000 ( end ) 346 | 347 | @deal ( Filled and shuffled to generate the board ) 348 | $90 349 | 350 | @board ( board[z<<9 | y<<5 | x] = tile ) 351 | $0a00 352 | 353 | @natural-draw-tile ( xyz* -- ) 354 | DUP2 .hovered LDZ2 EQU2 355 | Ovrsb .picked LDZ2 EQU2 ORA 356 | DUP ADD INC #80 ORA 357 | @draw-tile ( xyz* col -- ) 358 | ROT ROT ( col xyz* ) 359 | STH2 360 | STH2rk ;board ADD2 LDA ( col tile -- ) 361 | ( DUP ,&nonzero JCN POP2r POP2 JMP2r &nonzero ) 362 | Ext #0060 MUL2 ;s-blank ADD2 Ssa ( col -- ) 363 | STH2rk #001f AND2 #30 SFT2 #0010 ADD2 Ssx ( col -- ) 364 | STH2rk #05 SFT2 #000f AND2 #000b MUL2 #0010 ADD2 365 | STH2rk #29 SFT2 SUB2 Ssy 366 | ( col -- ) 367 | Aut1ay Sprrr ( -- ) 368 | POP2r 369 | JMP2r 370 | 371 | @draw-tile-cover ( xyz* col -- ) 372 | ( Early exit if zero ) 373 | STH ORAk ,&non-zero JCN POPr POP2 JMP2r &non-zero STHr 374 | 375 | ROTk ROT ROT ;draw-tile JSR2 376 | POP ( xyz* ) 377 | DUP2 378 | ( Redraw the whole column in front of xyz: ) 379 | &next-y 380 | #0020 ADD2 ( y+=1 ) 381 | #01ff AND2 ( z=0 ) 382 | &next-z 383 | DUP2 ;board ADD2 LDA #00 EQU ,&nah JCN 384 | DUP2 ;natural-draw-tile JSR2 &nah 385 | #0200 ADD2 ( z++ ) 386 | DUP2 #0a00 LTH2 ,&next-z JCN 387 | DUP2 #0be0 LTH2 ,&next-y JCN 388 | POP2 389 | 390 | #08ed EQU2 ,&is-top JCN 391 | #08ed Bd #00 EQU ,&is-top JCN 392 | #08ed ;natural-draw-tile JSR2 393 | &is-top 394 | JMP2r 395 | 396 | @is-free ( xyz* -- bool ) 397 | ORAk ,&non-zero JCN POP2 #00 JMP2r &non-zero 398 | STH2 399 | 400 | STH2rk #0022 SUB2 Bd #00 GTH STH2rk #01ff AND2 #001f GTH2 AND 401 | STH2rk #0002 SUB2 Bd ORA 402 | STH2rk #001e ADD2 Bd ORA #00 EQU 403 | 404 | STH2rk #001e SUB2 Bd #00 GTH STH2rk #01ff AND2 #001f GTH2 AND 405 | STH2rk #0002 ADD2 Bd ORA 406 | STH2rk #0022 ADD2 Bd ORA #00 EQU 407 | ORA 408 | 409 | STH2rk #07ff GTH2 410 | 411 | STH2rk #0200 ADD2 Bd #00 EQU 412 | STH2r #0600 LTH2 #08ed Bd #00 EQU ORA 413 | AND 414 | ORA 415 | AND 416 | JMP2r 417 | 418 | @mouse-to-tile ( mx* my* -- xyz* ) 419 | ( 420 | Tile x,y,z is rendered at [8*x+10, b*y-4*z+10] 421 | 422 | So mouse mx,my is tile [ [mx-10]>>3, [[my-10+4*z]/b], z ] for z=4..0 423 | ...also checking one tile left and one or two tiles up 424 | ) 425 | .my STZ2 .mx STZ2 426 | 427 | #0004 428 | &next-z 429 | #0000 430 | &next-ty 431 | #0000 432 | &next-tx 433 | 434 | ( z* ty* tx* ) 435 | ROT2k 436 | ( z* ty* tx* ty* tx* z* ) 437 | STH2k ( save z* ) 438 | .my LDZ2 #0010 SUB2 SWP2 #20 SFT2 ADD2 439 | ( z* ty* tx* ty* tx* my-10+4z ) 440 | #000b DIV2 ROT2 SUB2 441 | ( z* ty* tx* tx* my-10+4z/b-ty ) 442 | DUP2 #0010 LTH2 ,&ok-y JCN 443 | POP2 POP2r ,&no-tile JMP 444 | &ok-y 445 | 446 | #50 SFT2 447 | .mx LDZ2 #0010 SUB2 #03 SFT2 ROT2 SUB2 448 | ( z* ty* tx* my-10+4z/b-ty<<5 mx-10>>3-tx ) 449 | ORA2 STH2r #90 SFT2 ( restore and use z* ) 450 | ORA2 451 | ( z* ty* tx* i* ) 452 | DUP2 ;board ADD2 LDA 453 | ( z* ty* tx* i* tile ) 454 | #00 EQU ,&no-tile JCN 455 | 456 | ( z* ty* tx* i* ) 457 | DUP2 #0800 LTH2 ( z* ty* tx* i* i<800 ) 458 | Ovrsb #0200 ADD2 ;board ADD2 LDA #00 GTH AND ( z* ty* tz* i* blocked ) 459 | ,&no-tile JCN 460 | 461 | ( return i*: ) 462 | NIP2 NIP2 NIP2 JMP2r 463 | 464 | &no-tile 465 | POP2 466 | ( z* ty* tx* ) 467 | 468 | INC2 469 | DUP2 #0002 NEQ2 ;&next-tx JCN2 470 | POP2 471 | INC2 472 | DUP2 #0002 NEQ2 ;&next-ty JCN2 473 | POP2 474 | #0001 SUB2 475 | DUP2 INC2 ORA ;&next-z JCN2 476 | POP2 477 | 478 | ( no tile found ) 479 | #0000 480 | JMP2r 481 | 482 | @prng-init ( -- ) 483 | 484 | ( seed ) 485 | #00 .DateTime/second DEI 486 | #00 .DateTime/minute DEI #60 SFT2 EOR2 487 | #00 .DateTime/hour DEI #c0 SFT2 EOR2 ,prng/x STR2 488 | #00 .DateTime/hour DEI #04 SFT2 489 | #00 .DateTime/day DEI #10 SFT2 EOR2 490 | #00 .DateTime/month DEI #60 SFT2 EOR2 491 | .DateTime/year DEI2 #a0 SFT2 EOR2 ,prng/y STR2 492 | 493 | JMP2r 494 | 495 | @prng ( -- number* ) 496 | 497 | LIT2 &x $2 498 | DUP2 #50 SFT2 EOR2 499 | DUP2 #03 SFT2 EOR2 500 | LIT2 &y $2 DUP2 ,&x STR2 501 | DUP2 #01 SFT2 EOR2 EOR2 502 | ,&y STR2k POP 503 | 504 | JMP2r 505 | 506 | ( theme ) 507 | 508 | @load-theme ( -- ) 509 | 510 | ;&path .File/name DEO2 511 | #0002 .File/length DEO2 512 | ;&r .File/read DEO2 513 | ;&g .File/read DEO2 514 | ;&b .File/read DEO2 515 | .File/success DEI2 ORA #01 JCN JMP2r 516 | LIT2 &r $2 .System/r DEO2 517 | LIT2 &g $2 .System/g DEO2 518 | LIT2 &b $2 .System/b DEO2 519 | 520 | JMP2r 521 | &path ".theme $1 522 | 523 | ~tiles.tal 524 | ~sus2.tal 525 | ~note.tal 526 | ~font.tal 527 | -------------------------------------------------------------------------------- /sus2.tal: -------------------------------------------------------------------------------- 1 | @wave-sus2 2 | 80 c3 e1 d3 af 91 86 86 89 8a 8c 8c 85 79 72 78 3 | 84 84 71 59 54 6b 8c 9b 8c 6e 59 59 65 72 7c 89 4 | 99 a3 a1 98 92 92 8d 7b 65 5e 72 94 a8 9f 85 73 5 | 77 86 8d 83 70 60 5a 5d 68 7b 8f 96 82 5d 43 50 6 | 7f b3 ca bb 9d 88 83 86 87 85 84 84 7f 76 72 77 7 | 7d 75 5b 40 41 65 99 bb ba a1 85 75 6d 68 67 71 8 | 84 96 9c 98 92 8f 86 73 5e 5a 71 93 a4 94 72 5b 9 | 60 79 91 9b 99 92 8a 81 79 79 7e 7d 6a 4c 3b 4e 10 | 7f b1 c4 b3 95 82 81 86 86 7e 75 6d 66 64 6e 86 11 | 9f a4 8d 6b 5b 6c 8e a5 a1 8c 79 70 6d 67 63 69 12 | 7b 8e 98 97 92 8a 7a 5e 45 44 66 9a be bf a4 8a 13 | 82 88 8d 89 80 7b 7b 7a 78 79 7c 77 62 44 35 4c 14 | 7f af bc a2 7d 69 70 84 97 a2 a5 9f 8f 7c 72 79 15 | 88 8c 7a 60 57 6b 8d a1 9a 84 72 6d 6d 67 5e 5c 16 | 66 76 83 8d 9a a6 a6 91 73 64 73 94 ab a6 8e 7b 17 | 7b 87 8d 86 7a 73 73 75 76 79 79 6e 50 2c 1e 3c 18 | -------------------------------------------------------------------------------- /tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lynn/shanghai/a47743f02b25555632a79e7195864bd1af09dd35/tiles.png -------------------------------------------------------------------------------- /tiles.tal: -------------------------------------------------------------------------------- 1 | @s-blank 2 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8 | ( @s-dot-1 ) 9 | 00 00 00 00 00 00 03 07 00 7f ff ff fc f0 e3 e7 10 | 00 00 00 00 00 00 c0 e0 00 fe ff ff 3f 0f c7 e7 11 | 0e 0c 0c 0e 07 03 00 00 cf cf cf cf e7 e3 f0 fc 12 | 70 30 30 70 e0 c0 00 00 f3 f3 f3 f3 e7 c7 0f 3f 13 | 00 00 00 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 14 | 00 00 00 00 01 ff ff fe ff ff ff ff fe 00 00 00 15 | ( @s-dot-2 ) 16 | 00 00 00 00 01 03 06 06 00 7f ff ff fe fc f9 f9 17 | 00 00 00 00 80 c0 60 60 00 fe ff ff 7f 3f 9f 9f 18 | 03 01 00 00 00 00 00 00 fc fe ff ff fe fc f9 f9 19 | c0 80 00 00 00 00 00 00 3f 7f ff ff 7f 3f 9f 9f 20 | 00 00 00 00 80 ff ff 7f fc fe ff ff 7f 00 00 00 21 | 00 00 00 00 01 ff ff fe 3f 7f ff ff fe 00 00 00 22 | ( @s-dot-3 ) 23 | 00 00 00 18 3c 66 66 3c 00 7f ff e7 c3 99 99 c3 24 | 00 00 00 00 00 00 00 00 00 fe ff ff ff ff ff ff 25 | 19 03 06 06 03 01 00 00 e7 ff ff ff ff ff ff ff 26 | 80 c0 60 60 c0 80 00 00 ff ff ff ff ff e7 c3 99 27 | 00 00 00 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 28 | 00 00 00 00 01 ff ff fe 99 c3 e7 ff fe 00 00 00 29 | ( @s-dot-4 ) 30 | 00 00 00 00 00 00 00 00 00 7f ff ff f3 e1 e1 f3 31 | 00 00 00 00 30 78 78 30 00 fe ff ff cf 87 87 cf 32 | 00 00 00 00 00 00 0c 1e ff ff ff ff ff ff f3 e1 33 | 00 00 00 00 00 00 00 00 ff ff ff ff ff ff cf 87 34 | 1e 0c 00 00 80 ff ff 7f e1 f3 ff ff 7f 00 00 00 35 | 00 00 00 00 01 ff ff fe 87 cf ff ff fe 00 00 00 36 | ( @s-dot-5 ) 37 | 00 00 00 00 00 00 00 00 00 7f ff ff f3 e1 e1 f3 38 | 00 00 00 00 30 78 78 30 00 fe ff ff cf 87 87 cf 39 | 00 01 03 03 01 00 0c 1e ff ff ff ff ff ff f3 e1 40 | 00 80 c0 c0 80 00 00 00 ff ff ff ff ff ff cf 87 41 | 1e 0c 00 00 80 ff ff 7f e1 f3 ff ff 7f 00 00 00 42 | 00 00 00 00 01 ff ff fe 87 cf ff ff fe 00 00 00 43 | ( @s-dot-6 ) 44 | 00 00 00 00 00 00 00 00 00 7f ff ff f3 e1 e1 f3 45 | 00 00 00 00 00 00 00 00 00 fe ff ff cf 87 87 cf 46 | 00 0c 1e 1e 0c 00 0c 1e ff ff ff ff ff ff ff ff 47 | 00 30 78 78 30 00 30 78 ff ff ff ff ff ff ff ff 48 | 1e 0c 00 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 49 | 78 30 00 00 01 ff ff fe ff ff ff ff fe 00 00 00 50 | ( @s-dot-7 ) 51 | 00 00 00 00 00 00 00 00 00 7f ff cf 86 84 cc fe 52 | 00 00 00 00 00 00 00 00 00 fe ff ff 7f 33 21 61 53 | 00 00 0c 1e 1e 0c 00 0c ff ff ff ff ff ff ff ff 54 | 00 00 30 78 78 30 00 30 f3 ff ff ff ff ff ff ff 55 | 1e 1e 0c 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 56 | 78 78 30 00 01 ff ff fe ff ff ff ff fe 00 00 00 57 | ( @s-dot-8 ) 58 | 00 0c 1e 1e 0c 00 0c 1e 00 73 e1 e1 f3 ff f3 e1 59 | 00 30 78 78 30 00 30 78 00 ce 87 87 cf ff cf 87 60 | 1e 0c 00 0c 1e 1e 0c 00 e1 f3 ff f3 e1 e1 f3 ff 61 | 78 30 00 30 78 78 30 00 87 cf ff cf 87 87 cf ff 62 | 0c 1e 1e 0c 80 ff ff 7f f3 e1 e1 f3 7f 00 00 00 63 | 30 78 78 30 01 ff ff fe cf 87 87 cf fe 00 00 00 64 | ( @s-dot-9 ) 65 | 00 00 00 31 7b 7b 31 00 00 7f ff ce 84 84 ce ff 66 | 00 00 00 8c de de 8c 00 00 fe ff 73 21 21 73 ff 67 | 00 31 7b 7b 31 00 00 00 ff ff ff ff ff ff ff ce 68 | 00 8c de de 8c 00 00 00 ff ff ff ff ff ff ff 73 69 | 00 00 00 00 80 ff ff 7f 84 84 ce ff 7f 00 00 00 70 | 00 00 00 00 01 ff ff fe 21 21 73 ff fe 00 00 00 71 | ( @s-bamboo-1 ) 72 | 00 00 00 20 20 30 38 3c 00 7f ff df df cf c7 c3 73 | 00 00 00 00 00 00 00 00 00 f6 e7 cf 9b 93 37 3f 74 | 0e 3f 3f 06 1e 0e 18 32 f1 c0 c0 f9 e1 f1 e7 cf 75 | 02 06 0e 1e 38 7e fc e0 3d f9 f1 e1 c7 81 03 1f 76 | 34 21 3e 30 80 ff ff 7f cf de f1 ff 7f 00 00 00 77 | f8 70 60 00 01 ff ff fe 07 8f 9f ff fe 00 00 00 78 | ( @s-bamboo-2 ) 79 | 00 00 00 00 00 00 00 00 00 7f ff fc fe fe fe fe 80 | 00 00 00 00 00 00 00 00 00 fe ff 3f 7f 7f 7f 7f 81 | 00 00 00 00 00 00 00 00 fe fc ff fc fe fe fe fe 82 | 00 00 00 00 00 00 00 00 7f 3f ff 3f 7f 7f 7f 7f 83 | 00 00 00 00 80 ff ff 7f fe fc ff ff 7f 00 00 00 84 | 00 00 00 00 01 ff ff fe 7f 3f ff ff fe 00 00 00 85 | ( @s-bamboo-3 ) 86 | 00 00 00 00 00 00 00 00 00 7f ff fc fe fe fe fe 87 | 00 00 00 00 00 00 00 00 00 fe ff 3f 7f 7f 7f 7f 88 | 00 00 00 00 00 00 00 00 fe fc ff c3 e7 e7 e7 e7 89 | 00 00 00 00 00 00 00 00 7f 3f ff c3 e7 e7 e7 e7 90 | 00 00 00 00 80 ff ff 7f e7 c3 ff ff 7f 00 00 00 91 | 00 00 00 00 01 ff ff fe e7 c3 ff ff fe 00 00 00 92 | ( @s-bamboo-4 ) 93 | 00 00 00 00 00 00 00 00 00 7f ff c3 e7 e7 e7 e7 94 | 00 00 00 00 00 00 00 00 00 fe ff c3 e7 e7 e7 e7 95 | 00 00 00 00 00 00 00 00 e7 c3 ff c3 e7 e7 e7 e7 96 | 00 00 00 00 00 00 00 00 e7 c3 ff c3 e7 e7 e7 e7 97 | 00 00 00 00 80 ff ff 7f e7 c3 ff ff 7f 00 00 00 98 | 00 00 00 00 01 ff ff fe e7 c3 ff ff fe 00 00 00 99 | ( @s-bamboo-5 ) 100 | 00 00 00 00 00 00 00 03 00 7f ff 87 cf cf cf cf 101 | 00 00 00 00 00 00 00 c0 00 fe ff e1 f3 f3 f3 f3 102 | 01 01 01 01 01 03 00 00 cf 87 ff 87 cf cf cf cf 103 | 80 80 80 80 80 c0 00 00 f3 e1 ff e1 f3 f3 f3 f3 104 | 00 00 00 00 80 ff ff 7f cf 87 ff ff 7f 00 00 00 105 | 00 00 00 00 01 ff ff fe f3 e1 ff ff fe 00 00 00 106 | ( @s-bamboo-6 ) 107 | 00 00 00 00 00 00 00 00 00 7f ff 84 ce ce ce ce 108 | 00 00 00 00 00 00 00 00 00 fe ff 21 73 73 73 73 109 | 00 00 00 00 00 00 00 00 ce 84 ff 84 ce ce ce ce 110 | 00 00 00 00 00 00 00 00 73 21 ff 21 73 73 73 73 111 | 00 00 00 00 80 ff ff 7f ce 84 ff ff 7f 00 00 00 112 | 00 00 00 00 01 ff ff fe 73 21 ff ff fe 00 00 00 113 | ( @s-bamboo-7 ) 114 | 00 00 03 01 01 01 03 00 00 7f ff ff ff ff ff ff 115 | 00 00 c0 80 80 80 c0 00 00 fe ff ff ff ff ff ff 116 | 00 00 00 00 00 00 00 00 84 ce ce ce 84 ff 84 ce 117 | 00 00 00 00 00 00 00 00 21 73 73 73 21 ff 21 73 118 | 00 00 00 00 80 ff ff 7f ce ce 84 ff 7f 00 00 00 119 | 00 00 00 00 01 ff ff fe 73 73 21 ff fe 00 00 00 120 | ( @s-bamboo-8 ) 121 | 00 00 00 00 00 00 00 00 00 7f ff 84 cc c8 c1 c3 122 | 00 00 00 00 00 00 00 00 00 fe ff 21 33 13 83 c3 123 | 00 00 00 00 00 00 00 00 c7 87 ff 87 c7 c3 c1 c8 124 | 00 00 00 00 00 00 00 00 e3 e1 ff e1 e3 c3 83 13 125 | 00 00 00 00 80 ff ff 7f cc 84 ff ff 7f 00 00 00 126 | 00 00 00 00 01 ff ff fe 33 21 ff ff fe 00 00 00 127 | ( @s-bamboo-9 ) 128 | 00 00 03 01 01 01 03 00 00 7f 87 cf cf cf 87 ff 129 | 00 00 de 8c 8c 8c de 00 00 fe e1 f3 f3 f3 e1 ff 130 | 03 01 01 01 03 00 03 01 87 cf cf cf 87 ff 87 cf 131 | de 8c 8c 8c de 00 de 8c e1 f3 f3 f3 e1 ff e1 f3 132 | 01 01 03 00 80 ff ff 7f cf cf 87 ff 7f 00 00 00 133 | 8c 8c de 00 01 ff ff fe f3 f3 e1 ff fe 00 00 00 134 | ( @s-char-1 ) 135 | 00 00 00 00 00 1f 00 00 00 7f ff ff ff e0 ff ff 136 | 00 00 00 00 30 f8 00 00 00 fe ff ff cf 07 ff ff 137 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 138 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 139 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 140 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 141 | ( @s-char-2 ) 142 | 00 00 00 0f 00 00 00 1f 00 7f ff f0 ff ff ff e0 143 | 00 00 00 f0 00 00 00 f8 00 fe ff 0f ff ff ff 07 144 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 145 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 146 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 147 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 148 | ( @s-char-3 ) 149 | 00 00 00 0f 00 07 00 1f 00 7f ff f0 ff f8 ff e0 150 | 00 00 00 f0 00 e0 00 f8 00 fe ff 0f ff 1f ff 07 151 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 152 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 153 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 154 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 155 | ( @s-char-4 ) 156 | 00 00 00 3f 1b 1e 18 1f 00 7f ff c0 e4 e1 e7 e0 157 | 00 00 00 fc 6c 7c 0c f8 00 fe ff 03 93 83 f3 07 158 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 159 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 160 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 161 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 162 | ( @s-char-5 ) 163 | 00 00 1d 38 1b 19 19 1f 00 7f e2 c7 e4 e6 e6 e0 164 | 00 00 c0 c0 f0 b0 b0 fc 00 fe 3f 3f 0f 4f 4f 03 165 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 166 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 167 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 168 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 169 | ( @s-char-6 ) 170 | 00 00 01 3f 00 08 1c 18 00 7f fe c0 ff f7 e3 e7 171 | 00 00 80 fc 00 30 78 18 00 fe 7f 03 ff cf 87 e7 172 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 173 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 174 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 175 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 176 | ( @s-char-7 ) 177 | 00 00 0c 0c 3f 0c 0c 0f 00 7f f3 f3 c0 f3 f3 f0 178 | 00 00 00 fc 00 00 18 f8 00 fe ff 03 ff ff e7 07 179 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 180 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 181 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 182 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 183 | ( @s-char-8 ) 184 | 00 00 0f 00 0c 0c 18 18 00 7f f0 ff f3 f3 e7 e7 185 | 00 00 c0 60 60 30 30 3c 00 fe 3f 9f 9f cf cf c3 186 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 187 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 188 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 189 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 190 | ( @s-char-9 ) 191 | 00 00 03 03 3f 06 0e 3c 00 7f fc fc c0 f9 f1 c3 192 | 00 00 00 00 e0 60 6c 7c 00 fe ff ff 1f 9f 93 83 193 | 00 00 06 3f 06 0f 0d 0f ff ff ff ff ff ff ff ff 194 | 00 00 60 fc 60 f0 b0 f0 ff ff ff ff ff ff ff ff 195 | 3f 31 37 10 80 ff ff 7f ff ff ff ff 7f 00 00 00 196 | fe b6 e6 0c 01 ff ff fe ff ff ff ff fe 00 00 00 197 | ( @s-honor-1 ) 198 | 00 00 00 00 00 00 00 00 00 7f ff ff ff ff ff ff 199 | 00 00 00 00 00 00 00 00 00 fe ff ff ff ff ff ff 200 | 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff 201 | 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff 202 | 00 00 00 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 203 | 00 00 00 00 01 ff ff fe ff ff ff ff fe 00 00 00 204 | ( @s-honor-2 ) 205 | 00 00 00 00 00 00 00 00 00 7f ff e1 f9 f9 c3 e7 206 | 00 00 00 00 00 00 00 00 00 fe ff 27 27 8f c1 e7 207 | 00 00 00 00 00 00 00 00 82 92 f2 c0 cf ce c1 f9 208 | 00 00 00 00 00 00 00 00 11 4f 4f 43 ff 03 e7 0f 209 | 00 00 00 00 80 ff ff 7f f3 c2 e4 ff 7f 00 00 00 210 | 00 00 00 00 01 ff ff fe 87 63 f3 ff fe 00 00 00 211 | ( @s-honor-3 ) 212 | 00 00 00 03 01 01 01 01 00 7f ff ff ff ff ff ff 213 | 00 00 00 80 80 80 80 80 00 fe ff ff ff ff ff ff 214 | 3f 31 31 31 3f 01 01 01 ff ff ff ff ff ff ff ff 215 | fc 8c 8c 98 fc 80 80 80 ff ff ff ff ff ff ff ff 216 | 01 01 01 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 217 | 80 80 00 00 01 ff ff fe ff ff ff ff fe 00 00 00 218 | ( @s-honor-4 ) 219 | 00 00 00 01 1f 01 3f 31 00 7f ff fe e0 fe c0 ce 220 | 00 00 00 80 f8 80 fc 8c 00 fe ff 7f 07 7f 03 73 221 | 3f 19 1f 03 07 0d 31 01 c0 e6 e0 fc f8 f2 ce fe 222 | fc 98 f0 c0 f0 bc 9e 80 03 67 0f 3f 0f 43 61 7f 223 | 07 03 00 00 80 ff ff 7f f8 fc ff ff 7f 00 00 00 224 | 80 80 00 00 01 ff ff fe 7f 7f ff ff fe 00 00 00 225 | ( @s-honor-5 ) 226 | 00 00 00 01 3f 01 3f 36 00 7f ff fe c0 fe c0 c9 227 | 00 00 00 80 fc 80 fc 6c 00 fe ff 7f 03 7f 03 93 228 | 32 37 31 3f 31 31 31 30 cd c8 ce c0 ce ce ce cf 229 | 4c ec 8c fc 8c 8c 0c 4c b3 13 73 03 73 73 f3 b3 230 | 10 00 00 00 80 ff ff 7f ef ff ff ff 7f 00 00 00 231 | 3c 18 00 00 01 ff ff fe c3 e7 ff ff fe 00 00 00 232 | ( @s-honor-6 ) 233 | 00 00 00 00 1f 06 06 3f 00 7f ff ff e0 f9 f9 c0 234 | 00 00 00 00 f8 c0 c0 f8 00 fe ff ff 07 3f 3f 07 235 | 36 36 36 36 36 3c 18 1f c9 c9 c9 c9 c9 c3 e7 e0 236 | cc cc cc dc fc ec 0c fc 33 33 33 23 03 13 f3 03 237 | 10 00 00 00 80 ff ff 7f ef ff ff ff 7f 00 00 00 238 | 1c 00 00 00 01 ff ff fe e3 ff ff ff fe 00 00 00 239 | ( @s-honor-7 ) 240 | 00 00 00 00 06 06 06 3e 00 7f ff ff f9 f9 f9 c1 241 | 00 00 00 00 e0 60 64 6c 00 fe ff ff 1f 9f 9b 93 242 | 06 06 06 06 06 0e 3e 36 f9 f9 f9 f9 f9 f1 c1 c9 243 | 78 60 60 60 60 60 60 6c 87 9f 9f 9f 9f 9f 9f 93 244 | 06 00 00 00 80 ff ff 7f f9 ff ff ff 7f 00 00 00 245 | 7c 00 00 00 01 ff ff fe 83 ff ff ff fe 00 00 00 246 | ( @s-bonus-1 ) 247 | 00 00 28 3e 28 3e 2e 00 00 7f d7 c1 d7 c1 d1 ff 248 | 00 00 18 38 18 18 18 00 00 fe ff ff ff ff ff ff 249 | 01 03 1b 3f 3e 3c 1c 0e ff ff fe ff f3 fb ff fb 250 | 80 c0 d8 fc 7c 3c 38 70 ff ff 7f ff cf df ff df 251 | 1f 1f 0e 00 80 ff ff 7f f9 ff ff ff 7f 00 00 00 252 | f8 f8 70 00 01 ff ff fe 9f ff ff ff fe 00 00 00 253 | ( @s-bonus-2 ) 254 | 00 00 14 3e 36 3e 2a 00 00 7f eb c1 c9 c1 d5 ff 255 | 00 00 78 0c 38 60 7c 00 00 fe ff ff ff ff ff ff 256 | 01 1b 1c 36 32 33 30 30 ff ff ff ff ff ff ff fc 257 | 80 d8 38 6c 4c cc 0c 0c ff ff ff ff ff ff ff 3f 258 | 18 00 00 00 80 ff ff 7f fe f2 f0 ff 7f 00 00 00 259 | 18 00 00 00 01 ff ff fe 7f 4f 0f ff fe 00 00 00 260 | ( @s-bonus-3 ) 261 | 00 00 14 3e 1a 3a 3a 00 00 7f eb c1 e5 c5 c5 ff 262 | 00 00 78 0c 38 0c 78 00 00 fe ff ff ff ff ff ff 263 | 01 1d 16 12 3d 23 33 0d ff ff ff ff ff ff ff ff 264 | c0 78 48 58 b0 cc c4 bc ff ff ff ff ff ff ff ff 265 | 1a 12 1e 03 80 ff ff 7f ff ff ff ff 7f 00 00 00 266 | 48 68 b8 80 01 ff ff fe ff ff ff ff fe 00 00 00 267 | ( @s-bonus-4 ) 268 | 00 00 28 3e 64 24 2c 00 00 7f d7 c1 9b db d3 ff 269 | 00 00 6c 6c 7c 0c 0c 00 00 fe ff ff ff ff ff 3f 270 | 00 00 00 00 00 00 00 00 ff ff e3 c1 fc c3 85 f9 271 | 00 00 00 00 00 00 00 00 3f bf 33 07 33 33 37 bf 272 | 00 00 00 00 80 ff ff 7f f3 e3 e3 ff 7f 00 00 00 273 | 00 00 00 00 01 ff ff fe 1f 3f 3f ff fe 00 00 00 274 | ( @s-bonus-5 ) 275 | 00 00 0c 1c 0c 0c 0c 00 00 7f f3 e3 f3 f3 f3 ff 276 | 00 00 10 38 10 38 5c 00 00 fe ff ff ff ff ff ff 277 | 00 00 00 00 00 00 00 00 ff ff ff e3 c1 f2 fe fe 278 | 00 00 00 00 00 00 00 00 ff ff c7 87 8f 7f 7f 7f 279 | 02 07 03 00 80 ff ff 7f fe ff ff ff 7f 00 00 00 280 | 40 e0 c0 00 01 ff ff fe 7f ff ff ff fe 00 00 00 281 | ( @s-bonus-6 ) 282 | 00 00 3c 06 1c 30 3e 00 00 7f c3 f9 e3 cf c1 ff 283 | 00 00 7c 10 38 38 64 00 00 fe ff ff ff ff ff ff 284 | 00 03 07 0f 1f 1f 1f 1f ff ff ff ff ff ff ff ff 285 | 00 c0 e0 f0 f8 f8 f8 f8 ff ff ff ff ff ff ff ff 286 | 0f 07 03 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 287 | f0 e0 c0 00 01 ff ff fe ff ff ff ff fe 00 00 00 288 | ( @s-bonus-7 ) 289 | 00 00 3c 06 1c 06 3c 00 00 7f c3 f9 e3 f9 c3 ff 290 | 00 00 68 2c 78 2c 34 00 00 fe ff ff ff ff ff ff 291 | 00 01 19 07 0f 1f 07 0f ff ff e7 fb fd fe ff ff 292 | 00 80 f0 e0 c0 f0 f8 f8 ff ff ff ff ff ff 7f 7f 293 | 0f 0e 0c 00 80 ff ff 7f ff ff ff ff 7f 00 00 00 294 | e8 e0 e0 60 01 ff ff fe 7f ff ff ff fe 00 00 00 295 | ( @s-bonus-8 ) 296 | 00 00 36 36 3e 06 06 00 00 7f c9 c9 c1 f9 f9 ff 297 | 00 00 38 28 10 68 4c 00 00 fe ff ff ff ff ff ff 298 | 00 01 02 00 1f 00 0f 00 ff fe fd ff e0 ff f0 ff 299 | 00 80 40 58 84 04 f8 00 ff 7f bf a7 7b fb 07 ff 300 | 1f 00 00 00 80 ff ff 7f e0 ff ff ff 7f 00 00 00 301 | f0 08 10 00 01 ff ff fe 0f f7 ef ff fe 00 00 00 302 | --------------------------------------------------------------------------------