How does CHIP 8 graphics rendered on screen?

回眸只為那壹抹淺笑 提交于 2019-12-24 02:10:01

问题


Opcode DXYN: Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels. Each row of 8 pixels is read as bit-coded (with the most significant bit of each byte displayed on the left) starting from memory location I; I value doesn't change after the execution of this instruction. As described above, VF is set to 1 if any screen pixels are flipped from set to unset when the sprite is drawn, and to 0 if that doesn't happen.

Basically I have an array called graphics which is a double array constructed out of 64 rows of new arrays per each with 32 columns.

//Creating new double arrays for storing graphics data
    graphics = new Array(GFX_WIDTH);
        for(var i = 0; i < graphics .length; i++){
            graphics [i] = new Array(GFX_HEIGHT);
            for(var j = 0; j < graphics [i].length; j++){
                graphics [i][j] = 0;
            }
        }

and inside these arrays, I am storing graphics data as described above. My question is, do I just have to draw a square when an array element is 1 and empty that space when it's 0? According to a blog article on CHIP8, there is an extra array for font-set but what's the usage of it?

The blog article I have mentioned above

http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/

Thank you.


回答1:


First of all, note that the pixels are bitpacked - each byte will contain 8 pixels of sprite data. In other words, the byte 0xAA is a single-pixel tall sprite with the first, third, fifth and seventh pixel set.

When drawing your sprite, you need to loop through each bit. If the bit is set, you flip the corresponding bit in your display - 0 becomes 1 and 1 becomes 0. This can, for example, be done by applying the XOR (^) operation to your display byte.

Note, however, that VF must be set to 1 if any pixels go from 1 to 0 in the process, and 0 if no pixels are unset - so you also need to do this. I find it is easiest to read if you have an if that checks whether or not to flip a bit, and then take care of both flipping and VF-updating inside that if.

For reference, my own Delphi implementation of this opcode looks like this:

procedure TChip8CPU.OpcodeD(inst: TInstruction);
var
  X, Y, cX, cY, data: byte;
begin
  Reg[$F] := 0;
  for Y := 0 to inst.NibbleArg - 1 do begin
    cY := (Reg[inst.Y] + Y) mod HEIGHT;
    data := Memory[AddressI + Y];
    for X := 0 to 7 do begin
      if (data and ($80 shr X)) <> 0 then begin
        cX := (Reg[inst.X] + X) mod WIDTH;
        if Display[cY, cX] = 1 then Reg[$F] := 1;
        Display[cY, cX] := Display[cY, cX] xor 1;
      end;
    end;
  end;
end;

Note that for sprites which go outside the screen boundaries, they wrap around (this is done by the mod WIDTH/mod HEIGHT parts). This is mentioned in Cowgod's Chip-8 Technical Reference.



来源:https://stackoverflow.com/questions/17346592/how-does-chip-8-graphics-rendered-on-screen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!