vro_cpyfm and logical operations
Posted: 11 Nov 2024 04:42
I'm working on a little web app to let me draw art that can be exported to IGS ("Instant Graphics and Sound") format for use on Atari ST BBSes.
I'm trying to simulate IGS's "grab" (bit-blit) command in Javascript. In IGS on the Atari, this is basically a wrapper for VDI's vro_cpyfm. I don't quite understand how it works.
I thought that vro_cpyfm was comparing the color register values of the source pixel with the destination pixel, and computing a new value using whatever logical operation mode was set. So, for example, say that we use mode 7 ("S OR D" / transparent mode), and our source pixel (0,0) is set to color register 1, and our destination pixel (1,0) is set to color register 6. I thought that vro_cpyfm would perform the operation "1 | 6", which gives a result of "7".
But after implementing this approach, it doesn't match what I see on the Atari. Here's an example where I blitted a Calvin sprite on top of a cardboard box. The lefthand image was made in the IGDEV editor running in Hatari; the righthand image was made in my web-based program.
In my implementation (at right), color 1 (black) becomes 7 (brown) when blitted on top of color 6 (light brown) in mode 7. Similarly, color 13 (yellow hair) becomes 15 pink. 10 (white) becomes 14 (tan). I believe this follows the math: 1 | 6 = 7 ... 13 | 6 = 15 ... 10 | 6 = 14.
But on the Atari, it's mostly different. Color 1 (black) remains color 1 when blitted on top of color 6 (light brown) in mode 7; and color 13 (yellow hair) becomes color 1 (black). One change that matches mine is that color 10 (white) becomes 14 (flesh tone).
Anyway, I need to make my implementation match the Atari, and clearly I have misunderstood what's going on. Can anyone explain in plain language what operations vro_cpyfm actually performs?
I'm trying to simulate IGS's "grab" (bit-blit) command in Javascript. In IGS on the Atari, this is basically a wrapper for VDI's vro_cpyfm. I don't quite understand how it works.
I thought that vro_cpyfm was comparing the color register values of the source pixel with the destination pixel, and computing a new value using whatever logical operation mode was set. So, for example, say that we use mode 7 ("S OR D" / transparent mode), and our source pixel (0,0) is set to color register 1, and our destination pixel (1,0) is set to color register 6. I thought that vro_cpyfm would perform the operation "1 | 6", which gives a result of "7".
But after implementing this approach, it doesn't match what I see on the Atari. Here's an example where I blitted a Calvin sprite on top of a cardboard box. The lefthand image was made in the IGDEV editor running in Hatari; the righthand image was made in my web-based program.
In my implementation (at right), color 1 (black) becomes 7 (brown) when blitted on top of color 6 (light brown) in mode 7. Similarly, color 13 (yellow hair) becomes 15 pink. 10 (white) becomes 14 (tan). I believe this follows the math: 1 | 6 = 7 ... 13 | 6 = 15 ... 10 | 6 = 14.
But on the Atari, it's mostly different. Color 1 (black) remains color 1 when blitted on top of color 6 (light brown) in mode 7; and color 13 (yellow hair) becomes color 1 (black). One change that matches mine is that color 10 (white) becomes 14 (flesh tone).
Anyway, I need to make my implementation match the Atari, and clearly I have misunderstood what's going on. Can anyone explain in plain language what operations vro_cpyfm actually performs?