More silly fun/experiments:

I came across a disk image for the computer eyes video digitizer (the very first one that hooked up to the gameport). I thought I'd load it up just to see if it'd do anything. Running a capture I saw that if you pressed the controller button, it would change the screen display. Cool!

[Linked Image from]

Tapping the controller button as it captures: (kinda looks like a barcode)

[Linked Image from]

So this is a 1 bit capture device, capturing 280x192 and it captures 1 bit for each scanline, scanning left to right across the screen.

Well, why not try to send the capture program some data? Gimp is pretty useful in that it can save data in a raw format. I'll create a little 280x192 rgba bitmap and export it as raw data. (gimp seems to want to add an alpha channel to the image)

We'll add some stuff to apple2.cpp:

Make a buffer to hold a picture:
uint m_computereyescapturebuffer[192][280];  // [280][192] that is column major, we want [192][280]
int  m_cex, m_cey;

Give it a save_item so we can access it from lua:

Reset the position when we reset AN0.
printf("set cex,cey to zero AN0   %x\n",state);

 m_an0 = state;

Read a pixel from button 1 and increment the position:

int old_m_cey=m_cey;
int old_m_cex=m_cex;
if ((m_cex==0) && (m_cey==0)) printf(" AN STATUS: %x %x %x %x\n",m_an0,m_an1,m_an2,m_an3);

        u8 uFloatingBus7 = read_floatingbus() & 0x7f;

        // Y output of 74LS251 at H14 read as D7
        switch (offset)
        case 0: // cassette in (accidentally read at $C068 by ProDOS to attempt IIgs STATE register)
                return (m_cassette->input() > 0.0 ? 0x80 : 0) | uFloatingBus7;

        case 1:  // button 0

                return ((m_joybuttons->read() & 0x10) ? 0x80 : 0) | uFloatingBus7;

        case 2:  // button 1

if(m_cey>191) {m_cey=0; m_cex=m_cex+1;}

return (m_computereyescapturebuffer[std::min(old_m_cey,191)][std::min(old_m_cex,279)]>(128*m_an2+64*m_an1+32*m_an3))? 0x80:0;

// capture threshold seems to be 128  *m_an2  +  64 * m_an1    + 32 * m_an3

and since the main machine's saveitems aren't accessible otherwise, we'll add a function to luaengine.cpp

      emu["items"] = [this](){        sol::table table = sol().create_table();
                                        // 10000 is enough?
                                        for(int i = 0; i < 10000; i++)
                                                std::string name;
                                                const char *item;
                                                unsigned int size, count;
                                                void *base;
                                                item = machine().save().indexed_item(i, base, size, count);
                                                if(!item) break;
                                                //name = &(strchr(item, '/')[1]);
                                                name = item;
                                                table[name] = i;                                             
                                        return table;

Now we can load the file into a string:
a=f:read("*a") f:close() print(#a) 
and then write it into our capture "buffer".
quick = emu.items()["Apple ][+/:/0/m_computereyescapturebuffer"] print(quick)
for i=0,280*192-1 do emu.item(quick):write(i,a:byte(1+i*4)) end  -- just grab the red component to make it simple

It's a bit of a hack (yeah ok, it's a total hack), in that I'm not really getting the timing and sync right, I'm just incrementing the read position based on how many times it reads button 1, and resetting that position when it resets AN0.

I want to figure out how to capture a frame with v4l2 and load that up.

Mame logo:
[Linked Image from]

original bitmaps:
[Linked Image from]

8 level capture versus a 2 level capture:
[Linked Image from][Linked Image from]

The 8 bit guy has a video using a computer eyes on a c64 at
At the 6:55 mark you can see what's actually inside, it's pretty simple.

Digital Vision put up a webpage for the history of their products: