Rendering rewrite for aspect correction and vga vertical stretching
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1411
This commit is contained in:
parent
7b36937c81
commit
a1e279829b
6 changed files with 302 additions and 785 deletions
|
@ -16,10 +16,12 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: render.cpp,v 1.19 2003-10-15 08:20:50 harekiet Exp $ */
|
||||
/* $Id: render.cpp,v 1.20 2003-11-08 09:53:11 harekiet Exp $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "video.h"
|
||||
|
@ -29,7 +31,8 @@
|
|||
#include "cross.h"
|
||||
#include "support.h"
|
||||
|
||||
#define MAX_RES 2048
|
||||
#define RENDER_MAXWIDTH 1280
|
||||
#define RENDER_MAXHEIGHT 1024
|
||||
|
||||
struct PalData {
|
||||
struct {
|
||||
|
@ -43,6 +46,7 @@ struct PalData {
|
|||
union {
|
||||
Bit32u bpp32[256];
|
||||
Bit16u bpp16[256];
|
||||
Bit32u yuv[256];
|
||||
} lookup;
|
||||
};
|
||||
|
||||
|
@ -53,28 +57,36 @@ static struct {
|
|||
Bitu height;
|
||||
Bitu bpp;
|
||||
Bitu pitch;
|
||||
Bitu flags;
|
||||
float ratio;
|
||||
Bitu scalew;
|
||||
Bitu scaleh;
|
||||
double ratio;
|
||||
RENDER_Draw_Handler draw_handler;
|
||||
} src;
|
||||
struct {
|
||||
Bitu width;
|
||||
Bitu height;
|
||||
Bitu pitch;
|
||||
Bitu bpp; /* The type of BPP the operation requires for input */
|
||||
GFX_MODES gfx_mode;
|
||||
RENDER_Operation type;
|
||||
RENDER_Operation want_type;
|
||||
RENDER_Part_Handler part_handler;
|
||||
void * dest;
|
||||
void * buffer;
|
||||
void * pixels;
|
||||
Bit8u * dest;
|
||||
Bit8u * buffer;
|
||||
Bit8u * pixels;
|
||||
} op;
|
||||
struct {
|
||||
Bitu count;
|
||||
Bitu max;
|
||||
} frameskip;
|
||||
Bitu flags;
|
||||
PalData pal;
|
||||
struct {
|
||||
Bit8u hlines[RENDER_MAXHEIGHT];
|
||||
Bit16u hindex[RENDER_MAXHEIGHT];
|
||||
} normal;
|
||||
struct {
|
||||
Bit16u hindex[RENDER_MAXHEIGHT];
|
||||
Bitu line_starts[RENDER_MAXHEIGHT][3];
|
||||
} advmame2x;
|
||||
#if (C_SSHOT)
|
||||
struct {
|
||||
RENDER_Operation type;
|
||||
|
@ -84,12 +96,14 @@ static struct {
|
|||
#endif
|
||||
bool screenshot;
|
||||
bool active;
|
||||
bool aspect;
|
||||
} render;
|
||||
|
||||
/* Forward declerations */
|
||||
static void RENDER_ResetPal(void);
|
||||
|
||||
/* Include the different rendering routines */
|
||||
#include "render_templates.h"
|
||||
#include "render_normal.h"
|
||||
#include "render_scale2x.h"
|
||||
|
||||
|
@ -201,28 +215,41 @@ static void EnableScreenShot(void) {
|
|||
/* This could go kinda bad with multiple threads */
|
||||
static void Check_Palette(void) {
|
||||
if (render.pal.first>render.pal.last) return;
|
||||
switch (render.op.bpp) {
|
||||
case 8:
|
||||
Bitu i;
|
||||
switch (render.op.gfx_mode) {
|
||||
case GFX_8BPP:
|
||||
GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]);
|
||||
break;
|
||||
case 16:
|
||||
for (;render.pal.first<=render.pal.last;render.pal.first++) {
|
||||
render.pal.lookup.bpp16[render.pal.first]=GFX_GetRGB(
|
||||
render.pal.rgb[render.pal.first].red,
|
||||
render.pal.rgb[render.pal.first].green,
|
||||
render.pal.rgb[render.pal.first].blue);
|
||||
case GFX_15BPP:
|
||||
case GFX_16BPP:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (;render.pal.first<=render.pal.last;render.pal.first++) {
|
||||
render.pal.lookup.bpp32[render.pal.first]=
|
||||
GFX_GetRGB(
|
||||
render.pal.rgb[render.pal.first].red,
|
||||
render.pal.rgb[render.pal.first].green,
|
||||
render.pal.rgb[render.pal.first].blue);
|
||||
case GFX_24BPP:
|
||||
case GFX_32BPP:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
};
|
||||
case GFX_YUV:
|
||||
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;
|
||||
Bit8u y = ( 9797*(r) + 19237*(g) + 3734*(b) ) >> 15;
|
||||
Bit8u u = (18492*((b)-(y)) >> 15) + 128;
|
||||
Bit8u v = (23372*((r)-(y)) >> 15) + 128;
|
||||
render.pal.lookup.yuv[i]=(u << 0) | (y << 8) | (v << 16) | (y << 24);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Setup pal index to startup values */
|
||||
render.pal.first=256;
|
||||
render.pal.last=0;
|
||||
|
@ -251,19 +278,14 @@ void RENDER_DoUpdate(void) {
|
|||
GFX_DoUpdate();
|
||||
}
|
||||
|
||||
static void RENDER_DrawScreen(void * data) {
|
||||
static void RENDER_DrawScreen(Bit8u * data,Bitu pitch) {
|
||||
render.op.pitch=pitch;
|
||||
switch (render.op.type) {
|
||||
#if (C_SSHOT)
|
||||
doagain:
|
||||
#endif
|
||||
case OP_None:
|
||||
render.op.dest=render.op.pixels=data;
|
||||
render.src.draw_handler(render.op.part_handler);
|
||||
break;
|
||||
case OP_Blit:
|
||||
render.op.dest=render.op.pixels=data;
|
||||
render.src.draw_handler(render.op.part_handler);
|
||||
break;
|
||||
case OP_Normal2x:
|
||||
case OP_AdvMame2x:
|
||||
render.op.dest=render.op.pixels=data;
|
||||
render.src.draw_handler(render.op.part_handler);
|
||||
|
@ -272,8 +294,8 @@ doagain:
|
|||
case OP_Shot:
|
||||
render.shot.pitch=render.op.pitch;
|
||||
render.op.pitch=render.src.width;
|
||||
render.op.pixels=malloc(render.src.width*render.src.height);
|
||||
render.src.draw_handler(Normal_DN_8);
|
||||
render.op.pixels=(Bit8u*)malloc(render.src.width*render.src.height);
|
||||
// render.src.draw_handler(Normal_DN_8);
|
||||
TakeScreenShot((Bit8u *)render.op.pixels);
|
||||
free(render.op.pixels);
|
||||
render.op.pitch=render.shot.pitch;
|
||||
|
@ -283,30 +305,134 @@ doagain:
|
|||
}
|
||||
}
|
||||
|
||||
static void RENDER_Resize(Bitu * width,Bitu * height) {
|
||||
/* Calculate the new size the window should be */
|
||||
if (!*width && !*height) {
|
||||
/* Special command to reset any resizing for fullscreen */
|
||||
*width=render.src.width;
|
||||
*height=render.src.height;
|
||||
} else {
|
||||
if ((*width/render.src.ratio)<*height) *height=(Bitu)(*width/render.src.ratio);
|
||||
else *width=(Bitu)(*height*render.src.ratio);
|
||||
}
|
||||
static void SetAdvMameTable(Bitu index,Bits src0,Bits src1,Bits src2) {
|
||||
if (src0<0) src0=0;
|
||||
if ((Bitu)src0>=render.src.height) src0=render.src.height-1;
|
||||
if ((Bitu)src1>=render.src.height) src1=render.src.height-1;
|
||||
if ((Bitu)src2>=render.src.height) src2=render.src.height-1;
|
||||
render.advmame2x.line_starts[index][0]=src0*render.src.pitch;
|
||||
render.advmame2x.line_starts[index][1]=src1*render.src.pitch;
|
||||
render.advmame2x.line_starts[index][2]=src2*render.src.pitch;
|
||||
|
||||
}
|
||||
|
||||
static void Render_Blit_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) {
|
||||
|
||||
void RENDER_ReInit(void) {
|
||||
Bitu width=render.src.width;
|
||||
Bitu height=render.src.height;
|
||||
Bitu bpp=render.src.bpp;
|
||||
|
||||
Bitu scalew=render.src.scalew;
|
||||
Bitu scaleh=render.src.scaleh;
|
||||
|
||||
double gfx_scalew=1.0;
|
||||
double gfx_scaleh=1.0;
|
||||
|
||||
if (render.src.ratio>1.0) gfx_scaleh*=render.src.ratio;
|
||||
else gfx_scalew*=(1/render.src.ratio);
|
||||
|
||||
GFX_MODES gfx_mode;Bitu gfx_flags;
|
||||
gfx_mode=GFX_GetBestMode(render.src.bpp,gfx_flags);
|
||||
Bitu index;
|
||||
switch (gfx_mode) {
|
||||
case GFX_8BPP: index=0;break;
|
||||
case GFX_15BPP: index=1;break;
|
||||
case GFX_16BPP: index=1;break;
|
||||
case GFX_24BPP: index=2;break;
|
||||
case GFX_32BPP: index=3;break;
|
||||
case GFX_YUV: index=3;break;
|
||||
}
|
||||
/* Initial scaler testing */
|
||||
switch (render.op.want_type) {
|
||||
case OP_Normal2x:
|
||||
case OP_None:
|
||||
render.op.type=render.op.want_type;
|
||||
normalop:
|
||||
if (gfx_flags & GFX_HASSCALING) {
|
||||
gfx_scalew*=scalew;
|
||||
gfx_scaleh*=scaleh;
|
||||
render.op.part_handler=Normal_SINGLE_8[index];
|
||||
for (Bitu i=0;i<render.src.height;i++) {
|
||||
render.normal.hindex[i]=i;
|
||||
render.normal.hlines[i]=0;
|
||||
}
|
||||
} else {
|
||||
gfx_scaleh*=scaleh;
|
||||
if (scalew==2) {
|
||||
if (scaleh>1 && (render.op.type==OP_None)) {
|
||||
render.op.part_handler=Normal_SINGLE_8[index];
|
||||
scalew>>=1;gfx_scaleh/=2;
|
||||
} else {
|
||||
render.op.part_handler=Normal_DOUBLE_8[index];
|
||||
}
|
||||
} else render.op.part_handler=Normal_SINGLE_8[index];
|
||||
width*=scalew;
|
||||
double lines=0.0;
|
||||
gfx_scaleh=(gfx_scaleh*render.src.height-(double)render.src.height)/(double)render.src.height;
|
||||
height=0;
|
||||
for (Bitu i=0;i<render.src.height;i++) {
|
||||
render.normal.hindex[i]=height++;
|
||||
Bitu temp_lines=(Bitu)(lines);
|
||||
lines=lines+gfx_scaleh-temp_lines;
|
||||
render.normal.hlines[i]=temp_lines;
|
||||
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 height=0;
|
||||
for (i=0;i<=(Bits)render.src.height;i++) {
|
||||
render.advmame2x.hindex[i]=(Bitu)src_index;
|
||||
Bitu lines=(Bitu)src_lines;
|
||||
src_lines-=lines;
|
||||
src_index+=src_add;
|
||||
src_lines+=src_add;
|
||||
switch (lines) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
SetAdvMameTable(height++,i,i,i);
|
||||
break;
|
||||
case 2:
|
||||
SetAdvMameTable(height++,i-1,i,i+1);
|
||||
SetAdvMameTable(height++,i+1,i,i-1);
|
||||
break;
|
||||
default:
|
||||
SetAdvMameTable(height++,i-1,i,i+1);
|
||||
for (lines-=2;lines>0;lines--) SetAdvMameTable(height++,i,i,i);
|
||||
SetAdvMameTable(height++,i+1,i,i-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
render.op.part_handler=AdvMame2x_8_Table[index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
render.op.gfx_mode=gfx_mode;
|
||||
render.op.width=width;
|
||||
render.op.height=height;
|
||||
render.op.bpp=bpp;
|
||||
render.op.pitch=pitch;
|
||||
render.op.type=OP_Blit;
|
||||
render.op.part_handler=GFX_Render_Blit;
|
||||
GFX_SetSize(width,height,gfx_mode,gfx_scalew,gfx_scaleh,&RENDER_ReInit,RENDER_DrawScreen);
|
||||
RENDER_ResetPal();
|
||||
GFX_Start();
|
||||
}
|
||||
|
||||
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler) {
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh,RENDER_Draw_Handler draw_handler) {
|
||||
if ((!width) || (!height) || (!pitch)) {
|
||||
render.active=false;return;
|
||||
}
|
||||
|
@ -315,67 +441,12 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu
|
|||
render.src.height=height;
|
||||
render.src.bpp=bpp;
|
||||
render.src.pitch=pitch;
|
||||
render.src.ratio=ratio;
|
||||
render.src.flags=flags;
|
||||
render.src.ratio=render.aspect ? ratio : 1.0;
|
||||
render.src.scalew=scalew;
|
||||
render.src.scaleh=scaleh;
|
||||
render.src.draw_handler=draw_handler;
|
||||
RENDER_ReInit();
|
||||
|
||||
GFX_ModeCallBack mode_callback=0;
|
||||
switch (render.op.want_type) {
|
||||
|
||||
case OP_None:
|
||||
normalop:
|
||||
switch (render.src.flags) {
|
||||
case DoubleNone:
|
||||
flags=0;
|
||||
break;
|
||||
case DoubleWidth:
|
||||
width*=2;
|
||||
flags=GFX_SHADOW;
|
||||
break;
|
||||
case DoubleHeight:
|
||||
height*=2;
|
||||
flags=0;
|
||||
break;
|
||||
case DoubleBoth:
|
||||
render.src.flags=0;
|
||||
flags=0;
|
||||
break;
|
||||
}
|
||||
mode_callback=Render_Normal_CallBack;
|
||||
break;
|
||||
case OP_Normal2x:
|
||||
switch (render.src.flags) {
|
||||
case DoubleBoth:
|
||||
width*=2;height*=2;
|
||||
flags=GFX_SHADOW;
|
||||
mode_callback=Render_Normal_CallBack;
|
||||
break;
|
||||
default:
|
||||
goto normalop;
|
||||
}
|
||||
break;
|
||||
case OP_AdvMame2x:
|
||||
switch (render.src.flags) {
|
||||
case DoubleBoth:
|
||||
mode_callback=Render_Scale2x_CallBack;
|
||||
width*=2;height*=2;
|
||||
#if defined (SCALE2X_MMX)
|
||||
flags=GFX_SHADOW;
|
||||
#else
|
||||
flags=GFX_SHADOW;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
goto normalop;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
goto normalop;
|
||||
|
||||
}
|
||||
GFX_SetSize(width,height,bpp,flags,mode_callback,RENDER_DrawScreen);
|
||||
GFX_Start();
|
||||
}
|
||||
|
||||
extern void GFX_SetTitle(Bits cycles, Bits frameskip);
|
||||
|
@ -396,6 +467,7 @@ void RENDER_Init(Section * sec) {
|
|||
|
||||
render.pal.first=256;
|
||||
render.pal.last=0;
|
||||
render.aspect=section->Get_bool("aspect");
|
||||
render.frameskip.max=section->Get_int("frameskip");
|
||||
render.frameskip.count=0;
|
||||
#if (C_SSHOT)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue