teek 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +46 -0
- data/Rakefile +161 -5
- data/ext/teek/extconf.rb +1 -1
- data/ext/teek/tcltkbridge.c +3 -0
- data/ext/teek/tcltkbridge.h +3 -0
- data/ext/teek/tkeventsource.c +195 -0
- data/ext/teek/tkphoto.c +169 -5
- data/ext/teek/tkwin.c +84 -0
- data/lib/teek/background_ractor4x.rb +32 -4
- data/lib/teek/photo.rb +232 -0
- data/lib/teek/version.rb +1 -1
- data/lib/teek.rb +3 -1
- data/sample/optcarrot/vendor/optcarrot/apu.rb +856 -0
- data/sample/optcarrot/vendor/optcarrot/config.rb +257 -0
- data/sample/optcarrot/vendor/optcarrot/cpu.rb +1162 -0
- data/sample/optcarrot/vendor/optcarrot/driver.rb +144 -0
- data/sample/optcarrot/vendor/optcarrot/mapper/cnrom.rb +14 -0
- data/sample/optcarrot/vendor/optcarrot/mapper/mmc1.rb +105 -0
- data/sample/optcarrot/vendor/optcarrot/mapper/mmc3.rb +153 -0
- data/sample/optcarrot/vendor/optcarrot/mapper/uxrom.rb +14 -0
- data/sample/optcarrot/vendor/optcarrot/nes.rb +105 -0
- data/sample/optcarrot/vendor/optcarrot/opt.rb +168 -0
- data/sample/optcarrot/vendor/optcarrot/pad.rb +92 -0
- data/sample/optcarrot/vendor/optcarrot/palette.rb +65 -0
- data/sample/optcarrot/vendor/optcarrot/ppu.rb +1468 -0
- data/sample/optcarrot/vendor/optcarrot/rom.rb +143 -0
- data/sample/optcarrot/vendor/optcarrot.rb +14 -0
- data/sample/optcarrot.rb +354 -0
- data/sample/paint/assets/bucket.png +0 -0
- data/sample/paint/assets/cursor.png +0 -0
- data/sample/paint/assets/eraser.png +0 -0
- data/sample/paint/assets/pencil.png +0 -0
- data/sample/paint/assets/spray.png +0 -0
- data/sample/paint/layer.rb +255 -0
- data/sample/paint/layer_manager.rb +179 -0
- data/sample/paint/paint_demo.rb +837 -0
- data/sample/paint/sparse_pixel_buffer.rb +202 -0
- data/sample/sdl2_demo.rb +318 -0
- metadata +29 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Optcarrot
|
|
2
|
+
# Pad pair implementation (NES has two built-in game pad.)
|
|
3
|
+
class Pads
|
|
4
|
+
def inspect
|
|
5
|
+
"#<#{ self.class }>"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
###########################################################################
|
|
9
|
+
# initialization
|
|
10
|
+
|
|
11
|
+
def initialize(conf, cpu, apu)
|
|
12
|
+
@conf = conf
|
|
13
|
+
@cpu = cpu
|
|
14
|
+
@apu = apu
|
|
15
|
+
@pads = [Pad.new, Pad.new]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def reset
|
|
19
|
+
@cpu.add_mappings(0x4016, method(:peek_401x), method(:poke_4016))
|
|
20
|
+
@cpu.add_mappings(0x4017, method(:peek_401x), @apu.method(:poke_4017)) # delegate 4017H to APU
|
|
21
|
+
@pads[0].reset
|
|
22
|
+
@pads[1].reset
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def peek_401x(addr)
|
|
26
|
+
@cpu.update
|
|
27
|
+
@pads[addr - 0x4016].peek | 0x40
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def poke_4016(_addr, data)
|
|
31
|
+
@pads[0].poke(data)
|
|
32
|
+
@pads[1].poke(data)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
###########################################################################
|
|
36
|
+
# APIs
|
|
37
|
+
|
|
38
|
+
def keydown(pad, btn)
|
|
39
|
+
@pads[pad].buttons |= 1 << btn
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def keyup(pad, btn)
|
|
43
|
+
@pads[pad].buttons &= ~(1 << btn)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
###########################################################################
|
|
48
|
+
# each pad
|
|
49
|
+
class Pad
|
|
50
|
+
A = 0
|
|
51
|
+
B = 1
|
|
52
|
+
SELECT = 2
|
|
53
|
+
START = 3
|
|
54
|
+
UP = 4
|
|
55
|
+
DOWN = 5
|
|
56
|
+
LEFT = 6
|
|
57
|
+
RIGHT = 7
|
|
58
|
+
|
|
59
|
+
def initialize
|
|
60
|
+
reset
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def reset
|
|
64
|
+
@strobe = false
|
|
65
|
+
@buttons = @stream = 0
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def poke(data)
|
|
69
|
+
prev = @strobe
|
|
70
|
+
@strobe = data[0] == 1
|
|
71
|
+
@stream = ((poll_state << 1) ^ -512) if prev && !@strobe
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def peek
|
|
75
|
+
return poll_state & 1 if @strobe
|
|
76
|
+
@stream >>= 1
|
|
77
|
+
return @stream[0]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def poll_state
|
|
81
|
+
state = @buttons
|
|
82
|
+
|
|
83
|
+
# prohibit impossible simultaneous keydown (right and left, up and down)
|
|
84
|
+
state &= 0b11001111 if state & 0b00110000 == 0b00110000
|
|
85
|
+
state &= 0b00111111 if state & 0b11000000 == 0b11000000
|
|
86
|
+
|
|
87
|
+
state
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
attr_accessor :buttons
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Optcarrot
|
|
2
|
+
# NES palette generators
|
|
3
|
+
module Palette
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
# I don't know where this palette definition came from, but many emulators are using this palette
|
|
7
|
+
def defacto_palette
|
|
8
|
+
[
|
|
9
|
+
[1.00, 1.00, 1.00], # default
|
|
10
|
+
[1.00, 0.80, 0.81], # emphasize R
|
|
11
|
+
[0.78, 0.94, 0.66], # emphasize G
|
|
12
|
+
[0.79, 0.77, 0.63], # emphasize RG
|
|
13
|
+
[0.82, 0.83, 1.12], # emphasize B
|
|
14
|
+
[0.81, 0.71, 0.87], # emphasize RB
|
|
15
|
+
[0.68, 0.79, 0.79], # emphasize GB
|
|
16
|
+
[0.70, 0.70, 0.70], # emphasize RGB
|
|
17
|
+
].flat_map do |rf, gf, bf|
|
|
18
|
+
# RGB default palette (I don't know where this palette came from)
|
|
19
|
+
[
|
|
20
|
+
0x666666, 0x002a88, 0x1412a7, 0x3b00a4, 0x5c007e, 0x6e0040, 0x6c0600, 0x561d00,
|
|
21
|
+
0x333500, 0x0b4800, 0x005200, 0x004f08, 0x00404d, 0x000000, 0x000000, 0x000000,
|
|
22
|
+
0xadadad, 0x155fd9, 0x4240ff, 0x7527fe, 0xa01acc, 0xb71e7b, 0xb53120, 0x994e00,
|
|
23
|
+
0x6b6d00, 0x388700, 0x0c9300, 0x008f32, 0x007c8d, 0x000000, 0x000000, 0x000000,
|
|
24
|
+
0xfffeff, 0x64b0ff, 0x9290ff, 0xc676ff, 0xf36aff, 0xfe6ecc, 0xfe8170, 0xea9e22,
|
|
25
|
+
0xbcbe00, 0x88d800, 0x5ce430, 0x45e082, 0x48cdde, 0x4f4f4f, 0x000000, 0x000000,
|
|
26
|
+
0xfffeff, 0xc0dfff, 0xd3d2ff, 0xe8c8ff, 0xfbc2ff, 0xfec4ea, 0xfeccc5, 0xf7d8a5,
|
|
27
|
+
0xe4e594, 0xcfef96, 0xbdf4ab, 0xb3f3cc, 0xb5ebf2, 0xb8b8b8, 0x000000, 0x000000,
|
|
28
|
+
].map do |rgb|
|
|
29
|
+
r = [((rgb >> 16 & 0xff) * rf).floor, 0xff].min
|
|
30
|
+
g = [((rgb >> 8 & 0xff) * gf).floor, 0xff].min
|
|
31
|
+
b = [((rgb >> 0 & 0xff) * bf).floor, 0xff].min
|
|
32
|
+
[r, g, b]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Nestopia generates a palette systematically (cool!), but it is not compatible with nes-tests-rom
|
|
38
|
+
def nestopia_palette
|
|
39
|
+
(0..511).map do |n|
|
|
40
|
+
tint, level, color = n >> 6 & 7, n >> 4 & 3, n & 0x0f
|
|
41
|
+
level0, level1 = [[-0.12, 0.40], [0.00, 0.68], [0.31, 1.00], [0.72, 1.00]][level]
|
|
42
|
+
level0 = level1 if color == 0x00
|
|
43
|
+
level1 = level0 if color == 0x0d
|
|
44
|
+
level0 = level1 = 0 if color >= 0x0e
|
|
45
|
+
y = (level1 + level0) * 0.5
|
|
46
|
+
s = (level1 - level0) * 0.5
|
|
47
|
+
iq = Complex.polar(s, Math::PI / 6 * (color - 3))
|
|
48
|
+
if tint != 0 && color <= 0x0d
|
|
49
|
+
if tint == 7
|
|
50
|
+
y = (y * 0.79399 - 0.0782838) * 1.13
|
|
51
|
+
else
|
|
52
|
+
level1 = (level1 * (1 - 0.79399) + 0.0782838) * 0.5
|
|
53
|
+
y -= level1 * 0.5
|
|
54
|
+
y -= level1 *= 0.6 if [3, 5, 6].include?(tint)
|
|
55
|
+
iq += Complex.polar(level1, Math::PI / 12 * ([0, 6, 10, 8, 2, 4, 0, 0][tint] * 2 - 7))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
[[105, 0.570], [251, 0.351], [15, 1.015]].map do |angle, gain|
|
|
59
|
+
clr = y + (Complex.polar(gain * 2, (angle - 33) * Math::PI / 180) * iq.conjugate).real
|
|
60
|
+
[0, (clr * 255).round, 255].sort[1]
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|