line.cpp
来自「DGen源码最后版本」· C++ 代码 · 共 220 行
CPP
220 行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "md.h"
static inline int a_pixel(void *at,int bpp,int highcol,int white)
{
if (bpp<=8) ((unsigned char *)at)[0]=white?0xff:highcol;
else if (bpp<=16) ((unsigned short *)at)[0]=white?0xffff:highcol;
else if (bpp<=24)
{
((unsigned char *)at)[0]=white?0xff:(highcol&255);
((unsigned char *)at)[1]=white?0xff:((highcol>>8)&255);
((unsigned char *)at)[2]=white?0xff:(highcol>>16);
}
else if (bpp<=32) ((unsigned long *)at)[0]=white?0xffffffff:highcol;
return 0;
}
int md_vdp::tile_line(unsigned char *at,int bpp,int line,int tile)
{
// Draw a line (0-7) of the specified tile
int tile_off,pal_off;
unsigned char *tilep; unsigned int *palp;
int x,white=0;
tile_off=(tile&0x7ff)<<5;
tilep=vram+tile_off;
{
int byt,bit; // Retrieve dirty information down to 32byte level in bits
byt=tile_off>>8; bit=byt&7; byt>>=3; byt&=0xff;
if (dirt[0x00+byt]&(1<<bit)) white=1; else white=0;
dirt[0x00+byt]&=~(1<<bit); // reset dirty flag
}
pal_off=(tile&0x6000)>>9;
palp=highpal+pal_off;
if (tile&0x1000) line=7-line;
tilep+=(line&7)<<2;
for (x=0;x<8;x++)
{
int a,tx;
if (tile&0x0800) tx=7-x; else tx=x;
a=tilep[tx>>1]; if ((tx&1)==0) a>>=4; a&=15;
if (a) a_pixel(at,bpp,palp[a],white);
at+=(bpp+7)>>3;
}
return 0;
}
int md_vdp::draw_sprites(unsigned char *bml,int bpp,int line)
{
static unsigned sprite_order[0x100]={0};
static int sprite_count=0;
int may_have_changed=0,spr,i;
int inc;
inc=(bpp+7)>>3; // inc = add 1 pixel
if (dirt[0x30]&(1<<5)) may_have_changed=1; // reg[5] changed
spr=reg[0x05]<<9;
if (dirt[0x34]&1) may_have_changed=1; // VRAM changed
// (For more efficiency you may also want to check
// if the VRAM affecting the sprites is intact)
if (may_have_changed)
{
// Calculate the sprite order (needs to be rendered backwards)
sprite_count=0;
sprite_order[0]=0;
for (i=1;i<=0x100;i++)
{
unsigned char next;
next=vram[(spr+sprite_order[i-1]*8+3)&0xffff];
if ((next==0)||(i>=0x100)) { sprite_count=i; break; }
sprite_order[i]=next;
}
}
for (i=sprite_count-1;i>=0;i--)
{
int sprno,x,y,xs,ys,tile,tx,ty;
int fx,fy;
sprno=sprite_order[i];
y=(vram[(spr+sprno*8+0)&0xffff]<<8)+vram[(spr+sprno*8+1)&0xffff];
x=(vram[(spr+sprno*8+6)&0xffff]<<8)+vram[(spr+sprno*8+7)&0xffff];
x&=0x1ff;
if ((reg[12]&6)==6)
{
// interlace mode
y&=0x3ff;
y>>=1; // interlace mode
}
else y&=0x1ff;
y-=0x80;
x-=0x80;
if ((reg[0xc]&1)==0) x+=4*8;
ys=vram[(spr+sprno*8+2)&0xffff];
xs=ys>>2; xs&=3; ys&=3; xs++; ys++;
tile=vram[(spr+sprno*8+4)&0xffff]; tile<<=8;
tile+=vram[(spr+sprno*8+5)&0xffff];
fy=(tile&0x1000)?1:0;
fx=(tile&0x0800)?1:0;
for (tx=0;tx<xs;tx++)
{
for (ty=0;ty<ys;ty++)
{
int dx=x+(fx?xs-tx-1:tx)*8, dy=y+(fy?ys-ty-1:ty)*8;
if (line>=dy && line<dy+8)
{
if (dx+8>=0 && dx+16<336)
tile_line(bml+(dx+8)*inc,bpp,line-dy,tile);
}
// if ( ((tile&0x8000)==0x8000) == high )
// draw_tile(bm,si,dx,dy,tile,ymin,ymax);
tile++;
}
}
}
return 0;
}
// (Okay - we have lots of dirt info, but we may not use most of it!)
int md_vdp::draw_md_line(struct bmap *bm,int line,int mark)
{
unsigned char *bml;
int c,x;
{
// If we changed color depth
static int last_bpp=-1;
if (last_bpp!=bm->bpp) memset(dirt,0xff,0x35);
last_bpp=bm->bpp;
}
// We use the global color dirt info
if (dirt[0x34]&2)
{
unsigned char *pc; pc=cram;
for (c=0;c<64;c++)
{
int r,g,b;
b=(*pc&0x0e)<<4; pc++;
g=(*pc&0xe0);
r=(*pc&0x0e)<<4; pc++;
// Recode into required depth
if (bm->bpp<=8) highpal[c]=c;
else if (bm->bpp<=15) highpal[c]=((r>>3)<<10) + ((g>>3)<<5) + (b>>3);
else if (bm->bpp<=16) highpal[c]=((r>>3)<<11) + ((g>>2)<<5) + (b>>3);
else if (bm->bpp<=32) highpal[c]=(r<<16) + (g<<8) + b;
}
}
bml=bm->data+(line+8)*bm->pitch;
{
int col; unsigned char *pp;
int inc,x;
inc=(bm->bpp+7)>>3; // inc = add 1 pixels
pp=bml+(inc<<3);
col=highpal[reg[7]&63];
for (x=0;x<320;x++,pp+=inc)
{
if (mark) col=(x&1)?0:0xffffffff;
a_pixel(pp,bm->bpp,col,0);
}
}
draw_sprites(bml,bm->bpp,line);
/*
// Fade colors
if (bm->bpp>=24)
{
for (c=0;c<64;c++)
{
int r,g,b;
r=highpal[c]>>16; r&=0xff;
g=highpal[c]>> 8; g&=0xff;
b=highpal[c] ; b&=0xff;
if (r>0) r--;
if (g>0) g--;
if (b>0) b--;
highpal[c]=(r<<16) + (g<<8) + b;
}
}
*/
/*
// Draw some tiles
{
int x,inc;
static int add=0; add++;
unsigned char *bmt;
inc=(bm->bpp+7)&~7; // inc = add 8 pixels
bmt=(unsigned char *)bml+inc;
for (x=0;x<40;x++)
{
int tile;
tile=(((line+(add>>9))>>3)*40)+x;
tile_line(bmt,bm->bpp,(line+(add>>9))&7,tile);
bmt+=inc;
}
}
*/
memset(dirt,0x00,0x35); // Mark everything as unchanged again
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?