1
0
Fork 0

New rendering changes

New mapper changes


Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1817
This commit is contained in:
Sjoerd van der Berg 2004-06-10 07:18:53 +00:00
parent 7dcfa9c70a
commit 9213fd5bd6
11 changed files with 1858 additions and 651 deletions

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: render.cpp,v 1.26 2004-02-07 18:50:10 harekiet Exp $ */
/* $Id: render.cpp,v 1.27 2004-06-10 07:18:19 harekiet Exp $ */
#include <sys/types.h>
#include <dirent.h>
@ -27,12 +27,11 @@
#include "video.h"
#include "render.h"
#include "setup.h"
#include "keyboard.h"
#include "mapper.h"
#include "cross.h"
#include "support.h"
#define RENDER_MAXWIDTH 1280
#define RENDER_MAXHEIGHT 1024
#include "render_scalers.h"
struct PalData {
struct {
@ -43,51 +42,36 @@ struct PalData {
} rgb[256];
volatile Bitu first;
volatile Bitu last;
union {
Bit32u bpp32[256];
Bit16u bpp16[256];
Bit32u yuv[256];
} lookup;
};
static struct {
struct {
Bitu width;
Bitu height;
Bitu bpp;
Bitu scalew;
Bitu scaleh;
bool dblw,dblh;
double ratio;
} src;
struct {
Bitu width;
Bitu height;
Bitu pitch;
Bitu line;
Bitu bpp;
GFX_Modes mode;
RENDER_Operation type;
RENDER_Operation want_type;
RENDER_Line_Handler line_handler;
Bit8u * draw;
Bit8u * buffer;
Bit8u * pixels;
} op;
struct {
Bitu count;
Bitu max;
} frameskip;
PalData pal;
struct {
Bit8u hlines[RENDER_MAXHEIGHT];
} normal;
#if (C_SSHOT)
struct {
RENDER_Operation type;
Bitu bpp,width,height,line;
Bitu bpp,width,height,rowlen;
const char * dir;
Bit8u * buffer,* draw;
bool usesrc;
bool take,taking;
} shot;
#endif
bool active;
@ -95,27 +79,15 @@ static struct {
bool updating;
} render;
Bit8u render_line_cache[4][RENDER_MAXWIDTH*4]; //Bit32u pixels
RENDER_Line_Handler RENDER_DrawLine;
Bit8u * RENDER_TempLine;
/* Forward declerations */
static void RENDER_ResetPal(void);
/* Include the different rendering routines */
#include "render_templates.h"
#include "render_normal.h"
#include "render_scale2x.h"
#if (C_SSHOT)
#include <png.h>
static void RENDER_ShotDraw(Bit8u * src) {
if (render.shot.usesrc) {
memcpy(render.shot.draw,src,render.shot.line);
render.shot.draw+=render.shot.line;
} else render.op.line_handler(src);
static void RENDER_ShotDraw(const Bit8u * src) {
memcpy(render.shot.draw,src,render.shot.rowlen);
render.shot.draw+=render.shot.rowlen;
render.op.line_handler(src);
}
/* Take a screenshot of the data that should be rendered */
@ -153,7 +125,6 @@ static void TakeScreenShot(Bit8u * bitmap) {
LOG_MSG("Can't open file %s for snapshot",file_name);
return;
}
/* First try to alloacte the png structures */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL);
if (!png_ptr) return;
@ -192,7 +163,7 @@ static void TakeScreenShot(Bit8u * bitmap) {
/*Allocate an array of scanline pointers*/
row_pointers=(png_bytep*)malloc(render.shot.height*sizeof(png_bytep));
for (i=0;i<render.shot.height;i++) {
row_pointers[i]=(bitmap+i*render.shot.line);
row_pointers[i]=(bitmap+i*render.shot.rowlen);
}
/*tell the png library what to encode.*/
png_set_rows(png_ptr, info_ptr, row_pointers);
@ -212,8 +183,7 @@ static void TakeScreenShot(Bit8u * bitmap) {
}
static void EnableScreenShot(void) {
render.shot.type=render.op.type;
render.op.type=OP_Shot;
render.shot.take=true;
}
#endif
@ -222,25 +192,25 @@ static void EnableScreenShot(void) {
static void Check_Palette(void) {
if (render.pal.first>render.pal.last) return;
Bitu i;
switch (render.op.bpp) {
case 8:
switch (render.op.mode) {
case GFX_8:
GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]);
break;
case 16:
case GFX_15:
case GFX_16:
for (i=render.pal.first;i<=render.pal.last;i++) {
Bit8u r=render.pal.rgb[i].red;
Bit8u g=render.pal.rgb[i].green;
Bit8u b=render.pal.rgb[i].blue;
render.pal.lookup.bpp16[i]=GFX_GetRGB(r,g,b);
Scaler_PaletteLut.b16[i]=GFX_GetRGB(r,g,b);
}
break;
case 24:
case 32:
case GFX_32:
for (i=render.pal.first;i<=render.pal.last;i++) {
Bit8u r=render.pal.rgb[i].red;
Bit8u g=render.pal.rgb[i].green;
Bit8u b=render.pal.rgb[i].blue;
render.pal.lookup.bpp32[i]=GFX_GetRGB(r,g,b);
Scaler_PaletteLut.b32[i]=GFX_GetRGB(r,g,b);
}
break;
}
@ -262,7 +232,7 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) {
if (render.pal.last<entry) render.pal.last=entry;
}
static void RENDER_EmptyLineHandler(Bit8u * src) {
static void RENDER_EmptyLineHandler(const Bit8u * src) {
}
@ -274,43 +244,31 @@ bool RENDER_StartUpdate(void) {
}
render.frameskip.count=0;
if (render.src.bpp==8) Check_Palette();
render.op.line=0;
RENDER_TempLine=render_line_cache[0];
switch (render.op.type) {
case OP_None:
case OP_Normal2x:
case OP_AdvMame2x:
am2x.cmd_index=am2x.cmd_data;
if (!GFX_StartUpdate(render.op.pixels,render.op.pitch)) return false;
RENDER_DrawLine=render.op.line_handler;;
break;
Scaler_Line=0;
Scaler_Index=Scaler_Data;
if (!GFX_StartUpdate(Scaler_DstWrite,Scaler_DstPitch)) return false;
RENDER_DrawLine=render.op.line_handler;
#if (C_SSHOT)
case OP_Shot:
if (render.shot.buffer) free(render.shot.buffer);
if (render.shot.usesrc) {
render.shot.width=render.src.width;
render.shot.height=render.src.height;
render.shot.bpp=render.src.bpp;
} else {
render.shot.width=render.op.width;
render.shot.height=render.op.height;
render.shot.bpp=render.op.bpp;
if (render.shot.take) {
render.shot.take=false;
if (render.shot.buffer) {
free(render.shot.buffer);
}
render.shot.width=render.src.width;
render.shot.height=render.src.height;
render.shot.bpp=render.src.bpp;
switch (render.shot.bpp) {
case 8:render.shot.line=render.shot.width;break;
case 8:render.shot.rowlen=render.shot.width;break;
case 15:
case 16:render.shot.line=render.shot.width*2;break;
case 24:render.shot.line=render.shot.width*3;break;
case 32:render.shot.line=render.shot.width*4;break;
case 16:render.shot.rowlen=render.shot.width*2;break;
case 32:render.shot.rowlen=render.shot.width*4;break;
}
render.shot.buffer=(Bit8u*)malloc(render.shot.line*render.shot.height);
render.op.pixels=render.shot.buffer;
render.op.pitch=render.shot.line;
render.shot.buffer=(Bit8u*)malloc(render.shot.rowlen*render.shot.height);
render.shot.draw=render.shot.buffer;
RENDER_DrawLine=RENDER_ShotDraw;
break;
#endif
render.shot.taking=true;
}
#endif
render.updating=true;
return true;
}
@ -318,31 +276,40 @@ bool RENDER_StartUpdate(void) {
void RENDER_EndUpdate(void) {
if (!render.updating) return;
#if (C_SSHOT)
switch (render.op.type) {
case OP_None:
case OP_Normal2x:
case OP_AdvMame2x:
break;
case OP_Shot:
if (render.shot.taking) {
render.shot.taking=false;
TakeScreenShot(render.shot.buffer);
free(render.shot.buffer);
render.shot.buffer=0;
render.op.type=render.shot.type;
break;
}
#endif /* If Things are added to please check the define */
GFX_EndUpdate();
RENDER_DrawLine=RENDER_EmptyLineHandler;
render.updating=false;
render.updating=false;
}
static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) {
double lines=0;
Bitu linesadded=0;
for (Bitu i=0;i<height;i++) {
lines+=scaley;
if (lines>=miny) {
Bitu templines=(Bitu)lines;
lines-=templines;
linesadded+=templines;
Scaler_Data[i]=templines-miny;
} else Scaler_Data[i]=0;
}
return linesadded;
}
void RENDER_ReInit(void) {
if (render.updating) RENDER_EndUpdate();
Bitu width=render.src.width;
Bitu height=render.src.height;
Bitu scalew=render.src.scalew;
Bitu scaleh=render.src.scaleh;
bool dblw=render.src.dblw;
bool dblh=render.src.dblh;
double gfx_scalew=1.0;
double gfx_scaleh=1.0;
@ -351,105 +318,59 @@ void RENDER_ReInit(void) {
else gfx_scalew*=(1/render.src.ratio);
Bitu gfx_flags;
Bitu bpp=GFX_GetBestMode(render.src.bpp,gfx_flags);
Bitu index;
switch (bpp) {
case 8: index=0;break;
case 16:index=1;break;
case 24:index=2;break;
case 32:index=3;break;
}
/* Initial scaler testing */
switch (render.op.want_type) {
case OP_Normal2x:
case OP_None:
ScalerBlock * block;
if (dblh && dblw) {
render.op.type=render.op.want_type;
normalop:
if (gfx_flags & GFX_HASSCALING) {
gfx_scalew*=scalew;
gfx_scaleh*=scaleh;
render.op.line_handler=Normal_8[index];
for (Bitu i=0;i<render.src.height;i++) {
render.normal.hlines[i]=0;
}
} else {
gfx_scaleh*=scaleh;
if (scalew==2) {
if (scaleh>1 && (render.op.type==OP_None)) {
render.op.line_handler=Normal_8[index];
scalew>>=1;gfx_scaleh/=2;
} else {
render.op.line_handler=Normal_2x_8[index];
}
} else render.op.line_handler=Normal_8[index];
width*=scalew;
double lines=0.0;
height=0;
for (Bitu i=0;i<render.src.height;i++) {
lines+=gfx_scaleh;
Bitu temp_lines=(Bitu)(lines);
lines-=temp_lines;
render.normal.hlines[i]=(temp_lines>0) ? temp_lines-1 : 0;
height+=temp_lines;
}
}
break;
case OP_AdvMame2x:
if (scalew!=2){
render.op.type=OP_Normal2x;
goto normalop;
}
if (gfx_flags & GFX_HASSCALING) {
height=scaleh*height;
} else {
height=(Bitu)(gfx_scaleh*scaleh*height);
}
width<<=1;
{
Bits i;
double src_add=(double)height/(double)render.src.height;
double src_index=0;
double src_lines=0;
Bitu src_done=0;
Bitu height=0;
am2x.cmd_index=am2x.cmd_data;
am2x.buf_pos=0;am2x.buf_used=0;
for (i=0;i<=(Bits)render.src.height;i++) {
src_lines+=src_add;
Bitu lines=(Bitu)src_lines;
src_lines-=lines;
switch (lines) {
case 0:
break;
case 1:
AdvMame2x_AddLine(i,i,i);
break;
case 2:
AdvMame2x_AddLine(i-1,i,i+1);
AdvMame2x_AddLine(i+1,i,i-1);
break;
default:
AdvMame2x_AddLine(i-1,i,i+1);
for (lines-=2;lines>0;lines--) AdvMame2x_AddLine(i,i,i);
AdvMame2x_AddLine(i+1,i,i-1);
break;
}
AdvMame2x_CheckLines(i);
}
render.op.line_handler=AdvMame2x_8_Table[index];
}
break;
} else if (dblw) {
render.op.type=OP_Normal2x;
} else if (dblh) {
render.op.type=OP_Normal;
gfx_scaleh*=2;
} else {
forcenormal:
render.op.type=OP_Normal;
}
render.op.bpp=bpp;
switch (render.op.type) {
case OP_Normal:block=&Normal_8;break;
case OP_Normal2x:block=(dblh) ? &Normal2x_8 : &NormalDbl_8;break;
case OP_AdvMame2x:block=&AdvMame2x_8;break;
case OP_AdvMame3x:block=&AdvMame3x_8;break;
case OP_Interp2x:block=&Interp2x_8;break;
case OP_AdvInterp2x:block=&AdvInterp2x_8;break;
case OP_TV2x:block=&TV2x_8;break;
}
gfx_flags=GFX_GetBestMode(block->flags);
if (!gfx_flags) {
if (render.op.type==OP_Normal) E_Exit("Failed to create a rendering output");
else goto forcenormal;
}
/* Special test for normal2x to switch to normal with hardware scaling */
if (gfx_flags & HAVE_SCALING && render.op.type==OP_Normal2x) {
if (dblw) gfx_scalew*=2;
if (dblh) gfx_scaleh*=2;
block=&Normal_8;
render.op.type=OP_Normal;
}
width*=block->xscale;
if (gfx_flags & HAVE_SCALING) {
height=MakeAspectTable(render.src.height,block->yscale,block->miny);
} else {
gfx_scaleh*=block->yscale;
height=MakeAspectTable(render.src.height,gfx_scaleh,block->miny);
}
/* Setup the scaler variables */
render.op.mode=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_ReInit);;
if (render.op.mode==GFX_NONE) E_Exit("Failed to create a rendering output");
render.op.line_handler=block->handlers[render.op.mode];
render.op.width=width;
render.op.height=height;
GFX_SetSize(width,height,bpp,gfx_scalew,gfx_scaleh,&RENDER_ReInit);
Scaler_SrcWidth=render.src.width;
Scaler_SrcHeight=render.src.height;
RENDER_ResetPal();
render.active=true;
}
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bitu scaleh) {
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh) {
if (!width || !height) {
render.active=false;
return;
@ -457,9 +378,9 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,Bitu scalew,Bit
render.src.width=width;
render.src.height=height;
render.src.bpp=bpp;
render.src.dblw=dblw;
render.src.dblh=dblh;
render.src.ratio=render.aspect ? ratio : 1.0;
render.src.scalew=scalew;
render.src.scaleh=scaleh;
RENDER_ReInit();
}
@ -487,8 +408,7 @@ void RENDER_Init(Section * sec) {
render.updating=true;
#if (C_SSHOT)
render.shot.dir=section->Get_string("snapdir");
render.shot.usesrc=true;
KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot);
MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot");
#endif
const char * scaler;std::string cline;
if (control->cmdline->FindString("-scaler",cline,false)) {
@ -496,15 +416,19 @@ void RENDER_Init(Section * sec) {
} else {
scaler=section->Get_string("scaler");
}
if (!strcasecmp(scaler,"none")) render.op.want_type=OP_None;
if (!strcasecmp(scaler,"none")) render.op.want_type=OP_Normal;
else if (!strcasecmp(scaler,"normal2x")) render.op.want_type=OP_Normal2x;
else if (!strcasecmp(scaler,"advmame2x")) render.op.want_type=OP_AdvMame2x;
else if (!strcasecmp(scaler,"advmame3x")) render.op.want_type=OP_AdvMame3x;
else if (!strcasecmp(scaler,"advinterp2x")) render.op.want_type=OP_AdvInterp2x;
else if (!strcasecmp(scaler,"interp2x")) render.op.want_type=OP_Interp2x;
else if (!strcasecmp(scaler,"tv2x")) render.op.want_type=OP_TV2x;
else {
render.op.want_type=OP_None;
LOG_MSG("Illegal scaler type %s,falling back to none.",scaler);
render.op.want_type=OP_Normal;
LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler);
}
KEYBOARD_AddEvent(KBD_f7,KBD_MOD_CTRL,DecreaseFrameSkip);
KEYBOARD_AddEvent(KBD_f8,KBD_MOD_CTRL,IncreaseFrameSkip);
MAPPER_AddHandler(DecreaseFrameSkip,MK_f7,MMOD1,"decfskip","Dec Fskip");
MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip");
GFX_SetTitle(-1,render.frameskip.max);
}