📄 c4emu.cpp
字号:
C4WFXVal=(short)X2; C4WFYVal=(short)Y2; C4WFZVal=Z2; C4TransfWireFrame2(); X2=(C4WFXVal+48)<<8; Y2=(C4WFYVal+48)<<8; // get line info C4WFXVal=(short)(X1>>8); C4WFYVal=(short)(Y1>>8); C4WFX2Val=(short)(X2>>8); C4WFY2Val=(short)(Y2>>8); C4CalcWireFrame(); X2=(int16)C4WFXVal; Y2=(int16)C4WFYVal; // render line for(int i=C4WFDist?C4WFDist:1; i>0; i--) { //.loop if(X1>0xff && Y1>0xff && X1<0x6000 && Y1<0x6000) { uint16 addr=((X1&~0x7ff) + (Y1&~0x7ff)*12 + (Y1&0x700))>>7; addr=(((Y1>>8)>>3)<<8)-(((Y1>>8)>>3)<<6)+(((X1>>8)>>3)<<4)+((Y1>>8)&7)*2; uint8 bit=0x80>>((X1>>8)&7); Memory.C4RAM[addr+0x300]&=~bit; Memory.C4RAM[addr+0x301]&=~bit; if(Color&1) Memory.C4RAM[addr+0x300]|=bit; if(Color&2) Memory.C4RAM[addr+0x301]|=bit; } X1+=X2; Y1+=Y2; }}static void C4DrawWireFrame(void){ uint8 *line=S9xGetMemPointer(READ_3WORD(Memory.C4RAM+0x1f80)); uint8 *point1, *point2; int16 X1, Y1, Z1; int16 X2, Y2, Z2; uint8 Color;#ifdef DEBUGGER if(READ_3WORD(Memory.C4RAM+0x1f8f)&0xff00ff) printf("wireframe: Unexpected value in $7f8f: %06x\n", READ_3WORD(Memory.C4RAM+0x1f8f)); if(READ_3WORD(Memory.C4RAM+0x1fa4)!=0x001000) printf("wireframe: Unexpected value in $7fa4: %06x\n", READ_3WORD(Memory.C4RAM+0x1fa4));#endif for(int i=Memory.C4RAM[0x0295]; i>0; i--, line+=5){ if(line[0]==0xff && line[1]==0xff){ uint8 *tmp=line-5; while(line[2]==0xff && line[3]==0xff) tmp-=5; point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (tmp[2]<<8) | tmp[3]); } else { point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[0]<<8) | line[1]); } point2=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[2]<<8) | line[3]); X1=(point1[0]<<8) | point1[1]; Y1=(point1[2]<<8) | point1[3]; Z1=(point1[4]<<8) | point1[5]; X2=(point2[0]<<8) | point2[1]; Y2=(point2[2]<<8) | point2[3]; Z2=(point2[4]<<8) | point2[5]; Color=line[4]; C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color); }}static void C4TransformLines(void){ C4WFX2Val=Memory.C4RAM[0x1f83]; C4WFY2Val=Memory.C4RAM[0x1f86]; C4WFDist=Memory.C4RAM[0x1f89]; C4WFScale=Memory.C4RAM[0x1f8c];#ifdef DEBUGGER if(Memory.C4RAM[0x1f8a]!=0x90) printf("lines: $7f8a = %02x, expected 90\n", READ_WORD(Memory.C4RAM+0x1f8a));#endif // transform vertices uint8 *ptr=Memory.C4RAM; { for(int i=READ_WORD(Memory.C4RAM+0x1f80); i>0; i--, ptr+=0x10) { C4WFXVal=READ_WORD(ptr+1); C4WFYVal=READ_WORD(ptr+5); C4WFZVal=READ_WORD(ptr+9); C4TransfWireFrame(); // displace WRITE_WORD(ptr+1, C4WFXVal+0x80); WRITE_WORD(ptr+5, C4WFYVal+0x50); } } WRITE_WORD(Memory.C4RAM+0x600, 23); WRITE_WORD(Memory.C4RAM+0x602, 0x60); WRITE_WORD(Memory.C4RAM+0x605, 0x40); WRITE_WORD(Memory.C4RAM+0x600+8, 23); WRITE_WORD(Memory.C4RAM+0x602+8, 0x60); WRITE_WORD(Memory.C4RAM+0x605+8, 0x40); ptr=Memory.C4RAM+0xb02; uint8 *ptr2=Memory.C4RAM; { for(int i=READ_WORD(Memory.C4RAM+0xb00); i>0; i--, ptr+=2, ptr2+=8) { C4WFXVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+1); C4WFYVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+5); C4WFX2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+1); C4WFY2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+5); C4CalcWireFrame(); WRITE_WORD(ptr2+0x600, C4WFDist?C4WFDist:1); WRITE_WORD(ptr2+0x602, C4WFXVal); WRITE_WORD(ptr2+0x605, C4WFYVal); } }}static void C4BitPlaneWave(){ static uint16 bmpdata[]={ 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A, 0x000C, 0x000E, 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020A, 0x020C, 0x020E, 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040A, 0x040C, 0x040E, 0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060A, 0x060C, 0x060E, 0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080A, 0x080C, 0x080E }; uint8 *dst=Memory.C4RAM; uint32 waveptr=Memory.C4RAM[0x1f83]; uint16 mask1=0xc0c0; uint16 mask2=0x3f3f;#ifdef DEBUGGER if(READ_3WORD(Memory.C4RAM+0x1f80) != Memory.C4RAM[waveptr+0xb00]) printf("$7f80=%06x, expected %02x\n", READ_3WORD(Memory.C4RAM+0x1f80), Memory.C4RAM[waveptr+0xb00]);#endif for(int j=0; j<0x10; j++){ do { int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16; for(int i=0; i<40; i++){ uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2; if(height>=0){ if(height<8){ tmp|=mask1&READ_WORD(Memory.C4RAM+0xa00+height*2); } else { tmp|=mask1&0xff00; } } WRITE_WORD(dst+bmpdata[i], tmp); height++; } waveptr=(waveptr+1)&0x7f; mask1=(mask1>>2)|(mask1<<6); mask2=(mask2>>2)|(mask2<<6); } while(mask1!=0xc0c0); dst+=16; do { int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16; for(int i=0; i<40; i++){ uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2; if(height>=0){ if(height<8){ tmp|=mask1&READ_WORD(Memory.C4RAM+0xa10+height*2); } else { tmp|=mask1&0xff00; } } WRITE_WORD(dst+bmpdata[i], tmp); height++; } waveptr=(waveptr+1)&0x7f; mask1=(mask1>>2)|(mask1<<6); mask2=(mask2>>2)|(mask2<<6); } while(mask1!=0xc0c0); dst+=16; }}static void C4SprDisintegrate(){ uint8 width, height; uint32 StartX, StartY; uint8 *src; int32 scaleX, scaleY; int32 Cx, Cy; width=Memory.C4RAM[0x1f89]; height=Memory.C4RAM[0x1f8c]; Cx=(int16)READ_WORD(Memory.C4RAM+0x1f80); Cy=(int16)READ_WORD(Memory.C4RAM+0x1f83);#ifdef DEBUGGER if((Cx&~1)!=width/2 || (Cy&~1)!=height/2) printf("Center is not middle of image for disintegrate! (%d, %d) != (%d, %d)\n", Cx, Cy, width/2, height/2);#endif scaleX=(int16)READ_WORD(Memory.C4RAM+0x1f86); scaleY=(int16)READ_WORD(Memory.C4RAM+0x1f8f); StartX=-Cx*scaleX+(Cx<<8); StartY=-Cy*scaleY+(Cy<<8); src=Memory.C4RAM+0x600; memset(Memory.C4RAM, 0, width*height/2); for(uint32 y=StartY, i=0; i<height; i++, y+=scaleY) { for(uint32 x=StartX, j=0; j<width; j++, x+=scaleX) { if((x>>8)<width && (y>>8)<height && (y>>8)*width+(x>>8)<0x2000) { uint8 pixel=(j&1)?(*src>>4):*src; int idx=(y>>11)*width*4+(x>>11)*32+((y>>8)&7)*2; uint8 mask=0x80>>((x>>8)&7); if(pixel&1) Memory.C4RAM[idx]|=mask; if(pixel&2) Memory.C4RAM[idx+1]|=mask; if(pixel&4) Memory.C4RAM[idx+16]|=mask; if(pixel&8) Memory.C4RAM[idx+17]|=mask; } if(j&1) src++; } }}static void S9xC4ProcessSprites(){ switch(Memory.C4RAM[0x1f4d]) { case 0x00: // Build OAM#ifdef DEBUGGER// printf("00 00 Build OAM!\n");#endif C4ConvOAM(); break; case 0x03: // Scale/Rotate#ifdef DEBUGGER// printf("00 03 Scale/Rotate!\n");#endif C4DoScaleRotate(0); break; case 0x05: // Transform Lines#ifdef DEBUGGER// printf("00 05 Transform Lines!\n");#endif C4TransformLines(); break; case 0x07: // Scale/Rotate#ifdef DEBUGGER// printf("00 07 Scale/Rotate!\n");#endif C4DoScaleRotate(64); break; case 0x08: // Draw wireframe#ifdef DEBUGGER// printf("00 08 Draw wireframe!\n");#endif C4DrawWireFrame(); break; case 0x0b: // Disintegrate#ifdef DEBUGGER printf("00 0b Disintegrate!\n");#endif C4SprDisintegrate(); break; case 0x0c: // Wave#ifdef DEBUGGER// printf("00 0b Wave!\n");#endif C4BitPlaneWave(); break; default:#ifdef DEBUGGER printf ("Unknown C4 sprite command (%02x)\n", Memory.C4RAM [0x1f4d]);#endif break; }}void S9xSetC4 (uint8 byte, uint16 Address){ int i;#ifdef DEBUGGER if(Settings.BGLayering) printf("%02x to %04x\n", byte, Address);#endif Memory.C4RAM [Address-0x6000] = byte; if (Address == 0x7f4f) { if(Memory.C4RAM[0x1f4d]==0x0e && byte<0x40 && (byte&3)==0) {#ifdef DEBUGGER printf("Test command %02x 0e used!\n", byte);#endif Memory.C4RAM[0x1f80]=byte>>2; } else { switch (byte) { case 0x00: // Sprite S9xC4ProcessSprites(); break; case 0x01: // Draw wireframe#ifdef DEBUGGER //printf("01 Draw wireframe used!\n"); if(Memory.C4RAM[0x1f4d]!=8) printf("$7f4d=%02x, expected 08 for command 01 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);#endif memset(Memory.C4RAM+0x300, 0, 16*12*3*4); C4DrawWireFrame(); break; case 0x05: // Propulsion (?)#ifdef DEBUGGER printf("05 Propulsion (?)!\n"); if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 05 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);#endif { int32 tmp=0x10000; if(READ_WORD(Memory.C4RAM+0x1f83)){ tmp=SAR((tmp/READ_WORD(Memory.C4RAM+0x1f83))*READ_WORD(Memory.C4RAM+0x1f81), 8); } WRITE_WORD(Memory.C4RAM+0x1f80, (uint16)tmp); } break; case 0x0d: // Set vector length#ifdef DEBUGGER printf("0d Set vector length!\n"); if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 0d %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);#endif C41FXVal=READ_WORD(Memory.C4RAM+0x1f80); C41FYVal=READ_WORD(Memory.C4RAM+0x1f83); C41FDistVal=READ_WORD(Memory.C4RAM+0x1f86); C4Op0D(); WRITE_WORD(Memory.C4RAM+0x1f89, C41FXVal); WRITE_WORD(Memory.C4RAM+0x1f8c, C41FYVal);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -