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:
parent
7dcfa9c70a
commit
9213fd5bd6
11 changed files with 1858 additions and 651 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue