Scaler rewrite for detecting changes
New scalers for tv3x, rgb2x, rgb3x, scan2x, scan3x Only updaterect the changed parts in sdl Add support for 15/16/32bpp modes Add support for highres 4bpp modes Rewrite of vga page handlers for most other modes AVI capturing using zmbv codec New option for hardware scaled windows to try and reach a specified resolution Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2444
This commit is contained in:
parent
0968989c7a
commit
3b74afe0c4
7 changed files with 1418 additions and 813 deletions
|
@ -107,86 +107,8 @@ static struct {
|
|||
} sysex;
|
||||
bool available;
|
||||
MidiHandler * handler;
|
||||
struct {
|
||||
FILE * handle;
|
||||
Bit8u buffer[RAWBUF+SYSEX_SIZE];
|
||||
bool capturing;
|
||||
Bitu used,done;
|
||||
Bit32u last;
|
||||
} raw;
|
||||
} midi;
|
||||
|
||||
static Bit8u midi_header[]={
|
||||
'M','T','h','d', /* Bit32u, Header Chunk */
|
||||
0x0,0x0,0x0,0x6, /* Bit32u, Chunk Length */
|
||||
0x0,0x0, /* Bit16u, Format, 0=single track */
|
||||
0x0,0x1, /* Bit16u, Track Count, 1 track */
|
||||
0x01,0xf4, /* Bit16u, Timing, 2 beats/second with 500 frames */
|
||||
'M','T','r','k', /* Bit32u, Track Chunk */
|
||||
0x0,0x0,0x0,0x0, /* Bit32u, Chunk Length */
|
||||
//Track data
|
||||
};
|
||||
|
||||
#define ADDBUF(_VAL_) midi.raw.buffer[midi.raw.used++]=(Bit8u)(_VAL_);
|
||||
static INLINE void RawAddNumber(Bit32u val) {
|
||||
if (val & 0xfe00000) ADDBUF(0x80|((val >> 21) & 0x7f));
|
||||
if (val & 0xfffc000) ADDBUF(0x80|((val >> 14) & 0x7f));
|
||||
if (val & 0xfffff80) ADDBUF(0x80|((val >> 7) & 0x7f));
|
||||
ADDBUF(val & 0x7f);
|
||||
}
|
||||
static INLINE void RawAddDelta(void) {
|
||||
if (!midi.raw.handle) {
|
||||
midi.raw.handle=OpenCaptureFile("Raw Midi",".mid");
|
||||
if (!midi.raw.handle) {
|
||||
midi.raw.capturing=false;
|
||||
return;
|
||||
}
|
||||
fwrite(midi_header,1,sizeof(midi_header),midi.raw.handle);
|
||||
midi.raw.last=PIC_Ticks;
|
||||
}
|
||||
Bit32u delta=PIC_Ticks-midi.raw.last;
|
||||
midi.raw.last=PIC_Ticks;
|
||||
RawAddNumber(delta);
|
||||
}
|
||||
|
||||
static INLINE void RawAddData(Bit8u * data,Bitu len) {
|
||||
for (Bitu i=0;i<len;i++) ADDBUF(data[i]);
|
||||
if (midi.raw.used>=RAWBUF) {
|
||||
fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle);
|
||||
midi.raw.done+=midi.raw.used;
|
||||
midi.raw.used=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void MIDI_SaveRawEvent(void) {
|
||||
/* Check for previously opened wave file */
|
||||
if (midi.raw.capturing) {
|
||||
LOG_MSG("Stopping raw midi saving.");
|
||||
midi.raw.capturing=false;
|
||||
if (!midi.raw.handle) return;
|
||||
ADDBUF(0x00);//Delta time
|
||||
ADDBUF(0xff);ADDBUF(0x2F);ADDBUF(0x00); //End of track event
|
||||
fwrite(midi.raw.buffer,1,midi.raw.used,midi.raw.handle);
|
||||
midi.raw.done+=midi.raw.used;
|
||||
fseek(midi.raw.handle,18, SEEK_SET);
|
||||
Bit8u size[4];
|
||||
size[0]=(Bit8u)(midi.raw.done >> 24);
|
||||
size[1]=(Bit8u)(midi.raw.done >> 16);
|
||||
size[2]=(Bit8u)(midi.raw.done >> 8);
|
||||
size[3]=(Bit8u)(midi.raw.done >> 0);
|
||||
fwrite(&size,1,4,midi.raw.handle);
|
||||
fclose(midi.raw.handle);
|
||||
midi.raw.handle=0;
|
||||
} else {
|
||||
LOG_MSG("Preparing for raw midi capture, will start with first data.");
|
||||
midi.raw.used=0;
|
||||
midi.raw.done=0;
|
||||
midi.raw.handle=0;
|
||||
midi.raw.capturing=true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MIDI_RawOutByte(Bit8u data) {
|
||||
/* Test for a active sysex tranfer */
|
||||
if (midi.status==0xf0) {
|
||||
|
@ -197,11 +119,8 @@ void MIDI_RawOutByte(Bit8u data) {
|
|||
midi.sysex.buf[midi.sysex.used++]=0xf7;
|
||||
midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used);
|
||||
LOG(LOG_ALL,LOG_NORMAL)("Sysex message size %d",midi.sysex.used);
|
||||
if (midi.raw.capturing) {
|
||||
RawAddDelta();
|
||||
ADDBUF(0xf0);
|
||||
RawAddNumber(midi.sysex.used-1);
|
||||
RawAddData(&midi.sysex.buf[1],midi.sysex.used-1);
|
||||
if (CaptureState & CAPTURE_MIDI) {
|
||||
CAPTURE_AddMidi( true, midi.sysex.used-1, &midi.sysex.buf[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,9 +136,8 @@ void MIDI_RawOutByte(Bit8u data) {
|
|||
if (midi.cmd_len) {
|
||||
midi.cmd_buf[midi.cmd_pos++]=data;
|
||||
if (midi.cmd_pos >= midi.cmd_len) {
|
||||
if (midi.raw.capturing) {
|
||||
RawAddDelta();
|
||||
RawAddData(midi.cmd_buf,midi.cmd_len);
|
||||
if (CaptureState & CAPTURE_MIDI) {
|
||||
CAPTURE_AddMidi(false, midi.cmd_len, midi.cmd_buf);
|
||||
}
|
||||
midi.handler->PlayMsg(midi.cmd_buf);
|
||||
midi.cmd_pos=1; //Use Running status
|
||||
|
@ -231,7 +149,6 @@ bool MIDI_Available(void) {
|
|||
return midi.available;
|
||||
}
|
||||
|
||||
|
||||
class MIDI:public Module_base{
|
||||
public:
|
||||
MIDI(Section* configuration):Module_base(configuration){
|
||||
|
@ -240,12 +157,10 @@ public:
|
|||
const char * conf=section->Get_string("config");
|
||||
/* If device = "default" go for first handler that works */
|
||||
MidiHandler * handler;
|
||||
MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI");
|
||||
// MAPPER_AddHandler(MIDI_SaveRawEvent,MK_f8,MMOD1|MMOD2,"caprawmidi","Cap MIDI");
|
||||
midi.status=0x00;
|
||||
midi.cmd_pos=0;
|
||||
midi.cmd_len=0;
|
||||
midi.raw.handle=0;
|
||||
midi.raw.capturing=false;
|
||||
if (!strcasecmp(dev,"default")) goto getdefault;
|
||||
handler=handler_list;
|
||||
while (handler) {
|
||||
|
@ -276,12 +191,13 @@ getdefault:
|
|||
/* This shouldn't be possible */
|
||||
}
|
||||
~MIDI(){
|
||||
if(midi.raw.handle) MIDI_SaveRawEvent();
|
||||
if(midi.available) midi.handler->Close();
|
||||
midi.available = false;
|
||||
midi.handler = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static MIDI* test;
|
||||
void MIDI_Destroy(Section* sec){
|
||||
delete test;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: render.cpp,v 1.35 2005-10-25 14:02:11 qbix79 Exp $ */
|
||||
/* $Id: render.cpp,v 1.36 2006-01-30 09:58:07 harekiet Exp $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
@ -34,166 +34,45 @@
|
|||
|
||||
#include "render_scalers.h"
|
||||
|
||||
struct PalData {
|
||||
struct {
|
||||
Bit8u red;
|
||||
Bit8u green;
|
||||
Bit8u blue;
|
||||
Bit8u unused;
|
||||
} rgb[256];
|
||||
volatile Bitu first;
|
||||
volatile Bitu last;
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct {
|
||||
Bitu width;
|
||||
Bitu height;
|
||||
Bitu bpp;
|
||||
bool dblw,dblh;
|
||||
double ratio;
|
||||
} src;
|
||||
struct {
|
||||
Bitu width;
|
||||
Bitu height;
|
||||
Bitu pitch;
|
||||
GFX_Modes mode;
|
||||
RENDER_Operation type;
|
||||
RENDER_Operation want_type;
|
||||
RENDER_Line_Handler line_handler;
|
||||
} op;
|
||||
struct {
|
||||
Bitu count;
|
||||
Bitu max;
|
||||
} frameskip;
|
||||
PalData pal;
|
||||
#if (C_SSHOT)
|
||||
struct {
|
||||
Bitu bpp,width,height,rowlen;
|
||||
Bit8u * buffer,* draw;
|
||||
bool take,taking;
|
||||
} shot;
|
||||
#endif
|
||||
bool active;
|
||||
bool aspect;
|
||||
bool updating;
|
||||
} render;
|
||||
|
||||
RENDER_Line_Handler RENDER_DrawLine;
|
||||
|
||||
#if (C_SSHOT)
|
||||
#include <png.h>
|
||||
|
||||
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 */
|
||||
static void TakeScreenShot(Bit8u * bitmap) {
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_bytep * row_pointers;
|
||||
png_color palette[256];
|
||||
Bitu i;
|
||||
Bitu fix_double_scale = 1;//variable to compensate for only doubleheight
|
||||
|
||||
/* Remove this if we save rendered screens. instead of pre-rendered */
|
||||
if(render.src.dblh && !render.src.dblw) fix_double_scale = 2;
|
||||
|
||||
|
||||
/* Open the actual file */
|
||||
FILE * fp=OpenCaptureFile("Screenshot",".png");
|
||||
if (!fp) 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;
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finalize the initing of png library */
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);
|
||||
|
||||
/* set other zlib parameters */
|
||||
png_set_compression_mem_level(png_ptr, 8);
|
||||
png_set_compression_strategy(png_ptr,Z_DEFAULT_STRATEGY);
|
||||
png_set_compression_window_bits(png_ptr, 15);
|
||||
png_set_compression_method(png_ptr, 8);
|
||||
png_set_compression_buffer_size(png_ptr, 8192);
|
||||
|
||||
if (render.shot.bpp==8) {
|
||||
png_set_IHDR(png_ptr, info_ptr, render.shot.width, (render.shot.height*fix_double_scale),
|
||||
8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
for (i=0;i<256;i++) {
|
||||
palette[i].red=render.pal.rgb[i].red;
|
||||
palette[i].green=render.pal.rgb[i].green;
|
||||
palette[i].blue=render.pal.rgb[i].blue;
|
||||
}
|
||||
png_set_PLTE(png_ptr, info_ptr, palette,256);
|
||||
} else {
|
||||
png_set_IHDR(png_ptr, info_ptr, render.shot.width, (render.shot.height*fix_double_scale),
|
||||
render.shot.bpp, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
/*Allocate an array of scanline pointers*/
|
||||
row_pointers=(png_bytep*)malloc(render.shot.height*fix_double_scale*sizeof(png_bytep));
|
||||
for (i = 0;i < render.shot.height;i++) {
|
||||
row_pointers[fix_double_scale*i] = (bitmap+i*render.shot.rowlen);
|
||||
if(fix_double_scale == 2) row_pointers[fix_double_scale*i+1] = (bitmap+i*render.shot.rowlen);
|
||||
}
|
||||
|
||||
/*tell the png library what to encode.*/
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
||||
|
||||
/*Write image to file*/
|
||||
png_write_png(png_ptr, info_ptr, 0, NULL);
|
||||
|
||||
/*close file*/
|
||||
fclose(fp);
|
||||
|
||||
/*Destroy PNG structs*/
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
/*clean up dynamically allocated RAM.*/
|
||||
free(row_pointers);
|
||||
}
|
||||
|
||||
static void EnableScreenShot(void) {
|
||||
render.shot.take=true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Render_t render;
|
||||
|
||||
static void Check_Palette(void) {
|
||||
if (render.pal.first>render.pal.last) return;
|
||||
/* Clean up any previous changed palette data */
|
||||
if (render.pal.changed) {
|
||||
memset(render.pal.modified, 0, sizeof(render.pal.modified));
|
||||
render.pal.changed = false;
|
||||
}
|
||||
if (render.pal.first>render.pal.last)
|
||||
return;
|
||||
Bitu i;
|
||||
switch (render.op.mode) {
|
||||
case GFX_8:
|
||||
switch (render.scale.outMode) {
|
||||
case scalerMode8:
|
||||
GFX_SetPalette(render.pal.first,render.pal.last-render.pal.first+1,(GFX_PalEntry *)&render.pal.rgb[render.pal.first]);
|
||||
break;
|
||||
case GFX_15:
|
||||
case GFX_16:
|
||||
case scalerMode15:
|
||||
case scalerMode16:
|
||||
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;
|
||||
Scaler_PaletteLut.b16[i]=GFX_GetRGB(r,g,b);
|
||||
Bit16u newPal = GFX_GetRGB(r,g,b);
|
||||
if (newPal != render.pal.lut.b16[i]) {
|
||||
render.pal.changed = true;
|
||||
render.pal.lut.b16[i] = newPal;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GFX_32:
|
||||
case scalerMode32:
|
||||
default:
|
||||
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;
|
||||
Scaler_PaletteLut.b32[i]=GFX_GetRGB(r,g,b);
|
||||
Bit32u newPal = GFX_GetRGB(r,g,b);
|
||||
if (newPal != render.pal.lut.b32[i]) {
|
||||
render.pal.changed = true;
|
||||
render.pal.lut.b32[i] = newPal;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -215,60 +94,101 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) {
|
|||
if (render.pal.last<entry) render.pal.last=entry;
|
||||
}
|
||||
|
||||
static void RENDER_EmptyLineHandler(const Bit8u * src) {
|
||||
|
||||
static void RENDER_EmptyCacheHandler(const void * src) {
|
||||
}
|
||||
static void RENDER_EmptyLineHandler(void) {
|
||||
}
|
||||
|
||||
|
||||
bool RENDER_StartUpdate(void) {
|
||||
if (!render.updating) {
|
||||
if (render.frameskip.count>=render.frameskip.max) {
|
||||
if (render.src.bpp==8) Check_Palette();
|
||||
render.frameskip.count=0;
|
||||
Scaler_Line=0;
|
||||
Scaler_Index=Scaler_Data;
|
||||
if (GFX_StartUpdate(Scaler_DstWrite,Scaler_DstPitch)) {
|
||||
RENDER_DrawLine=render.op.line_handler;
|
||||
#if (C_SSHOT)
|
||||
if (GCC_UNLIKELY(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.rowlen=render.shot.width;break;
|
||||
case 15:
|
||||
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.rowlen*render.shot.height);
|
||||
render.shot.draw=render.shot.buffer;
|
||||
RENDER_DrawLine=RENDER_ShotDraw;
|
||||
render.shot.taking=true;
|
||||
}
|
||||
#endif
|
||||
render.updating=true;
|
||||
return true;
|
||||
}
|
||||
} else render.frameskip.count++;
|
||||
}
|
||||
return false;
|
||||
if (GCC_UNLIKELY(render.updating))
|
||||
return false;
|
||||
if (GCC_UNLIKELY(!render.active))
|
||||
return false;
|
||||
if (GCC_UNLIKELY(render.frameskip.count<render.frameskip.max)) {
|
||||
render.frameskip.count++;
|
||||
return false;
|
||||
}
|
||||
render.frameskip.count=0;
|
||||
if (render.scale.inMode == scalerMode8) {
|
||||
Check_Palette();
|
||||
}
|
||||
if (GCC_UNLIKELY(!GFX_StartUpdate(render.scale.outWrite,render.scale.outPitch)))
|
||||
return false;
|
||||
render.scale.inLine = 0;
|
||||
render.scale.outLine = 0;
|
||||
Scaler_ChangedLines[0] = 0;
|
||||
Scaler_ChangedLineIndex = 0;
|
||||
/*
|
||||
if (GCC_UNLIKELY( render.scale.clearCache) ) {
|
||||
LOG_MSG("Clearing cache");
|
||||
render.scale.clearCache = false;
|
||||
render.scale.cacheHandler = RENDER_EmptyCacheHandler;
|
||||
memset( scalerChangeCache, SCALE_FULL, sizeof( scalerChangeCache ) );
|
||||
} else */
|
||||
{
|
||||
ScalerCacheBlock_t *cacheBlock;
|
||||
switch (render.scale.inMode) {
|
||||
case scalerMode8:
|
||||
cacheBlock = !render.pal.changed ? &ScalerCache_8 : &ScalerCache_8Pal;
|
||||
break;
|
||||
case scalerMode15:
|
||||
cacheBlock = &ScalerCache_15;
|
||||
break;
|
||||
case scalerMode16:
|
||||
cacheBlock = &ScalerCache_16;
|
||||
break;
|
||||
case scalerMode32:
|
||||
cacheBlock = &ScalerCache_32;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (render.scale.lineFlags & ScaleFlagSimple) {
|
||||
render.scale.cacheHandler = cacheBlock->simple[render.scale.outMode];
|
||||
} else {
|
||||
render.scale.cacheHandler = cacheBlock->complex[render.scale.outMode];
|
||||
}
|
||||
}
|
||||
render.scale.lineHandler = render.scale.currentHandler;
|
||||
render.updating=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RENDER_EndUpdate(void) {
|
||||
if (render.updating) {
|
||||
#if (C_SSHOT)
|
||||
if (GCC_UNLIKELY(render.shot.taking)) {
|
||||
render.shot.taking=false;
|
||||
TakeScreenShot(render.shot.buffer);
|
||||
free(render.shot.buffer);
|
||||
render.shot.buffer=0;
|
||||
if (!render.updating)
|
||||
return;
|
||||
render.scale.cacheHandler = RENDER_EmptyCacheHandler;
|
||||
render.scale.lineHandler = RENDER_EmptyLineHandler;
|
||||
if (CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO)) {
|
||||
Bitu pitch, flags;
|
||||
switch (render.scale.inMode) {
|
||||
case scalerMode8:
|
||||
pitch = sizeof(scalerSourceCache.b8[0]);
|
||||
break;
|
||||
case scalerMode15:
|
||||
case scalerMode16:
|
||||
pitch = sizeof(scalerSourceCache.b16[0]);
|
||||
break;
|
||||
case scalerMode32:
|
||||
pitch = sizeof(scalerSourceCache.b32[0]);
|
||||
break;
|
||||
}
|
||||
flags = 0;
|
||||
if (render.src.dblw != render.src.dblh) {
|
||||
if (render.src.dblw) flags|=CAPTURE_FLAG_DBLW;
|
||||
if (render.src.dblh) flags|=CAPTURE_FLAG_DBLH;
|
||||
}
|
||||
CAPTURE_AddImage( render.src.width, render.src.height, render.src.bpp, pitch,
|
||||
flags, render.src.fps, scalerSourceCache.b8[0], (Bit8u*)&render.pal.rgb );
|
||||
}
|
||||
#endif /* If Things are added to please check the define */
|
||||
GFX_EndUpdate();
|
||||
RENDER_DrawLine=RENDER_EmptyLineHandler;
|
||||
GFX_EndUpdate( Scaler_ChangedLines );
|
||||
render.updating=false;
|
||||
}
|
||||
}
|
||||
|
||||
void RENDER_DrawLine( const void *src ) {
|
||||
render.scale.cacheHandler( src );
|
||||
render.scale.lineHandler();
|
||||
}
|
||||
|
||||
static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) {
|
||||
|
@ -280,90 +200,191 @@ static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) {
|
|||
Bitu templines=(Bitu)lines;
|
||||
lines-=templines;
|
||||
linesadded+=templines;
|
||||
Scaler_Data[i]=templines-miny;
|
||||
} else Scaler_Data[i]=0;
|
||||
Scaler_Aspect[1+i]=templines-miny;
|
||||
} else Scaler_Aspect[1+i]=0;
|
||||
}
|
||||
return linesadded;
|
||||
}
|
||||
|
||||
void RENDER_ReInit(void) {
|
||||
if (render.updating) RENDER_EndUpdate();
|
||||
void RENDER_ReInit( bool stopIt ) {
|
||||
if (render.updating)
|
||||
RENDER_EndUpdate();
|
||||
|
||||
if (stopIt)
|
||||
return;
|
||||
|
||||
Bitu width=render.src.width;
|
||||
Bitu height=render.src.height;
|
||||
bool dblw=render.src.dblw;
|
||||
bool dblh=render.src.dblh;
|
||||
|
||||
double gfx_scalew=1.0;
|
||||
double gfx_scaleh=1.0;
|
||||
double gfx_scalew;
|
||||
double gfx_scaleh;
|
||||
|
||||
if (render.src.ratio>1.0) gfx_scaleh*=render.src.ratio;
|
||||
else gfx_scalew*=(1/render.src.ratio);
|
||||
|
||||
Bitu gfx_flags;
|
||||
ScalerBlock * block;
|
||||
ScalerLineBlock_t *lineBlock;
|
||||
if (render.aspect) {
|
||||
if (render.src.ratio>1.0) {
|
||||
gfx_scalew = 1;
|
||||
gfx_scaleh = render.src.ratio;
|
||||
} else {
|
||||
gfx_scalew = (1/render.src.ratio);
|
||||
gfx_scaleh = 1;
|
||||
}
|
||||
} else {
|
||||
gfx_scalew = 1;
|
||||
gfx_scaleh = 1;
|
||||
}
|
||||
lineBlock = &ScaleNormal;
|
||||
if (dblh && dblw) {
|
||||
render.op.type=render.op.want_type;
|
||||
/* Initialize always working defaults */
|
||||
if (render.scale.size == 2)
|
||||
lineBlock = &ScaleNormal2x;
|
||||
else if (render.scale.size == 3)
|
||||
lineBlock = &ScaleNormal3x;
|
||||
else
|
||||
lineBlock = &ScaleNormal;
|
||||
/* Maybe override them */
|
||||
switch (render.scale.op) {
|
||||
case scalerOpAdvInterp:
|
||||
if (render.scale.size == 2)
|
||||
lineBlock = &ScaleAdvInterp2x;
|
||||
break;
|
||||
case scalerOpAdvMame:
|
||||
if (render.scale.size == 2)
|
||||
lineBlock = &ScaleAdvMame2x;
|
||||
else if (render.scale.size == 3)
|
||||
lineBlock = &ScaleAdvMame3x;
|
||||
break;
|
||||
case scalerOpTV:
|
||||
if (render.scale.size == 2)
|
||||
lineBlock = &ScaleTV2x;
|
||||
else if (render.scale.size == 3)
|
||||
lineBlock = &ScaleTV3x;
|
||||
break;
|
||||
case scalerOpRGB:
|
||||
if (render.scale.size == 2)
|
||||
lineBlock = &ScaleRGB2x;
|
||||
else if (render.scale.size == 3)
|
||||
lineBlock = &ScaleRGB3x;
|
||||
break;
|
||||
case scalerOpScan:
|
||||
if (render.scale.size == 2)
|
||||
lineBlock = &ScaleScan2x;
|
||||
else if (render.scale.size == 3)
|
||||
lineBlock = &ScaleScan3x;
|
||||
break;
|
||||
}
|
||||
} else if (dblw) {
|
||||
render.op.type=OP_Normal2x;
|
||||
lineBlock = &ScaleNormalDw;
|
||||
} else if (dblh) {
|
||||
render.op.type=OP_Normal;
|
||||
gfx_scaleh*=2;
|
||||
lineBlock = &ScaleNormalDh;
|
||||
} else {
|
||||
forcenormal:
|
||||
render.op.type=OP_Normal;
|
||||
lineBlock = &ScaleNormal;
|
||||
}
|
||||
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);
|
||||
gfx_flags = lineBlock->gfxFlags;
|
||||
if (render.src.bpp != 8)
|
||||
gfx_flags |= GFX_RGBONLY;
|
||||
gfx_flags=GFX_GetBestMode(gfx_flags);
|
||||
if (!gfx_flags) {
|
||||
if (render.op.type==OP_Normal) E_Exit("Failed to create a rendering output");
|
||||
else goto forcenormal;
|
||||
if (lineBlock == &ScaleNormal)
|
||||
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);
|
||||
width *= lineBlock->xscale;
|
||||
if (gfx_flags & GFX_SCALING) {
|
||||
height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale );
|
||||
} else {
|
||||
gfx_scaleh*=block->yscale;
|
||||
height=MakeAspectTable(render.src.height,gfx_scaleh,block->miny);
|
||||
if ((gfx_flags & GFX_CAN_RANDOM) && gfx_scaleh > 1) {
|
||||
gfx_scaleh *= lineBlock->yscale;
|
||||
height = MakeAspectTable(render.src.height, gfx_scaleh, lineBlock->yscale );
|
||||
} else {
|
||||
gfx_flags &= ~GFX_CAN_RANDOM; //Hardware surface when possible
|
||||
height = MakeAspectTable(render.src.height, lineBlock->yscale, lineBlock->yscale);
|
||||
}
|
||||
}
|
||||
/* 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;
|
||||
Scaler_SrcWidth=render.src.width;
|
||||
Scaler_SrcHeight=render.src.height;
|
||||
gfx_flags=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_ReInit);;
|
||||
if (gfx_flags & GFX_CAN_8)
|
||||
render.scale.outMode = scalerMode8;
|
||||
else if (gfx_flags & GFX_CAN_15)
|
||||
render.scale.outMode = scalerMode15;
|
||||
else if (gfx_flags & GFX_CAN_16)
|
||||
render.scale.outMode = scalerMode16;
|
||||
else if (gfx_flags & GFX_CAN_32)
|
||||
render.scale.outMode = scalerMode32;
|
||||
else
|
||||
E_Exit("Failed to create a rendering output");
|
||||
if (gfx_flags & GFX_HARDWARE) {
|
||||
render.scale.currentHandler = lineBlock->Linear[ render.scale.outMode ];
|
||||
} else {
|
||||
render.scale.currentHandler = lineBlock->Random[ render.scale.outMode ];
|
||||
}
|
||||
switch (render.src.bpp) {
|
||||
case 8:
|
||||
render.scale.inMode = scalerMode8;
|
||||
break;
|
||||
case 15:
|
||||
render.scale.inMode = scalerMode15;
|
||||
break;
|
||||
case 16:
|
||||
render.scale.inMode = scalerMode16;
|
||||
break;
|
||||
case 32:
|
||||
render.scale.inMode = scalerMode32;
|
||||
break;
|
||||
default:
|
||||
E_Exit("RENDER:Wrong source bpp %d", render.src.bpp );
|
||||
}
|
||||
render.scale.lineFlags = lineBlock->scaleFlags;
|
||||
render.scale.blocks = render.src.width / SCALER_BLOCKSIZE;
|
||||
render.scale.lastBlock = render.src.width % SCALER_BLOCKSIZE;
|
||||
render.scale.inHeight = render.src.height;
|
||||
RENDER_ResetPal();
|
||||
/* Not exactltly the best way to clean the cache, but seems to do the trick */
|
||||
for (Bitu y=0;y<render.src.height;y++) {
|
||||
Bit32u *cacheLine;
|
||||
Bitu x;
|
||||
switch (render.scale.inMode) {
|
||||
case scalerMode8:
|
||||
cacheLine = (Bit32u *)scalerSourceCache.b8[y];
|
||||
x = render.src.width / 4;
|
||||
break;
|
||||
case scalerMode15:
|
||||
case scalerMode16:
|
||||
cacheLine = (Bit32u *)scalerSourceCache.b16[y];
|
||||
x = render.src.width / 2;
|
||||
break;
|
||||
case scalerMode32:
|
||||
cacheLine = (Bit32u *)scalerSourceCache.b32[y];
|
||||
x = render.src.width / 1;
|
||||
break;
|
||||
}
|
||||
for (;x>0;x--)
|
||||
cacheLine[x] = ~cacheLine[x];
|
||||
}
|
||||
//Maybe do it again through a special passthrough cache check handler
|
||||
render.scale.clearCache = true;
|
||||
render.active=true;
|
||||
}
|
||||
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh) {
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh) {
|
||||
if (!width || !height) {
|
||||
render.active=false;
|
||||
return;
|
||||
}
|
||||
RENDER_EndUpdate();
|
||||
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_ReInit();
|
||||
render.src.fps=fps;
|
||||
render.src.ratio=ratio;
|
||||
RENDER_ReInit( false );
|
||||
}
|
||||
|
||||
extern void GFX_SetTitle(Bits cycles, Bits frameskip,bool paused);
|
||||
|
@ -385,42 +406,43 @@ void RENDER_Init(Section * sec) {
|
|||
//For restarting the renderer.
|
||||
static bool running = false;
|
||||
bool aspect = render.aspect;
|
||||
RENDER_Operation type = render.op.want_type;
|
||||
scalerOperation_t scaleOp = render.scale.op;
|
||||
|
||||
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;
|
||||
render.active=false;
|
||||
const char * scaler;std::string cline;
|
||||
if (control->cmdline->FindString("-scaler",cline,false)) {
|
||||
scaler=cline.c_str();
|
||||
} else {
|
||||
scaler=section->Get_string("scaler");
|
||||
}
|
||||
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;
|
||||
if (!strcasecmp(scaler,"none")) { render.scale.op = scalerOpNormal;render.scale.size = 1; }
|
||||
else if (!strcasecmp(scaler,"normal2x")) { render.scale.op = scalerOpNormal;render.scale.size = 2; }
|
||||
else if (!strcasecmp(scaler,"normal3x")) { render.scale.op = scalerOpNormal;render.scale.size = 3; }
|
||||
else if (!strcasecmp(scaler,"advmame2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; }
|
||||
else if (!strcasecmp(scaler,"advmame3x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 3; }
|
||||
else if (!strcasecmp(scaler,"advinterp2x")) { render.scale.op = scalerOpAdvMame;render.scale.size = 2; }
|
||||
else if (!strcasecmp(scaler,"tv2x")) { render.scale.op = scalerOpTV;render.scale.size = 2; }
|
||||
else if (!strcasecmp(scaler,"tv3x")) { render.scale.op = scalerOpTV;render.scale.size = 3; }
|
||||
else if (!strcasecmp(scaler,"rgb2x")){ render.scale.op = scalerOpRGB;render.scale.size = 2; }
|
||||
else if (!strcasecmp(scaler,"rgb3x")){ render.scale.op = scalerOpRGB;render.scale.size = 3; }
|
||||
else if (!strcasecmp(scaler,"scan2x")){ render.scale.op = scalerOpScan;render.scale.size = 2; }
|
||||
else if (!strcasecmp(scaler,"scan3x")){ render.scale.op = scalerOpScan;render.scale.size = 3; }
|
||||
else {
|
||||
render.op.want_type=OP_Normal;
|
||||
render.scale.op = scalerOpNormal;render.scale.size = 1;
|
||||
LOG_MSG("Illegal scaler type %s,falling back to normal.",scaler);
|
||||
}
|
||||
|
||||
//If something changed that needs a ReInit
|
||||
if(running && (render.aspect != aspect || render.op.want_type != type))
|
||||
RENDER_ReInit();
|
||||
if(running && (render.aspect != aspect || render.scale.op != scaleOp))
|
||||
RENDER_ReInit( false );
|
||||
if(!running) render.updating=true;
|
||||
running = true;
|
||||
|
||||
|
||||
|
||||
#if (C_SSHOT)
|
||||
MAPPER_AddHandler(EnableScreenShot,MK_f5,MMOD1,"scrshot","Screenshot");
|
||||
#endif
|
||||
MAPPER_AddHandler(DecreaseFrameSkip,MK_f7,MMOD1,"decfskip","Dec Fskip");
|
||||
MAPPER_AddHandler(IncreaseFrameSkip,MK_f8,MMOD1,"incfskip","Inc Fskip");
|
||||
GFX_SetTitle(-1,render.frameskip.max,false);
|
||||
|
|
182
src/gui/render_loops.h
Normal file
182
src/gui/render_loops.h
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2005 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if defined (SCALERLINEAR)
|
||||
void conc3d(SCALERNAME,SBPP,L)(void) {
|
||||
#else
|
||||
void conc3d(SCALERNAME,SBPP,R)(void) {
|
||||
#endif
|
||||
if (!render.scale.outLine) {
|
||||
render.scale.outLine++;
|
||||
return;
|
||||
}
|
||||
lastagain:
|
||||
if (!CC[render.scale.outLine][0]) {
|
||||
#if defined(SCALERLINEAR)
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
#else
|
||||
Bitu scaleLines = SCALERHEIGHT + Scaler_Aspect[ render.scale.outLine ];
|
||||
#endif
|
||||
render.scale.outWrite += render.scale.outPitch * scaleLines;
|
||||
if (!(Scaler_ChangedLineIndex & 1)) {
|
||||
Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines;
|
||||
} else {
|
||||
Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines;
|
||||
}
|
||||
if (++render.scale.outLine == render.scale.inHeight)
|
||||
goto lastagain;
|
||||
return;
|
||||
}
|
||||
/* Clear the complete line marker */
|
||||
CC[render.scale.outLine][0] = 0;
|
||||
const PTYPE * fc = &FC[render.scale.outLine][1];
|
||||
PTYPE * line0=(PTYPE *)(render.scale.outWrite);
|
||||
Bit8u * changed = &CC[render.scale.outLine][1];
|
||||
Bitu b;
|
||||
for (b=0;b<render.scale.blocks;b++) {
|
||||
#if (SCALERHEIGHT > 1)
|
||||
PTYPE * line1;
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
PTYPE * line2;
|
||||
#endif
|
||||
|
||||
#if defined ( SCALERSIMPLE )
|
||||
if (!changed[b]) {
|
||||
line0 += SCALERWIDTH * SCALER_BLOCKSIZE;
|
||||
fc += SCALER_BLOCKSIZE;
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
switch (changed[b]) {
|
||||
case 0:
|
||||
line0 += SCALERWIDTH * SCALER_BLOCKSIZE;
|
||||
fc += SCALER_BLOCKSIZE;
|
||||
continue;
|
||||
case SCALE_LEFT:
|
||||
#if (SCALERHEIGHT > 1)
|
||||
line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch);
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2);
|
||||
#endif
|
||||
SCALERFUNC;
|
||||
line0 += SCALERWIDTH * SCALER_BLOCKSIZE;
|
||||
fc += SCALER_BLOCKSIZE;
|
||||
break;
|
||||
case SCALE_LEFT | SCALE_RIGHT:
|
||||
#if (SCALERHEIGHT > 1)
|
||||
line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch);
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2);
|
||||
#endif
|
||||
SCALERFUNC;
|
||||
case SCALE_RIGHT:
|
||||
#if (SCALERHEIGHT > 1)
|
||||
line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch);
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2);
|
||||
#endif
|
||||
line0 += SCALERWIDTH * (SCALER_BLOCKSIZE -1);
|
||||
#if (SCALERHEIGHT > 1)
|
||||
line1 += SCALERWIDTH * (SCALER_BLOCKSIZE -1);
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
line2 += SCALERWIDTH * (SCALER_BLOCKSIZE -1);
|
||||
#endif
|
||||
fc += SCALER_BLOCKSIZE -1;
|
||||
SCALERFUNC;
|
||||
line0 += SCALERWIDTH;
|
||||
fc++;
|
||||
break;
|
||||
default:
|
||||
#endif //SCALERSIMPLE
|
||||
|
||||
#if defined(SCALERLINEAR)
|
||||
#if (SCALERHEIGHT > 1)
|
||||
line1 = WC[0];
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
line2 = WC[1];
|
||||
#endif
|
||||
#else
|
||||
#if (SCALERHEIGHT > 1)
|
||||
line1 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch);
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
line2 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 2);
|
||||
#endif
|
||||
#endif //defined(SCALERLINEAR)
|
||||
for (Bitu i = 0; i<SCALER_BLOCKSIZE;i++) {
|
||||
SCALERFUNC;
|
||||
line0 += SCALERWIDTH;
|
||||
#if (SCALERHEIGHT > 1)
|
||||
line1 += SCALERWIDTH;
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
line2 += SCALERWIDTH;
|
||||
#endif
|
||||
fc++;
|
||||
}
|
||||
#if defined(SCALERLINEAR)
|
||||
#if (SCALERHEIGHT > 1)
|
||||
BituMove((Bit8u*)(&line0[-SCALER_BLOCKSIZE*SCALERWIDTH])+render.scale.outPitch ,WC[0], SCALER_BLOCKSIZE *SCALERWIDTH*PSIZE);
|
||||
#endif
|
||||
#if (SCALERHEIGHT > 2)
|
||||
BituMove((Bit8u*)(&line0[-SCALER_BLOCKSIZE*SCALERWIDTH])+render.scale.outPitch*2,WC[1], SCALER_BLOCKSIZE *SCALERWIDTH*PSIZE);
|
||||
#endif
|
||||
#endif //defined(SCALERLINEAR)
|
||||
#if !defined (SCALERSIMPLE)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* Clear this block being dirty marker */
|
||||
changed[b] = 0;
|
||||
}
|
||||
#if defined(SCALERLINEAR)
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
render.scale.outWrite += render.scale.outPitch * scaleLines;
|
||||
#else
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
if ( Scaler_Aspect[ render.scale.outLine ] ) {
|
||||
scaleLines++;
|
||||
BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT,
|
||||
render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1),
|
||||
render.src.width * SCALERWIDTH * PSIZE);
|
||||
render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1);
|
||||
} else {
|
||||
render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT;
|
||||
}
|
||||
#endif
|
||||
/* Keep track of changed lines */
|
||||
if (Scaler_ChangedLineIndex & 1) {
|
||||
Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines;
|
||||
} else {
|
||||
Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines;
|
||||
}
|
||||
if (++render.scale.outLine == render.scale.inHeight)
|
||||
goto lastagain;
|
||||
}
|
||||
|
||||
#if !defined(SCALERLINEAR)
|
||||
#define SCALERLINEAR 1
|
||||
#include "render_loops.h"
|
||||
#undef SCALERLINEAR
|
||||
#endif
|
|
@ -16,30 +16,28 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
//TODO:
|
||||
//Maybe just do the cache checking back into the simple scalers so they can
|
||||
//just handle it all in one go, but this seems to work well enough for now
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "render_scalers.h"
|
||||
#include "render.h"
|
||||
#include <string.h>
|
||||
|
||||
Bitu Scaler_Line;
|
||||
Bitu Scaler_SrcWidth;
|
||||
Bitu Scaler_SrcHeight;
|
||||
Bitu Scaler_DstPitch;
|
||||
Bit8u * Scaler_DstWrite;
|
||||
Bit8u * Scaler_Index;
|
||||
Bit8u Scaler_Data[SCALER_MAXHEIGHT*5]; //5cmds/line
|
||||
PaletteLut Scaler_PaletteLut;
|
||||
Bit8u Scaler_Aspect[SCALER_MAXHEIGHT];
|
||||
Bit16u Scaler_ChangedLines[SCALER_MAXHEIGHT];
|
||||
Bitu Scaler_ChangedLineIndex;
|
||||
|
||||
static union {
|
||||
Bit32u b32 [4][SCALER_MAXWIDTH];
|
||||
Bit16u b16 [4][SCALER_MAXWIDTH];
|
||||
Bit8u b8 [4][SCALER_MAXWIDTH];
|
||||
} line_cache;
|
||||
static union {
|
||||
union {
|
||||
Bit32u b32 [4][SCALER_MAXWIDTH*3];
|
||||
Bit16u b16 [4][SCALER_MAXWIDTH*3];
|
||||
Bit8u b8 [4][SCALER_MAXWIDTH*3];
|
||||
} write_cache;
|
||||
} scalerWriteCache;
|
||||
scalerFrameCache_t scalerFrameCache;
|
||||
scalerSourceCache_t scalerSourceCache;
|
||||
|
||||
static Bit8u * ln[3];
|
||||
Bit8u scalerChangeCache [SCALER_MAXHEIGHT][SCALER_MAXWIDTH / SCALER_BLOCKSIZE];
|
||||
|
||||
#define _conc2(A,B) A ## B
|
||||
#define _conc3(A,B,C) A ## B ## C
|
||||
|
@ -52,7 +50,15 @@ static Bit8u * ln[3];
|
|||
#define conc2d(A,B) _conc3(A,_,B)
|
||||
#define conc3d(A,B,C) _conc5(A,_,B,_,C)
|
||||
|
||||
#define BituMove(_DST,_SRC,_SIZE) \
|
||||
static INLINE void BituMove( void *_dst, const void * _src, Bitu size) {
|
||||
Bitu * dst=(Bitu *)(_dst);
|
||||
const Bitu * src=(Bitu *)(_src);
|
||||
size/=sizeof(Bitu);
|
||||
for (Bitu x=0; x<size;x++)
|
||||
dst[x] = src[x];
|
||||
}
|
||||
|
||||
#define BituMove2(_DST,_SRC,_SIZE) \
|
||||
{ \
|
||||
Bitu bsize=(_SIZE)/sizeof(Bitu); \
|
||||
Bitu * bdst=(Bitu *)(_DST); \
|
||||
|
@ -70,6 +76,9 @@ static Bit8u * ln[3];
|
|||
((((P0&redblueMask)*W0+(P1&redblueMask)*W1+(P2&redblueMask)*W2+(P3&redblueMask)*W3)/(W0+W1+W2+W3)) & redblueMask) | \
|
||||
((((P0& greenMask)*W0+(P1& greenMask)*W1+(P2& greenMask)*W2+(P3& greenMask)*W3)/(W0+W1+W2+W3)) & greenMask)
|
||||
|
||||
|
||||
#define CC scalerChangeCache
|
||||
|
||||
/* Include the different rendering routines */
|
||||
#define SBPP 8
|
||||
#define DBPP 8
|
||||
|
@ -86,54 +95,178 @@ static Bit8u * ln[3];
|
|||
#undef SBPP
|
||||
#undef DBPP
|
||||
|
||||
#define SBPP 15
|
||||
#define DBPP 15
|
||||
#include "render_templates.h"
|
||||
#undef DBPP
|
||||
#define DBPP 16
|
||||
#include "render_templates.h"
|
||||
#undef DBPP
|
||||
#define DBPP 32
|
||||
#include "render_templates.h"
|
||||
#undef SBPP
|
||||
#undef DBPP
|
||||
|
||||
#define SBPP 16
|
||||
#define DBPP 15
|
||||
#include "render_templates.h"
|
||||
#undef DBPP
|
||||
#define DBPP 16
|
||||
#include "render_templates.h"
|
||||
#undef DBPP
|
||||
#define DBPP 32
|
||||
#include "render_templates.h"
|
||||
#undef SBPP
|
||||
#undef DBPP
|
||||
|
||||
ScalerBlock Normal_8={
|
||||
CAN_8|CAN_16|CAN_32|LOVE_8,
|
||||
1,1,1,
|
||||
Normal_8_8,Normal_8_16,Normal_8_16,Normal_8_32
|
||||
#define SBPP 32
|
||||
#define DBPP 15
|
||||
#include "render_templates.h"
|
||||
#undef DBPP
|
||||
#define DBPP 16
|
||||
#include "render_templates.h"
|
||||
#undef DBPP
|
||||
#define DBPP 32
|
||||
#include "render_templates.h"
|
||||
#undef SBPP
|
||||
#undef DBPP
|
||||
|
||||
ScalerCacheBlock_t ScalerCache_8 = {
|
||||
CacheSimple_8_8, CacheSimple_8_15, CacheSimple_8_16, CacheSimple_8_32,
|
||||
CacheComplex_8_8, CacheComplex_8_15, CacheComplex_8_16, CacheComplex_8_32,
|
||||
};
|
||||
|
||||
ScalerBlock NormalDbl_8= {
|
||||
CAN_8|CAN_16|CAN_32|LOVE_8,
|
||||
2,1,1,
|
||||
Normal2x_8_8,Normal2x_8_16,Normal2x_8_16,Normal2x_8_32
|
||||
ScalerCacheBlock_t ScalerCache_8Pal = {
|
||||
0, CacheSimplePal_8_15, CacheSimplePal_8_16, CacheSimplePal_8_32,
|
||||
0, CacheComplexPal_8_15, CacheComplexPal_8_16, CacheComplexPal_8_32,
|
||||
};
|
||||
|
||||
ScalerBlock Normal2x_8={
|
||||
CAN_8|CAN_16|CAN_32|LOVE_8,
|
||||
2,2,1,
|
||||
Normal2x_8_8,Normal2x_8_16,Normal2x_8_16,Normal2x_8_32
|
||||
ScalerCacheBlock_t ScalerCache_15 = {
|
||||
0, CacheSimple_15_15, CacheSimple_15_16, CacheSimple_15_32,
|
||||
0, CacheComplex_15_15, CacheComplex_15_16, CacheComplex_15_32,
|
||||
};
|
||||
|
||||
ScalerBlock AdvMame2x_8={
|
||||
CAN_8|CAN_16|CAN_32|LOVE_8,
|
||||
2,2,1,
|
||||
AdvMame2x_8_8,AdvMame2x_8_16,AdvMame2x_8_16,AdvMame2x_8_32
|
||||
ScalerCacheBlock_t ScalerCache_16 = {
|
||||
0, CacheSimple_16_15, CacheSimple_16_16, CacheSimple_16_32,
|
||||
0, CacheComplex_16_15, CacheComplex_16_16, CacheComplex_16_32,
|
||||
};
|
||||
|
||||
ScalerBlock AdvMame3x_8={
|
||||
CAN_8|CAN_16|CAN_32|LOVE_8,
|
||||
3,3,2,
|
||||
AdvMame3x_8_8,AdvMame3x_8_16,AdvMame3x_8_16,AdvMame3x_8_32
|
||||
};
|
||||
|
||||
ScalerBlock Interp2x_8={
|
||||
CAN_16|CAN_32|LOVE_32|NEED_RGB,
|
||||
2,2,1,
|
||||
0,Interp2x_8_16,Interp2x_8_16,Interp2x_8_32
|
||||
};
|
||||
|
||||
ScalerBlock AdvInterp2x_8={
|
||||
CAN_16|CAN_32|LOVE_32|NEED_RGB,
|
||||
2,2,1,
|
||||
0,AdvInterp2x_8_16,AdvInterp2x_8_16,AdvInterp2x_8_32
|
||||
};
|
||||
|
||||
ScalerBlock TV2x_8={
|
||||
CAN_16|CAN_32|LOVE_32|NEED_RGB,
|
||||
2,2,1,
|
||||
0,TV2x_8_16,TV2x_8_16,TV2x_8_32
|
||||
ScalerCacheBlock_t ScalerCache_32 = {
|
||||
0, CacheSimple_32_15, CacheSimple_32_16, CacheSimple_32_32,
|
||||
0, CacheComplex_32_15, CacheComplex_32_16, CacheComplex_32_32,
|
||||
};
|
||||
|
||||
|
||||
/* 8 bpp input versions */
|
||||
ScalerLineBlock_t ScaleNormal = {
|
||||
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
|
||||
ScaleFlagSimple,
|
||||
1,1,
|
||||
Normal_8_L,Normal_16_L,Normal_16_L,Normal_32_L,
|
||||
Normal_8_R,Normal_16_R,Normal_16_R,Normal_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleNormalDw = {
|
||||
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
|
||||
ScaleFlagSimple,
|
||||
2,1,
|
||||
NormalDw_8_L,NormalDw_16_L,NormalDw_16_L,NormalDw_32_L,
|
||||
NormalDw_8_R,NormalDw_16_R,NormalDw_16_R,NormalDw_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleNormalDh = {
|
||||
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
|
||||
ScaleFlagSimple,
|
||||
2,1,
|
||||
NormalDh_8_L,NormalDh_16_L,NormalDh_16_L,NormalDh_32_L,
|
||||
NormalDh_8_R,NormalDh_16_R,NormalDh_16_R,NormalDh_32_R
|
||||
};
|
||||
|
||||
|
||||
ScalerLineBlock_t ScaleNormal2x = {
|
||||
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
|
||||
ScaleFlagSimple,
|
||||
2,2,
|
||||
Normal2x_8_L,Normal2x_16_L,Normal2x_16_L,Normal2x_32_L,
|
||||
Normal2x_8_R,Normal2x_16_R,Normal2x_16_R,Normal2x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleNormal3x = {
|
||||
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
|
||||
ScaleFlagSimple,
|
||||
3,3,
|
||||
Normal3x_8_L,Normal3x_16_L,Normal3x_16_L,Normal3x_32_L,
|
||||
Normal3x_8_R,Normal3x_16_R,Normal3x_16_R,Normal3x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleAdvMame2x ={
|
||||
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
|
||||
0,
|
||||
2,2,
|
||||
AdvMame2x_8_L,AdvMame2x_16_L,AdvMame2x_16_L,AdvMame2x_32_L,
|
||||
AdvMame2x_8_R,AdvMame2x_16_R,AdvMame2x_16_R,AdvMame2x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleAdvMame3x = {
|
||||
GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_8,
|
||||
0,
|
||||
3,3,
|
||||
AdvMame3x_8_L,AdvMame3x_16_L,AdvMame3x_16_L,AdvMame3x_32_L,
|
||||
AdvMame3x_8_R,AdvMame3x_16_R,AdvMame3x_16_R,AdvMame3x_32_R
|
||||
};
|
||||
|
||||
/* These need specific 15bpp versions */
|
||||
ScalerLineBlock_t ScaleAdvInterp2x = {
|
||||
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
|
||||
0,
|
||||
2,2,
|
||||
0,AdvInterp2x_15_L,AdvInterp2x_16_L,AdvInterp2x_32_L,
|
||||
0,AdvInterp2x_15_R,AdvInterp2x_16_R,AdvInterp2x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleTV2x = {
|
||||
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
|
||||
ScaleFlagSimple,
|
||||
2,2,
|
||||
0,TV2x_15_L,TV2x_16_L,TV2x_32_L,
|
||||
0,TV2x_15_R,TV2x_16_R,TV2x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleTV3x = {
|
||||
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
|
||||
ScaleFlagSimple,
|
||||
3,3,
|
||||
0,TV3x_15_L,TV3x_16_L,TV3x_32_L,
|
||||
0,TV3x_15_R,TV3x_16_R,TV3x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleRGB2x = {
|
||||
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
|
||||
ScaleFlagSimple,
|
||||
2,2,
|
||||
0,RGB2x_15_L,RGB2x_16_L,RGB2x_32_L,
|
||||
0,RGB2x_15_R,RGB2x_16_R,RGB2x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleRGB3x = {
|
||||
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
|
||||
ScaleFlagSimple,
|
||||
3,3,
|
||||
0,RGB3x_15_L,RGB3x_16_L,RGB3x_32_L,
|
||||
0,RGB3x_15_R,RGB3x_16_R,RGB3x_32_R
|
||||
};
|
||||
|
||||
|
||||
ScalerLineBlock_t ScaleScan2x = {
|
||||
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
|
||||
ScaleFlagSimple,
|
||||
2,2,
|
||||
0,Scan2x_15_L,Scan2x_16_L,Scan2x_32_L,
|
||||
0,Scan2x_15_R,Scan2x_16_R,Scan2x_32_R
|
||||
};
|
||||
|
||||
ScalerLineBlock_t ScaleScan3x = {
|
||||
GFX_CAN_15|GFX_CAN_16|GFX_CAN_32|GFX_LOVE_32|GFX_RGBONLY,
|
||||
ScaleFlagSimple,
|
||||
3,3,
|
||||
0,Scan3x_15_L,Scan3x_16_L,Scan3x_32_L,
|
||||
0,Scan3x_15_R,Scan3x_16_R,Scan3x_32_R
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -19,51 +19,98 @@
|
|||
#ifndef _RENDER_SCALERS_H
|
||||
#define _RENDER_SCALERS_H
|
||||
|
||||
#include "render.h"
|
||||
//#include "render.h"
|
||||
#include "video.h"
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define SCALER_MAXWIDTH 1280
|
||||
#define SCALER_MAXHEIGHT 1024
|
||||
#define SCALER_MAXWIDTH 1024
|
||||
#define SCALER_MAXHEIGHT 768
|
||||
#define SCALER_BLOCKSIZE 16
|
||||
|
||||
extern Bitu Scaler_Line;
|
||||
extern Bitu Scaler_SrcWidth;
|
||||
extern Bitu Scaler_SrcHeight;
|
||||
extern Bitu Scaler_DstPitch;
|
||||
extern Bit8u * Scaler_DstWrite;
|
||||
extern Bit8u Scaler_Data[];
|
||||
extern Bit8u * Scaler_Index;
|
||||
typedef enum {
|
||||
scalerMode8, scalerMode15, scalerMode16, scalerMode32
|
||||
} scalerMode_t;
|
||||
|
||||
union PaletteLut {
|
||||
Bit16u b16[256];
|
||||
Bit32u b32[256];
|
||||
};
|
||||
typedef enum {
|
||||
scalerOpNormal,
|
||||
scalerOpAdvMame,
|
||||
scalerOpAdvInterp,
|
||||
scalerOpTV,
|
||||
scalerOpRGB,
|
||||
scalerOpScan,
|
||||
} scalerOperation_t;
|
||||
|
||||
extern PaletteLut Scaler_PaletteLut;
|
||||
typedef void (*ScalerCacheHandler_t)(const void *src);
|
||||
typedef void (*ScalerLineHandler_t)(void);
|
||||
|
||||
enum RENDER_Operation {
|
||||
OP_Normal,
|
||||
OP_Normal2x,
|
||||
OP_AdvMame2x,
|
||||
OP_AdvMame3x,
|
||||
OP_AdvInterp2x,
|
||||
OP_Interp2x,
|
||||
OP_TV2x,
|
||||
};
|
||||
extern Bit8u Scaler_Aspect[];
|
||||
extern Bit8u diff_table[];
|
||||
extern Bitu Scaler_ChangedLineIndex;
|
||||
extern Bit16u Scaler_ChangedLines[];
|
||||
extern Bit8u scalerChangeCache [SCALER_MAXHEIGHT][SCALER_MAXWIDTH / SCALER_BLOCKSIZE];
|
||||
typedef union {
|
||||
Bit32u b32 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)];
|
||||
Bit16u b16 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)];
|
||||
Bit8u b8 [(SCALER_MAXHEIGHT+2)] [(SCALER_MAXWIDTH+2)];
|
||||
} scalerFrameCache_t;
|
||||
typedef union {
|
||||
Bit32u b32 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH];
|
||||
Bit16u b16 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH];
|
||||
Bit8u b8 [SCALER_MAXHEIGHT] [SCALER_MAXWIDTH];
|
||||
} scalerSourceCache_t;
|
||||
|
||||
struct ScalerBlock {
|
||||
Bitu flags;
|
||||
Bitu xscale,yscale,miny;
|
||||
RENDER_Line_Handler handlers[4];
|
||||
};
|
||||
extern scalerFrameCache_t scalerFrameCache;
|
||||
extern scalerSourceCache_t scalerSourceCache;
|
||||
|
||||
extern ScalerBlock Normal_8;
|
||||
extern ScalerBlock NormalDbl_8;
|
||||
extern ScalerBlock Normal2x_8;
|
||||
extern ScalerBlock AdvMame2x_8;
|
||||
extern ScalerBlock AdvMame3x_8;
|
||||
extern ScalerBlock AdvInterp2x_8;
|
||||
extern ScalerBlock Interp2x_8;
|
||||
extern ScalerBlock TV2x_8;
|
||||
#define ScaleFlagSimple 0x001
|
||||
|
||||
typedef struct {
|
||||
Bitu gfxFlags;
|
||||
Bitu scaleFlags;
|
||||
Bitu xscale,yscale;
|
||||
ScalerLineHandler_t Linear[4];
|
||||
ScalerLineHandler_t Random[4];
|
||||
} ScalerLineBlock_t;
|
||||
|
||||
typedef struct {
|
||||
Bitu gfxFlags;
|
||||
Bitu scaleFlags;
|
||||
Bitu xscale,yscale;
|
||||
ScalerLineHandler_t Linear[4][4];
|
||||
ScalerLineHandler_t Random[4][4];
|
||||
} ScalerFullLineBlock_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ScalerCacheHandler_t simple[4];
|
||||
ScalerCacheHandler_t complex[4];
|
||||
} ScalerCacheBlock_t;
|
||||
|
||||
extern ScalerLineBlock_t ScaleNormal;
|
||||
extern ScalerLineBlock_t ScaleNormalDw;
|
||||
extern ScalerLineBlock_t ScaleNormalDh;
|
||||
|
||||
#define SCALE_LEFT 0x1
|
||||
#define SCALE_RIGHT 0x2
|
||||
#define SCALE_FULL 0x4
|
||||
|
||||
extern ScalerLineBlock_t ScaleNormal2x;
|
||||
extern ScalerLineBlock_t ScaleNormal3x;
|
||||
extern ScalerLineBlock_t ScaleAdvMame2x;
|
||||
extern ScalerLineBlock_t ScaleAdvMame3x;
|
||||
extern ScalerLineBlock_t ScaleAdvInterp2x;
|
||||
|
||||
extern ScalerLineBlock_t ScaleTV2x;
|
||||
extern ScalerLineBlock_t ScaleTV3x;
|
||||
extern ScalerLineBlock_t ScaleRGB2x;
|
||||
extern ScalerLineBlock_t ScaleRGB3x;
|
||||
extern ScalerLineBlock_t ScaleScan2x;
|
||||
extern ScalerLineBlock_t ScaleScan3x;
|
||||
|
||||
extern ScalerCacheBlock_t ScalerCache_8;
|
||||
extern ScalerCacheBlock_t ScalerCache_8Pal;
|
||||
extern ScalerCacheBlock_t ScalerCache_15;
|
||||
extern ScalerCacheBlock_t ScalerCache_16;
|
||||
extern ScalerCacheBlock_t ScalerCache_32;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,294 +19,502 @@
|
|||
#if DBPP == 8
|
||||
#define PSIZE 1
|
||||
#define PTYPE Bit8u
|
||||
#define WC write_cache.b8
|
||||
#define LC line_cache.b8
|
||||
#define redblueMask 0
|
||||
#define greenMask 0
|
||||
#define WC scalerWriteCache.b8
|
||||
#define FC scalerFrameCache.b8
|
||||
#define redMask 0
|
||||
#define greenMask 0
|
||||
#define blueMask 0
|
||||
#elif DBPP == 15 || DBPP == 16
|
||||
#define PSIZE 2
|
||||
#define PTYPE Bit16u
|
||||
#define WC write_cache.b16
|
||||
#define LC line_cache.b16
|
||||
#define WC scalerWriteCache.b16
|
||||
#define FC scalerFrameCache.b16
|
||||
#if DBPP == 15
|
||||
#define redblueMask 0x7C1F
|
||||
#define greenMask 0x03E0
|
||||
#define redMask 0x7C00
|
||||
#define greenMask 0x03E0
|
||||
#define blueMask 0x001F
|
||||
#elif DBPP == 16
|
||||
#define redblueMask 0xF81F
|
||||
#define greenMask 0x07E0
|
||||
#define redMask 0xF800
|
||||
#define greenMask 0x07E0
|
||||
#define blueMask 0x001F
|
||||
#endif
|
||||
#elif DBPP == 32
|
||||
#define PSIZE 4
|
||||
#define PTYPE Bit32u
|
||||
#define WC write_cache.b32
|
||||
#define LC line_cache.b32
|
||||
#define redblueMask 0xff00ff
|
||||
#define greenMask 0xff00
|
||||
#define WC scalerWriteCache.b32
|
||||
#define FC scalerFrameCache.b32
|
||||
#define redMask 0xff0000
|
||||
#define greenMask 0x00ff00
|
||||
#define blueMask 0x0000ff
|
||||
#endif
|
||||
|
||||
#define redblueMask (redMask | blueMask)
|
||||
|
||||
|
||||
#if SBPP == 8
|
||||
#define SC scalerSourceCache.b8
|
||||
#if DBPP == 8
|
||||
#define PMAKE(_VAL) _VAL
|
||||
#define PMAKE(_VAL) (_VAL)
|
||||
#elif DBPP == 15
|
||||
#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL]
|
||||
#define PMAKE(_VAL) render.pal.lut.b16[_VAL]
|
||||
#elif DBPP == 16
|
||||
#define PMAKE(_VAL) Scaler_PaletteLut.b16[_VAL]
|
||||
#define PMAKE(_VAL) render.pal.lut.b16[_VAL]
|
||||
#elif DBPP == 32
|
||||
#define PMAKE(_VAL) Scaler_PaletteLut.b32[_VAL]
|
||||
#define PMAKE(_VAL) render.pal.lut.b32[_VAL]
|
||||
#endif
|
||||
#define SRCTYPE Bit8u
|
||||
#endif
|
||||
|
||||
#define C0 LC[0][x-1]
|
||||
#define C1 LC[0][x+0]
|
||||
#define C2 LC[0][x+1]
|
||||
#define C3 LC[1][x-1]
|
||||
#define C4 LC[1][x+0]
|
||||
#define C5 LC[1][x+1]
|
||||
#define C6 LC[2][x-1]
|
||||
#define C7 LC[2][x+0]
|
||||
#define C8 LC[2][x+1]
|
||||
#if SBPP == 15
|
||||
#define SC scalerSourceCache.b16
|
||||
#if DBPP == 15
|
||||
#define PMAKE(_VAL) (_VAL)
|
||||
#elif DBPP == 16
|
||||
#define PMAKE(_VAL) (((_VAL) & 31) | ((_VAL) & ~31) << 1)
|
||||
#elif DBPP == 32
|
||||
#define PMAKE(_VAL) (((_VAL&(31<<10))<<9)|((_VAL&(31<<5))<<6)|((_VAL&31)<<3))
|
||||
#endif
|
||||
#define SRCTYPE Bit16u
|
||||
#endif
|
||||
|
||||
static void conc3d(Normal,SBPP,DBPP) (const Bit8u * src) {
|
||||
const Bit8u * line;
|
||||
#if SBPP == DBPP
|
||||
line=src;
|
||||
BituMove(Scaler_DstWrite,line,Scaler_SrcWidth*PSIZE);
|
||||
#if SBPP == 16
|
||||
#define SC scalerSourceCache.b16
|
||||
#if DBPP == 15
|
||||
#define PMAKE(_VAL) (((_VAL&~31)>>1)|(_VAL&31))
|
||||
#elif DBPP == 16
|
||||
#define PMAKE(_VAL) (_VAL)
|
||||
#elif DBPP == 32
|
||||
#define PMAKE(_VAL) (((_VAL&(31<<11))<<8)|((_VAL&(63<<5))<<5)|((_VAL&31)<<3))
|
||||
#endif
|
||||
#define SRCTYPE Bit16u
|
||||
#endif
|
||||
|
||||
#if SBPP == 32
|
||||
#define SC scalerSourceCache.b32
|
||||
#if DBPP == 15
|
||||
#define PMAKE(_VAL) (PTYPE)(((_VAL&(31<<19))>>9)|((_VAL&(31<<11))>>6)|((_VAL&(31<<3))>>3))
|
||||
#elif DBPP == 16
|
||||
#define PMAKE(_VAL) (PTYPE)(((_VAL&(31<<19))>>8)|((_VAL&(63<<10))>>4)|((_VAL&(31<<3))>>3))
|
||||
#elif DBPP == 32
|
||||
#define PMAKE(_VAL) (_VAL)
|
||||
#endif
|
||||
#define SRCTYPE Bit32u
|
||||
#endif
|
||||
|
||||
#define C0 fc[-1 - SCALER_MAXWIDTH -2]
|
||||
#define C1 fc[+0 - SCALER_MAXWIDTH -2]
|
||||
#define C2 fc[+1 - SCALER_MAXWIDTH -2]
|
||||
#define C3 fc[-1 ]
|
||||
#define C4 fc[+0 ]
|
||||
#define C5 fc[+1 ]
|
||||
#define C6 fc[-1 + SCALER_MAXWIDTH +2]
|
||||
#define C7 fc[+0 + SCALER_MAXWIDTH +2]
|
||||
#define C8 fc[+1 + SCALER_MAXWIDTH +2]
|
||||
|
||||
#if defined (CACHEWITHPAL)
|
||||
static void conc3d(CacheComplexPal,SBPP,DBPP) (const void * s) {
|
||||
#else
|
||||
PTYPE * dst=(PTYPE *)Scaler_DstWrite;
|
||||
line=line_cache.b8[0];
|
||||
for (Bitu x=0;x<Scaler_SrcWidth;x++) {
|
||||
PTYPE pixel=PMAKE(src[x]);
|
||||
dst[x]=pixel;LC[0][x]=pixel;
|
||||
}
|
||||
static void conc3d(CacheComplex,SBPP,DBPP) (const void * s) {
|
||||
#endif
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
for (Bitu lines=*Scaler_Index++;lines;lines--) {
|
||||
BituMove(Scaler_DstWrite,line,Scaler_SrcWidth*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
const SRCTYPE * src = (SRCTYPE*)s;
|
||||
PTYPE *fc= &FC[render.scale.inLine+1][1];
|
||||
SRCTYPE *sc= &SC[render.scale.inLine][0];
|
||||
Bitu b;
|
||||
bool hadChange = false;
|
||||
/* This should also copy the surrounding pixels but it looks nice enough without */
|
||||
for (b=0;b<render.scale.blocks;b++) {
|
||||
#if defined (CACHEWITHPAL)
|
||||
for (Bitu x=0;x<SCALER_BLOCKSIZE;x++) {
|
||||
PTYPE pixel = PMAKE(src[x]);
|
||||
if (pixel != fc[x]) {
|
||||
#else
|
||||
for (Bitu x=0;x<SCALER_BLOCKSIZE;x+=sizeof(Bitu)/sizeof(SRCTYPE)) {
|
||||
if (*(Bitu*)&src[x] != *(Bitu*)&sc[x]) {
|
||||
#endif
|
||||
do {
|
||||
fc[x] = PMAKE(src[x]);
|
||||
sc[x] = src[x];
|
||||
x++;
|
||||
} while (x<SCALER_BLOCKSIZE);
|
||||
hadChange = true;
|
||||
/* Change the surrounding blocks */
|
||||
CC[render.scale.inLine+0][1+b-1] |= SCALE_RIGHT;
|
||||
CC[render.scale.inLine+0][1+b+0] |= SCALE_FULL;
|
||||
CC[render.scale.inLine+0][1+b+1] |= SCALE_LEFT;
|
||||
CC[render.scale.inLine+1][1+b-1] |= SCALE_RIGHT;
|
||||
CC[render.scale.inLine+1][1+b+0] |= SCALE_FULL;
|
||||
CC[render.scale.inLine+1][1+b+1] |= SCALE_LEFT;
|
||||
CC[render.scale.inLine+2][1+b-1] |= SCALE_RIGHT;
|
||||
CC[render.scale.inLine+2][1+b+0] |= SCALE_FULL;
|
||||
CC[render.scale.inLine+2][1+b+1] |= SCALE_LEFT;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fc += SCALER_BLOCKSIZE;
|
||||
sc += SCALER_BLOCKSIZE;
|
||||
src += SCALER_BLOCKSIZE;
|
||||
}
|
||||
if (hadChange) {
|
||||
CC[render.scale.inLine+0][0] = 1;
|
||||
CC[render.scale.inLine+1][0] = 1;
|
||||
CC[render.scale.inLine+2][0] = 1;
|
||||
}
|
||||
render.scale.inLine ++;
|
||||
}
|
||||
|
||||
static void conc3d(Normal2x,SBPP,DBPP) (const Bit8u * src) {
|
||||
PTYPE * dst=(PTYPE *)Scaler_DstWrite;
|
||||
for (Bitu x=0;x<Scaler_SrcWidth;x++) {
|
||||
Bitu pixel=PMAKE(src[x]);
|
||||
dst[x*2+0]=dst[x*2+1]=pixel;
|
||||
LC[0][x*2+0]=LC[0][x*2+1]=pixel;
|
||||
}
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
for (Bitu lines=*Scaler_Index++;lines;lines--) {
|
||||
BituMove(Scaler_DstWrite,LC[0],Scaler_SrcWidth*2*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
|
||||
#if defined (CACHEWITHPAL)
|
||||
static void conc3d(CacheSimplePal,SBPP,DBPP) (const void * s) {
|
||||
#else
|
||||
static void conc3d(CacheSimple,SBPP,DBPP) (const void * s) {
|
||||
#endif
|
||||
const SRCTYPE * src = (SRCTYPE*)s;
|
||||
PTYPE *fc= &FC[render.scale.inLine+1][1];
|
||||
SRCTYPE *sc= &SC[render.scale.inLine][0];
|
||||
Bitu b;
|
||||
/* This should also copy the surrounding pixels but it looks nice enough without */
|
||||
for (b=0;b<render.scale.blocks;b++) {
|
||||
#if defined (CACHEWITHPAL)
|
||||
for (Bitu x=0;x<SCALER_BLOCKSIZE;x++) {
|
||||
PTYPE pixel = PMAKE(src[x]);
|
||||
if (pixel != fc[x]) {
|
||||
#else
|
||||
for (Bitu x=0;x<SCALER_BLOCKSIZE;x+=sizeof(Bitu)/sizeof(SRCTYPE)) {
|
||||
if (*(Bitu*)&src[x] != *(Bitu*)&sc[x]) {
|
||||
#endif
|
||||
do {
|
||||
fc[x] = PMAKE(src[x]);
|
||||
sc[x] = src[x];
|
||||
x++;
|
||||
} while (x<SCALER_BLOCKSIZE);
|
||||
CC[render.scale.inLine+1][0] = 1;
|
||||
CC[render.scale.inLine+1][1+b] = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fc += SCALER_BLOCKSIZE;
|
||||
sc += SCALER_BLOCKSIZE;
|
||||
src += SCALER_BLOCKSIZE;
|
||||
}
|
||||
render.scale.inLine ++;
|
||||
}
|
||||
|
||||
|
||||
/* Add all the specific scalers */
|
||||
|
||||
#if (SBPP == DBPP) && !defined (CACHEWITHPAL)
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME Normal
|
||||
#define SCALERWIDTH 1
|
||||
#define SCALERHEIGHT 1
|
||||
#define SCALERFUNC \
|
||||
line0[0] = C4;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME NormalDw
|
||||
#define SCALERWIDTH 2
|
||||
#define SCALERHEIGHT 1
|
||||
#define SCALERFUNC \
|
||||
line0[0] = C4; \
|
||||
line0[1] = C4;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME NormalDh
|
||||
#define SCALERWIDTH 1
|
||||
#define SCALERHEIGHT 2
|
||||
#define SCALERFUNC \
|
||||
line0[0] = C4; \
|
||||
line1[1] = C4;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME Normal2x
|
||||
#define SCALERWIDTH 2
|
||||
#define SCALERHEIGHT 2
|
||||
#define SCALERFUNC \
|
||||
line0[0] = C4; \
|
||||
line0[1] = C4; \
|
||||
line1[0] = C4; \
|
||||
line1[1] = C4;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME Normal3x
|
||||
#define SCALERWIDTH 3
|
||||
#define SCALERHEIGHT 3
|
||||
#define SCALERFUNC \
|
||||
line0[0] = C4; \
|
||||
line0[1] = C4; \
|
||||
line0[2] = C4; \
|
||||
line1[0] = C4; \
|
||||
line1[1] = C4; \
|
||||
line1[2] = C4; \
|
||||
line2[0] = C4; \
|
||||
line2[1] = C4; \
|
||||
line2[2] = C4;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
#if (DBPP > 8)
|
||||
static void conc3d(TV2x,SBPP,DBPP) (const Bit8u * src) {
|
||||
PTYPE * dst=(PTYPE *)Scaler_DstWrite;
|
||||
for (Bitu x=0;x<Scaler_SrcWidth;x++) {
|
||||
Bitu pixel=PMAKE(src[x]);
|
||||
Bitu halfpixel=(((pixel & redblueMask) * 7) >> 3) & redblueMask;
|
||||
halfpixel|=(((pixel & greenMask) * 7) >> 3) & greenMask;
|
||||
dst[x*2+0]=dst[x*2+1]=halfpixel;
|
||||
LC[0][x*2+0]=LC[0][x*2+1]=pixel;
|
||||
}
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
for (Bitu lines=*Scaler_Index++;lines;lines--) {
|
||||
BituMove(Scaler_DstWrite,LC[0],Scaler_SrcWidth*2*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
}
|
||||
}
|
||||
|
||||
static void conc3d(Interp2x,SBPP,DBPP) (const Bit8u * src) {
|
||||
if (!Scaler_Line) {
|
||||
Scaler_Line++;
|
||||
for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) {
|
||||
LC[1][tempx] = LC[2][tempx] = PMAKE(src[tempx]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
lastagain:
|
||||
Bitu x=0;
|
||||
PTYPE * dst=(PTYPE *)Scaler_DstWrite;
|
||||
C1=C4;C4=C7;C7=PMAKE(src[x]);
|
||||
C2=C5;C5=C8;C8=PMAKE(src[x+1]);
|
||||
dst[0] = interp_w2(C4,C1,3,1);
|
||||
dst[1] = interp_w4(C4,C1,C2,C5,5,1,1,1);
|
||||
WC[1][0] = interp_w2(C4,C7,3,1);
|
||||
WC[1][1] = interp_w4(C4,C5,C8,C7,5,1,1,1);
|
||||
for (x=1;x<Scaler_SrcWidth-1;x++) {
|
||||
C2=C5;C5=C8;C8=PMAKE(src[x+1]);
|
||||
dst[x*2+0] = interp_w4(C4,C3,C0,C1,5,1,1,1);
|
||||
dst[x*2+1] = interp_w4(C4,C1,C2,C5,5,1,1,1);
|
||||
WC[1][x*2+0] = interp_w4(C4,C7,C6,C3,5,1,1,1);
|
||||
WC[1][x*2+1] = interp_w4(C4,C5,C8,C7,5,1,1,1);
|
||||
}
|
||||
dst[x*2] = interp_w4(C4,C3,C0,C1,5,1,1,1);
|
||||
dst[x*2+1] = interp_w2(C4,C1,3,1);
|
||||
WC[1][x*2+0] = interp_w4(C4,C7,C6,C3,5,1,1,1);
|
||||
WC[1][x*2+1] = interp_w2(C4,C7,3,1);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
for (Bitu lines=*Scaler_Index++;lines;lines--) {
|
||||
BituMove(Scaler_DstWrite,&WC[1],Scaler_SrcWidth*2*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
}
|
||||
if (++Scaler_Line==Scaler_SrcHeight) goto lastagain;
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME TV2x
|
||||
#define SCALERWIDTH 2
|
||||
#define SCALERHEIGHT 2
|
||||
#define SCALERFUNC \
|
||||
{ \
|
||||
Bitu halfpixel=(((C4 & redblueMask) * 5) >> 3) & redblueMask; \
|
||||
halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \
|
||||
line0[0]=C4; \
|
||||
line0[1]=C4; \
|
||||
line1[0]=halfpixel; \
|
||||
line1[1]=halfpixel; \
|
||||
}
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
static void conc3d(AdvInterp2x,SBPP,DBPP) (const Bit8u * src) {
|
||||
if (!Scaler_Line) {
|
||||
Scaler_Line++;
|
||||
for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) {
|
||||
LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
lastagain:
|
||||
Bitu x=0;
|
||||
PTYPE * dst=(PTYPE *)Scaler_DstWrite;
|
||||
C1=C4;C4=C7;C7=PMAKE(src[x]);
|
||||
C2=C5;C5=C8;C8=PMAKE(src[x+1]);
|
||||
dst[0]=C4;
|
||||
WC[1][0]=C4;
|
||||
dst[1] = C5 == C1 && C7 != C1 ? C2 : C4;
|
||||
WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4;
|
||||
for (x=1;x<Scaler_SrcWidth-1;x++) {
|
||||
C2=C5;C5=C8;C8=PMAKE(src[x+1]);
|
||||
if (C1 != C7 && C3 != C5) {
|
||||
dst[x*2+0] = C3 == C1 ? interp_w2(C3,C4,5,3) : C4;
|
||||
dst[x*2+1] = C1 == C5 ? interp_w2(C5,C4,5,3) : C4;
|
||||
WC[1][x*2+0] = C3 == C7 ? interp_w2(C3,C4,5,3) : C4;
|
||||
WC[1][x*2+1] = C7 == C5 ? interp_w2(C5,C4,5,3) : C4;
|
||||
} else {
|
||||
dst[x*2+0] = dst[x*2+1] =
|
||||
WC[1][x*2+0] = WC[1][x*2+1]= C4;
|
||||
}
|
||||
}
|
||||
x=Scaler_SrcWidth-1;
|
||||
dst[x*2] = (C3 == C1 && C7 != C1) ? C1 : C4;
|
||||
WC[1][x*2+0] = (C3 == C7 && C1 != C7) ? C7 : C4;
|
||||
dst[x*2+1] = C4;
|
||||
WC[1][x*2+1] = C4;
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
for (Bitu lines=*Scaler_Index++;lines>0;lines--) {
|
||||
BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
}
|
||||
if (++Scaler_Line==Scaler_SrcHeight) goto lastagain;
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME TV3x
|
||||
#define SCALERWIDTH 3
|
||||
#define SCALERHEIGHT 3
|
||||
#define SCALERFUNC \
|
||||
{ \
|
||||
Bitu halfpixel=(((C4 & redblueMask) * 5) >> 3) & redblueMask; \
|
||||
halfpixel|=(((C4 & greenMask) * 5) >> 3) & greenMask; \
|
||||
line0[0]=C4; \
|
||||
line0[1]=C4; \
|
||||
line0[2]=C4; \
|
||||
line1[0]=halfpixel; \
|
||||
line1[1]=halfpixel; \
|
||||
line1[2]=halfpixel; \
|
||||
halfpixel=(((C4 & redblueMask) * 5) >> 4) & redblueMask; \
|
||||
halfpixel|=(((C4 & greenMask) * 5) >> 4) & greenMask; \
|
||||
line2[0]=halfpixel; \
|
||||
line2[1]=halfpixel; \
|
||||
line2[2]=halfpixel; \
|
||||
}
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME RGB2x
|
||||
#define SCALERWIDTH 2
|
||||
#define SCALERHEIGHT 2
|
||||
#define SCALERFUNC \
|
||||
line0[0]=C4 & redMask; \
|
||||
line0[1]=C4 & greenMask; \
|
||||
line1[0]=C4 & blueMask; \
|
||||
line1[1]=C4;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME RGB3x
|
||||
#define SCALERWIDTH 3
|
||||
#define SCALERHEIGHT 3
|
||||
#define SCALERFUNC \
|
||||
line0[0]=C4; \
|
||||
line0[1]=C4 & greenMask; \
|
||||
line0[2]=C4 & blueMask; \
|
||||
line1[0]=C4 & blueMask; \
|
||||
line1[1]=C4; \
|
||||
line1[2]=C4 & redMask; \
|
||||
line2[0]=C4 & redMask; \
|
||||
line2[1]=C4 & greenMask; \
|
||||
line2[2]=C4;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME Scan2x
|
||||
#define SCALERWIDTH 2
|
||||
#define SCALERHEIGHT 2
|
||||
#define SCALERFUNC \
|
||||
line0[0]=C4; \
|
||||
line0[1]=C4; \
|
||||
line1[0]=0; \
|
||||
line1[1]=0;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
|
||||
#define SCALERSIMPLE 1
|
||||
#define SCALERNAME Scan3x
|
||||
#define SCALERWIDTH 3
|
||||
#define SCALERHEIGHT 3
|
||||
#define SCALERFUNC \
|
||||
line0[0]=C4; \
|
||||
line0[1]=C4; \
|
||||
line0[2]=C4; \
|
||||
line1[0]=0; \
|
||||
line1[1]=0; \
|
||||
line1[2]=0; \
|
||||
line2[0]=0; \
|
||||
line2[1]=0; \
|
||||
line2[2]=0;
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
#undef SCALERSIMPLE
|
||||
|
||||
|
||||
|
||||
#define SCALERNAME AdvInterp2x
|
||||
#define SCALERWIDTH 2
|
||||
#define SCALERHEIGHT 2
|
||||
#define SCALERFUNC \
|
||||
if (C1 != C7 && C3 != C5) { \
|
||||
line0[0] = C3 == C1 ? interp_w2(C3,C4,5,3) : C4; \
|
||||
line0[1] = C1 == C5 ? interp_w2(C5,C4,5,3) : C4; \
|
||||
line1[0] = C3 == C7 ? interp_w2(C3,C4,5,3) : C4; \
|
||||
line1[1] = C7 == C5 ? interp_w2(C5,C4,5,3) : C4; \
|
||||
} else { \
|
||||
line0[0] = line0[1] = C4; \
|
||||
line1[0] = line1[1] = C4; \
|
||||
}
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
|
||||
#define SCALERNAME AdvInterp3x
|
||||
#define SCALERWIDTH 3
|
||||
#define SCALERHEIGHT 3
|
||||
#define SCALERFUNC \
|
||||
if (C1 != C7 && C3 != C5) { \
|
||||
line0[0] = C3 == C1 ? interp_w2(C3,C4,5,3) : C4; \
|
||||
line0[1] = C1 == C5 ? interp_w2(C5,C4,5,3) : C4; \
|
||||
line1[0] = C3 == C7 ? interp_w2(C3,C4,5,3) : C4; \
|
||||
line1[1] = C7 == C5 ? interp_w2(C5,C4,5,3) : C4; \
|
||||
} else { \
|
||||
line0[0] = line0[1] = C4; \
|
||||
line1[0] = line1[1] = C4; \
|
||||
}
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
|
||||
#endif //DBPP > 8
|
||||
|
||||
static void conc3d(AdvMame2x,SBPP,DBPP) (const Bit8u * src) {
|
||||
if (!Scaler_Line) {
|
||||
Scaler_Line++;
|
||||
for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) {
|
||||
LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]);
|
||||
}
|
||||
return;
|
||||
#define SCALERNAME AdvMame2x
|
||||
#define SCALERWIDTH 2
|
||||
#define SCALERHEIGHT 2
|
||||
#define SCALERFUNC \
|
||||
if (C1 != C7 && C3 != C5) { \
|
||||
line0[0] = C3 == C1 ? C3 : C4; \
|
||||
line0[1] = C1 == C5 ? C5 : C4; \
|
||||
line1[0] = C3 == C7 ? C3 : C4; \
|
||||
line1[1] = C7 == C5 ? C5 : C4; \
|
||||
} else { \
|
||||
line0[0] = line0[1] = C4; \
|
||||
line1[0] = line1[1] = C4; \
|
||||
}
|
||||
lastagain:
|
||||
Bitu x=0;
|
||||
PTYPE * dst=(PTYPE *)Scaler_DstWrite;
|
||||
C1=C4;C4=C7;C7=PMAKE(src[x]);
|
||||
C2=C5;C5=C8;C8=PMAKE(src[x+1]);
|
||||
dst[0]=C4;
|
||||
WC[1][0]=C4;
|
||||
dst[1] = C5 == C1 && C7 != C1 ? C2 : C4;
|
||||
WC[1][1]= C5 == C7 && C1 != C7 ? C7 : C4;
|
||||
for (x=1;x<Scaler_SrcWidth-1;x++) {
|
||||
C2=C5;C5=C8;C8=PMAKE(src[x+1]);
|
||||
if (C1 != C7 && C3 != C5) {
|
||||
dst[x*2+0] = C3 == C1 ? C3 : C4;
|
||||
dst[x*2+1] = C1 == C5 ? C5 : C4;
|
||||
WC[1][x*2+0] = C3 == C7 ? C3 : C4;
|
||||
WC[1][x*2+1] = C7 == C5 ? C5 : C4;
|
||||
} else {
|
||||
dst[x*2+0] = dst[x*2+1] =
|
||||
WC[1][x*2+0] = WC[1][x*2+1]= C4;
|
||||
}
|
||||
}
|
||||
x=Scaler_SrcWidth-1;
|
||||
dst[x*2] = (C3 == C1 && C7 != C1) ? C1 : C4;
|
||||
WC[1][x*2+0] = (C3 == C7 && C1 != C7) ? C7 : C4;
|
||||
dst[x*2+1] = C4;
|
||||
WC[1][x*2+1] = C4;
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
for (Bitu lines=*Scaler_Index++;lines>0;lines--) {
|
||||
BituMove(Scaler_DstWrite,&WC[1],2*Scaler_SrcWidth*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
}
|
||||
if (++Scaler_Line==Scaler_SrcHeight) goto lastagain;
|
||||
}
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
|
||||
static void conc3d(AdvMame3x,SBPP,DBPP) (const Bit8u * src) {
|
||||
if (!Scaler_Line) {
|
||||
Scaler_Line++;
|
||||
for (Bitu tempx=Scaler_SrcWidth;tempx>0;tempx--) {
|
||||
LC[1][tempx]=LC[2][tempx]=PMAKE(src[tempx]);
|
||||
}
|
||||
return;
|
||||
#define SCALERNAME AdvMame3x
|
||||
#define SCALERWIDTH 3
|
||||
#define SCALERHEIGHT 3
|
||||
#define SCALERFUNC \
|
||||
if ((C1 != C7) && (C3 != C5)) { \
|
||||
line0[0] = C3 == C1 ? C3 : C4; \
|
||||
line0[1] = (C3 == C1 && C4 != C2) || (C5 == C1 && C4 != C0) ? C1 : C4; \
|
||||
line0[2] = C5 == C1 ? C5 : C4; \
|
||||
line1[0] = (C3 == C1 && C4 != C6) || (C3 == C7 && C4 != C0) ? C3 : C4; \
|
||||
line1[1] = C4; \
|
||||
line1[2] = (C5 == C1 && C4 != C8) || (C5 == C7 && C4 != C2) ? C5 : C4; \
|
||||
line2[0] = C3 == C7 ? C3 : C4; \
|
||||
line2[1] = (C3 == C7 && C4 != C8) || (C5 == C7 && C4 != C6) ? C7 : C4; \
|
||||
line2[2] = C5 == C7 ? C5 : C4; \
|
||||
} else { \
|
||||
line0[0] = line0[1] = line0[2] = C4; \
|
||||
line1[0] = line1[1] = line1[2] = C4; \
|
||||
line2[0] = line2[1] = line2[2] = C4; \
|
||||
}
|
||||
lastagain:
|
||||
PTYPE * dst=(PTYPE *)Scaler_DstWrite;
|
||||
LC[0][0]=LC[1][0];LC[1][0]=LC[2][0];LC[2][0]=PMAKE(src[0]);
|
||||
LC[0][1]=LC[1][1];LC[1][1]=LC[2][1];LC[2][1]=PMAKE(src[1]);
|
||||
/* first pixel */
|
||||
dst[0] = LC[1][0];
|
||||
dst[1] = LC[1][0];
|
||||
dst[2] = (LC[1][1] == LC[0][0] && LC[2][0] != LC[0][0]) ? LC[0][0] : LC[1][0];
|
||||
WC[1][0] = LC[1][0];
|
||||
WC[1][1] = LC[1][0];
|
||||
WC[1][2] = (LC[0][0] != LC[2][0]) ? (((LC[1][1] == LC[0][0] && LC[1][0] != LC[2][1]) || (LC[1][1] == LC[2][0] && LC[1][0] != LC[0][1])) ? LC[1][1] : LC[1][0]) : LC[1][0];
|
||||
WC[2][0] = LC[1][0];
|
||||
WC[2][1] = LC[1][0];
|
||||
WC[2][2] = (LC[1][1] == LC[2][0] && LC[0][0] != LC[2][0]) ? LC[2][0] : LC[1][0];
|
||||
Bitu x;
|
||||
for (x=1;x<Scaler_SrcWidth-1;x++) {
|
||||
C2=C5;C5=C8;C8=PMAKE(src[x+1]);
|
||||
if ((C1 != C7) && (C3 != C5)) {
|
||||
dst[x*3+0] = C3 == C1 ? C3 : C4;
|
||||
dst[x*3+1] = (C3 == C1 && C4 != C2) || (C5 == C1 && C4 != C0) ? C1 : C4;
|
||||
dst[x*3+2] = C5 == C1 ? C5 : C4;
|
||||
WC[1][x*3+0] = (C3 == C1 && C4 != C6) || (C3 == C7 && C4 != C0) ? C3 : C4;
|
||||
WC[1][x*3+1] = C4;
|
||||
WC[1][x*3+2] = (C5 == C1 && C4 != C8) || (C5 == C7 && C4 != C2) ? C5 : C4;
|
||||
WC[2][x*3+0] = C3 == C7 ? C3 : C4;
|
||||
WC[2][x*3+1] = (C3 == C7 && C4 != C8) || (C5 == C7 && C4 != C6) ? C7 : C4;
|
||||
WC[2][x*3+2] = C5 == C7 ? C5 : C4;
|
||||
} else {
|
||||
dst[x*3+0] = dst[x*3+1] = dst[x*3+2] =
|
||||
WC[1][x*3+0] = WC[1][x*3+1] = WC[1][x*3+2] =
|
||||
WC[2][x*3+0] = WC[2][x*3+1] = WC[2][x*3+2] = LC[1][x];
|
||||
}
|
||||
}
|
||||
x=Scaler_SrcWidth-1;
|
||||
/* last pixel */
|
||||
dst[x*3+0] = (C3 == C1 && C7 != C1) ? C1 : C4;
|
||||
dst[x*3+1] = C4;
|
||||
dst[x*3+2] = C4;
|
||||
WC[1][x*3+0] = (C1 != C7) ? ((C3 == C1 && C4 != C6) || (C3 == C7 && C4 != C0) ? C3 : C4) : C4;
|
||||
WC[1][x*3+1] = C4;
|
||||
WC[1][x*3+2] = C4;
|
||||
WC[2][x*3+0] = (C3 == C7 && C1 != C7) ? C7 : C4;
|
||||
WC[2][x*3+1] = C4;
|
||||
WC[2][x*3+2] = C4;
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
BituMove(Scaler_DstWrite,&WC[1],3*Scaler_SrcWidth*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
for (Bitu lines=*Scaler_Index++;lines>0;lines--) {
|
||||
BituMove(Scaler_DstWrite,&WC[2],3*Scaler_SrcWidth*PSIZE);
|
||||
Scaler_DstWrite+=Scaler_DstPitch;
|
||||
}
|
||||
if (++Scaler_Line==Scaler_SrcHeight) goto lastagain;
|
||||
}
|
||||
|
||||
#include "render_loops.h"
|
||||
#undef SCALERNAME
|
||||
#undef SCALERWIDTH
|
||||
#undef SCALERHEIGHT
|
||||
#undef SCALERFUNC
|
||||
|
||||
|
||||
#endif // (SBPP == DBPP) && !defined (CACHEWITHPAL)
|
||||
|
||||
#undef PSIZE
|
||||
#undef PTYPE
|
||||
#undef PMAKE
|
||||
#undef WC
|
||||
#undef LC
|
||||
#undef FC
|
||||
#undef SC
|
||||
#undef redMask
|
||||
#undef greenMask
|
||||
#undef blueMask
|
||||
#undef redblueMask
|
||||
#undef SRCTYPE
|
||||
|
||||
|
||||
#if (SBPP == 8) && (DBPP > 8) && !defined (CACHEWITHPAL)
|
||||
#define CACHEWITHPAL 1
|
||||
#include "render_templates.h"
|
||||
#undef CACHEWITHPAL
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: sdlmain.cpp,v 1.95 2006-01-22 14:13:00 qbix79 Exp $ */
|
||||
/* $Id: sdlmain.cpp,v 1.96 2006-01-30 09:58:07 harekiet Exp $ */
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
@ -144,20 +144,25 @@ struct SDL_Block {
|
|||
struct {
|
||||
Bit32u width;
|
||||
Bit32u height;
|
||||
Bit32u bpp;
|
||||
Bitu flags;
|
||||
GFX_Modes mode;
|
||||
double scalex,scaley;
|
||||
GFX_ResetCallBack reset;
|
||||
} draw;
|
||||
bool wait_on_error;
|
||||
struct {
|
||||
Bit32u width,height,bpp;
|
||||
bool fixed;
|
||||
struct {
|
||||
Bit16u width, height;
|
||||
bool fixed;
|
||||
} full;
|
||||
struct {
|
||||
Bit16u width, height;
|
||||
} window;
|
||||
Bit8u bpp;
|
||||
bool fullscreen;
|
||||
bool doublebuf;
|
||||
SCREEN_TYPES type;
|
||||
SCREEN_TYPES want_type;
|
||||
double hwscale;
|
||||
} desktop;
|
||||
#if C_OPENGL
|
||||
struct {
|
||||
|
@ -196,6 +201,7 @@ struct SDL_Block {
|
|||
bool locked;
|
||||
Bitu sensitivity;
|
||||
} mouse;
|
||||
SDL_Rect updateRects[1024];
|
||||
};
|
||||
|
||||
static SDL_Block sdl;
|
||||
|
@ -249,47 +255,51 @@ Bitu GFX_GetBestMode(Bitu flags) {
|
|||
case SCREEN_SURFACE:
|
||||
check_surface:
|
||||
/* Check if we can satisfy the depth it loves */
|
||||
if (flags & LOVE_8) testbpp=8;
|
||||
else if (flags & LOVE_16) testbpp=16;
|
||||
else if (flags & LOVE_32) testbpp=32;
|
||||
if (flags & GFX_LOVE_8) testbpp=8;
|
||||
else if (flags & GFX_LOVE_15) testbpp=15;
|
||||
else if (flags & GFX_LOVE_16) testbpp=16;
|
||||
else if (flags & GFX_LOVE_32) testbpp=32;
|
||||
check_gotbpp:
|
||||
if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE);
|
||||
else gotbpp=sdl.desktop.bpp;
|
||||
/* If we can't get our favorite mode check for another working one */
|
||||
switch (gotbpp) {
|
||||
case 8:
|
||||
if (flags & CAN_8) flags&=~(CAN_16|CAN_32);
|
||||
if (flags & GFX_CAN_8) flags&=~(GFX_CAN_15|GFX_CAN_16|GFX_CAN_32);
|
||||
break;
|
||||
case 15:
|
||||
if (flags & GFX_CAN_15) flags&=~(GFX_CAN_8|GFX_CAN_16|GFX_CAN_32);
|
||||
break;
|
||||
case 16:
|
||||
if (flags & CAN_16) flags&=~(CAN_8|CAN_32);
|
||||
if (flags & GFX_CAN_16) flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_32);
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
if (flags & CAN_32) flags&=~(CAN_8|CAN_16);
|
||||
if (flags & GFX_CAN_32) flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16);
|
||||
break;
|
||||
}
|
||||
/* Not a valid display depth found? Let's just hope sdl provides conversions */
|
||||
flags |= GFX_CAN_RANDOM;
|
||||
break;
|
||||
#if (HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
if (!(flags&(CAN_32|CAN_16))) goto check_surface;
|
||||
if (flags & LOVE_16) testbpp=16;
|
||||
else if (flags & LOVE_32) testbpp=32;
|
||||
if (!(flags&(GFX_CAN_15|GFX_CAN_16|GFX_CAN_32))) goto check_surface;
|
||||
if (flags & GFX_LOVE_15) testbpp=15;
|
||||
else if (flags & GFX_LOVE_16) testbpp=16;
|
||||
else if (flags & GFX_LOVE_32) testbpp=32;
|
||||
else testbpp=0;
|
||||
flags|=HAVE_SCALING;
|
||||
flags|=GFX_SCALING;
|
||||
goto check_gotbpp;
|
||||
#endif
|
||||
case SCREEN_OVERLAY:
|
||||
if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface;
|
||||
flags|=HAVE_SCALING;
|
||||
flags&=~(CAN_8|CAN_16);
|
||||
if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface;
|
||||
flags|=GFX_SCALING;
|
||||
flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16);
|
||||
break;
|
||||
#if C_OPENGL
|
||||
case SCREEN_OPENGL:
|
||||
if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface;
|
||||
flags|=HAVE_SCALING;
|
||||
flags&=~(CAN_8|CAN_16);
|
||||
if (flags & GFX_RGBONLY || !(flags&GFX_CAN_32)) goto check_surface;
|
||||
flags|=GFX_SCALING;
|
||||
flags&=~(GFX_CAN_8|GFX_CAN_15|GFX_CAN_16);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -299,7 +309,7 @@ check_gotbpp:
|
|||
|
||||
void GFX_ResetScreen(void) {
|
||||
GFX_Stop();
|
||||
if (sdl.draw.reset) (sdl.draw.reset)();
|
||||
if (sdl.draw.reset) (sdl.draw.reset)( false );
|
||||
GFX_Start();
|
||||
}
|
||||
|
||||
|
@ -311,86 +321,91 @@ static int int_log2 (int val) {
|
|||
}
|
||||
|
||||
|
||||
static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags,Bit32u bpp) {
|
||||
static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) {
|
||||
Bit16u fixedWidth;
|
||||
Bit16u fixedHeight;
|
||||
|
||||
if (sdl.desktop.fullscreen) {
|
||||
if (sdl.desktop.fixed) {
|
||||
double ratio_w=(double)sdl.desktop.width/(sdl.draw.width*sdl.draw.scalex);
|
||||
double ratio_h=(double)sdl.desktop.height/(sdl.draw.height*sdl.draw.scaley);
|
||||
if ( ratio_w < ratio_h) {
|
||||
sdl.clip.w=(Bit16u)sdl.desktop.width;
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w);
|
||||
} else {
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h);
|
||||
sdl.clip.h=(Bit16u)sdl.desktop.height;
|
||||
}
|
||||
sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2);
|
||||
sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.width,sdl.desktop.height,bpp,SDL_GetError());
|
||||
return sdl.surface;
|
||||
fixedWidth = sdl.desktop.full.fixed ? sdl.desktop.full.width : 0;
|
||||
fixedHeight = sdl.desktop.full.fixed ? sdl.desktop.full.height : 0;
|
||||
sdl_flags |= SDL_FULLSCREEN|SDL_HWSURFACE;
|
||||
} else {
|
||||
fixedWidth = sdl.desktop.window.width;
|
||||
fixedHeight = sdl.desktop.window.height;
|
||||
sdl_flags |= SDL_HWSURFACE;
|
||||
}
|
||||
if (fixedWidth && fixedHeight) {
|
||||
double ratio_w=(double)fixedWidth/(sdl.draw.width*sdl.draw.scalex);
|
||||
double ratio_h=(double)fixedHeight/(sdl.draw.height*sdl.draw.scaley);
|
||||
if ( ratio_w < ratio_h) {
|
||||
sdl.clip.w=fixedWidth;
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w);
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex);
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.clip.w,sdl.clip.h,bpp,SDL_GetError());
|
||||
return sdl.surface;
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h);
|
||||
sdl.clip.h=(Bit16u)fixedHeight;
|
||||
}
|
||||
if (sdl.desktop.fullscreen)
|
||||
sdl.surface = SDL_SetVideoMode(fixedWidth,fixedHeight,bpp,sdl_flags);
|
||||
else
|
||||
sdl.surface = SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags);
|
||||
if (sdl.surface && sdl.surface->flags & SDL_FULLSCREEN) {
|
||||
sdl.clip.x=(Sint16)((sdl.surface->w-sdl.clip.w)/2);
|
||||
sdl.clip.y=(Sint16)((sdl.surface->h-sdl.clip.h)/2);
|
||||
} else {
|
||||
sdl.clip.x = 0;
|
||||
sdl.clip.y = 0;
|
||||
}
|
||||
return sdl.surface;
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*sdl.desktop.hwscale);
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*sdl.desktop.hwscale);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE);
|
||||
#ifdef WIN32
|
||||
if (sdl.surface == NULL) {
|
||||
LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled.");
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
putenv("SDL_VIDEODRIVER=windib");
|
||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE);
|
||||
}
|
||||
#endif
|
||||
if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",sdl.clip.w,sdl.clip.h,bpp,SDL_GetError());
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex);
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags);
|
||||
return sdl.surface;
|
||||
}
|
||||
}
|
||||
|
||||
GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) {
|
||||
if (sdl.updating) GFX_EndUpdate();
|
||||
Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) {
|
||||
if (sdl.updating)
|
||||
GFX_EndUpdate( 0 );
|
||||
|
||||
sdl.draw.width=width;
|
||||
sdl.draw.height=height;
|
||||
sdl.draw.flags=flags;
|
||||
sdl.draw.mode=GFX_NONE;
|
||||
sdl.draw.reset=reset;
|
||||
sdl.draw.scalex=scalex;
|
||||
sdl.draw.scaley=scaley;
|
||||
|
||||
Bitu bpp;
|
||||
Bitu retFlags;
|
||||
switch (sdl.desktop.want_type) {
|
||||
case SCREEN_SURFACE:
|
||||
dosurface:
|
||||
if (flags & CAN_8) bpp=8;
|
||||
if (flags & CAN_16) bpp=16;
|
||||
if (flags & CAN_32) bpp=32;
|
||||
if (flags & GFX_CAN_8) bpp=8;
|
||||
if (flags & GFX_CAN_15) bpp=15;
|
||||
if (flags & GFX_CAN_16) bpp=16;
|
||||
if (flags & GFX_CAN_32) bpp=32;
|
||||
sdl.desktop.type=SCREEN_SURFACE;
|
||||
sdl.clip.w=width;
|
||||
sdl.clip.h=height;
|
||||
if (sdl.desktop.fullscreen) {
|
||||
if (sdl.desktop.fixed) {
|
||||
sdl.clip.x=(Sint16)((sdl.desktop.width-width)/2);
|
||||
sdl.clip.y=(Sint16)((sdl.desktop.height-height)/2);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,
|
||||
SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE);
|
||||
if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.width,sdl.desktop.height,bpp,SDL_GetError());
|
||||
if (sdl.desktop.full.fixed) {
|
||||
sdl.clip.x=(Sint16)((sdl.desktop.full.width-width)/2);
|
||||
sdl.clip.y=(Sint16)((sdl.desktop.full.height-height)/2);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.desktop.full.width,sdl.desktop.full.height,bpp,
|
||||
SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) |
|
||||
(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0) | SDL_HWPALETTE);
|
||||
if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",sdl.desktop.full.width,sdl.desktop.full.height,bpp,SDL_GetError());
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.surface=SDL_SetVideoMode(width,height,bpp,
|
||||
SDL_FULLSCREEN|SDL_HWSURFACE|(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE);
|
||||
if (sdl.surface == NULL) E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError());
|
||||
SDL_FULLSCREEN | ((flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) |
|
||||
(sdl.desktop.doublebuf ? SDL_DOUBLEBUF|SDL_ASYNCBLIT : 0)|SDL_HWPALETTE);
|
||||
if (sdl.surface == NULL)
|
||||
E_Exit("Could not set fullscreen video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError());
|
||||
}
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE);
|
||||
sdl.surface=SDL_SetVideoMode(width,height,bpp,(flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE);
|
||||
#ifdef WIN32
|
||||
if (sdl.surface == NULL) {
|
||||
LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled.");
|
||||
|
@ -400,21 +415,33 @@ dosurface:
|
|||
sdl.surface = SDL_SetVideoMode(width,height,bpp,SDL_HWSURFACE);
|
||||
}
|
||||
#endif
|
||||
if (sdl.surface == NULL) E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError());
|
||||
if (sdl.surface == NULL)
|
||||
E_Exit("Could not set windowed video mode %ix%i-%i: %s",width,height,bpp,SDL_GetError());
|
||||
}
|
||||
if (sdl.surface) switch (sdl.surface->format->BitsPerPixel) {
|
||||
case 8:sdl.draw.mode=GFX_8;break;
|
||||
case 15:sdl.draw.mode=GFX_15;break;
|
||||
case 16:sdl.draw.mode=GFX_16;break;
|
||||
case 32:sdl.draw.mode=GFX_32;break;
|
||||
default:
|
||||
if (sdl.surface) {
|
||||
switch (sdl.surface->format->BitsPerPixel) {
|
||||
case 8:
|
||||
retFlags = GFX_CAN_8;
|
||||
break;
|
||||
case 15:
|
||||
retFlags = GFX_CAN_15;
|
||||
break;
|
||||
case 16:
|
||||
retFlags = GFX_CAN_16;
|
||||
break;
|
||||
case 32:
|
||||
retFlags = GFX_CAN_32;
|
||||
break;
|
||||
}
|
||||
if (retFlags && sdl.surface->flags & SDL_HWSURFACE)
|
||||
retFlags |= GFX_HARDWARE;
|
||||
}
|
||||
break;
|
||||
#if (HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
if (flags & CAN_16) bpp=16;
|
||||
if (flags & CAN_32) bpp=32;
|
||||
if (flags & GFX_CAN_15) bpp=15;
|
||||
if (flags & GFX_CAN_16) bpp=16;
|
||||
if (flags & GFX_CAN_32) bpp=32;
|
||||
if (sdl.blit.surface) {
|
||||
SDL_FreeSurface(sdl.blit.surface);
|
||||
sdl.blit.surface=0;
|
||||
|
@ -437,11 +464,15 @@ dosurface:
|
|||
goto dosurface;
|
||||
}
|
||||
switch (sdl.surface->format->BitsPerPixel) {
|
||||
case 15:sdl.draw.mode=GFX_15;break;
|
||||
case 16:sdl.draw.mode=GFX_16;break;
|
||||
case 32:sdl.draw.mode=GFX_32;break;
|
||||
default:
|
||||
break;
|
||||
case 15:
|
||||
retFlags = GFX_CAN_15 | GFX_SCALING | GFX_HARDWARE;
|
||||
break;
|
||||
case 16:
|
||||
retFlags = GFX_CAN_16 | GFX_SCALING | GFX_HARDWARE;
|
||||
break;
|
||||
case 32:
|
||||
retFlags = GFX_CAN_32 | GFX_SCALING | GFX_HARDWARE;
|
||||
break;
|
||||
}
|
||||
sdl.desktop.type=SCREEN_SURFACE_DDRAW;
|
||||
break;
|
||||
|
@ -451,7 +482,7 @@ dosurface:
|
|||
SDL_FreeYUVOverlay(sdl.overlay);
|
||||
sdl.overlay=0;
|
||||
}
|
||||
if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface;
|
||||
if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface;
|
||||
if (!GFX_SetupSurfaceScaled(0,0)) goto dosurface;
|
||||
sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface);
|
||||
if (!sdl.overlay) {
|
||||
|
@ -459,7 +490,7 @@ dosurface:
|
|||
goto dosurface;
|
||||
}
|
||||
sdl.desktop.type=SCREEN_OVERLAY;
|
||||
sdl.draw.mode=GFX_32;
|
||||
retFlags = GFX_CAN_32 | GFX_SCALING | GFX_HARDWARE;
|
||||
break;
|
||||
#if C_OPENGL
|
||||
case SCREEN_OPENGL:
|
||||
|
@ -472,7 +503,7 @@ dosurface:
|
|||
free(sdl.opengl.framebuf);
|
||||
}
|
||||
sdl.opengl.framebuf=0;
|
||||
if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface;
|
||||
if (!(flags&GFX_CAN_32) || (flags & GFX_RGBONLY)) goto dosurface;
|
||||
int texsize=2 << int_log2(width > height ? width : height);
|
||||
if (texsize>sdl.opengl.max_texsize) {
|
||||
LOG_MSG("SDL:OPENGL:No support for texturesize of %d, falling back to surface",texsize);
|
||||
|
@ -546,13 +577,18 @@ dosurface:
|
|||
glEnd();
|
||||
glEndList();
|
||||
sdl.desktop.type=SCREEN_OPENGL;
|
||||
sdl.draw.mode=GFX_32;
|
||||
break;
|
||||
retFlags = GFX_CAN_32 | GFX_SCALING;
|
||||
#if defined(NVIDIA_PixelDataRange)
|
||||
if (sdl.opengl.pixel_data_range)
|
||||
retFlags |= GFX_HARDWARE;
|
||||
#endif
|
||||
break;
|
||||
}//OPENGL
|
||||
#endif //C_OPENGL
|
||||
}//CASE
|
||||
if (sdl.draw.mode!=GFX_NONE) GFX_Start();
|
||||
return sdl.draw.mode;
|
||||
if (retFlags)
|
||||
GFX_Start();
|
||||
return retFlags;
|
||||
}
|
||||
|
||||
bool mouselocked; //Global variable for mapper
|
||||
|
@ -629,7 +665,8 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void GFX_EndUpdate(void) {
|
||||
|
||||
void GFX_EndUpdate( const Bit16u *changedLines ) {
|
||||
int ret;
|
||||
if (!sdl.updating) return;
|
||||
sdl.updating=false;
|
||||
|
@ -637,8 +674,27 @@ void GFX_EndUpdate(void) {
|
|||
case SCREEN_SURFACE:
|
||||
if (SDL_MUSTLOCK(sdl.surface)) {
|
||||
SDL_UnlockSurface(sdl.surface);
|
||||
SDL_Flip(sdl.surface);
|
||||
} else if (changedLines) {
|
||||
Bitu y = 0, index = 0, rectCount = 0;
|
||||
while (y < sdl.draw.height) {
|
||||
if (!(index & 1)) {
|
||||
y += changedLines[index];
|
||||
} else {
|
||||
SDL_Rect *rect = &sdl.updateRects[rectCount++];
|
||||
rect->x = sdl.clip.x;
|
||||
rect->y = sdl.clip.y + y;
|
||||
rect->w = (Bit16u)sdl.draw.width;
|
||||
rect->h = changedLines[index];
|
||||
y += changedLines[index];
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (rectCount)
|
||||
SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects );
|
||||
} else {
|
||||
SDL_Flip(sdl.surface);
|
||||
}
|
||||
SDL_Flip(sdl.surface);
|
||||
break;
|
||||
#if (HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
|
@ -668,12 +724,35 @@ void GFX_EndUpdate(void) {
|
|||
break;
|
||||
#if C_OPENGL
|
||||
case SCREEN_OPENGL:
|
||||
glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
||||
sdl.draw.width, sdl.draw.height, GL_BGRA_EXT,
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf);
|
||||
glCallList(sdl.opengl.displaylist);
|
||||
SDL_GL_SwapBuffers();
|
||||
#if defined(NVIDIA_PixelDataRange)
|
||||
if (sdl.opengl.pixel_data_range) {
|
||||
glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
||||
sdl.draw.width, sdl.draw.height, GL_BGRA_EXT,
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV, sdl.opengl.framebuf);
|
||||
glCallList(sdl.opengl.displaylist);
|
||||
SDL_GL_SwapBuffers();
|
||||
} else
|
||||
#endif
|
||||
if (changedLines) {
|
||||
Bitu y = 0, index = 0;
|
||||
glBindTexture(GL_TEXTURE_2D, sdl.opengl.texture);
|
||||
while (y < sdl.draw.height) {
|
||||
if (!(index & 1)) {
|
||||
y += changedLines[index];
|
||||
} else {
|
||||
Bit8u *pixels = (Bit8u *)sdl.opengl.framebuf + y * sdl.opengl.pitch;
|
||||
Bitu height = changedLines[index];
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y,
|
||||
sdl.draw.width, height, GL_BGRA_EXT,
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV, pixels );
|
||||
y += height;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
glCallList(sdl.opengl.displaylist);
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -719,7 +798,8 @@ Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) {
|
|||
}
|
||||
|
||||
void GFX_Stop() {
|
||||
if (sdl.updating) GFX_EndUpdate();
|
||||
if (sdl.updating)
|
||||
GFX_EndUpdate( 0 );
|
||||
sdl.active=false;
|
||||
}
|
||||
|
||||
|
@ -729,6 +809,7 @@ void GFX_Start() {
|
|||
|
||||
static void GUI_ShutDown(Section * sec) {
|
||||
GFX_Stop();
|
||||
if (sdl.draw.reset) (sdl.draw.reset)( true );
|
||||
if (sdl.mouse.locked) CaptureMouse();
|
||||
if (sdl.desktop.fullscreen) SwitchFullScreen();
|
||||
}
|
||||
|
@ -825,44 +906,58 @@ static void GUI_StartUp(Section * sec) {
|
|||
sdl.mouse.locked=false;
|
||||
mouselocked=false; //Global for mapper
|
||||
sdl.mouse.requestlock=false;
|
||||
sdl.desktop.fixed=section->Get_bool("fullfixed");
|
||||
sdl.desktop.full.fixed=section->Get_bool("fullfixed");
|
||||
const char* fullresolution=section->Get_string("fullresolution");
|
||||
if(fullresolution && *fullresolution) {
|
||||
char res[100]= { 0 };
|
||||
strcpy(res,fullresolution);
|
||||
char res[100];
|
||||
strncpy( res, fullresolution, sizeof( res ));
|
||||
fullresolution = lowcase (res);//so x and X are allowed
|
||||
|
||||
char* height = const_cast<char*>(strchr(fullresolution,'x'));
|
||||
if(height && * height) {
|
||||
*height = 0;
|
||||
sdl.desktop.height = atoi(height+1);
|
||||
sdl.desktop.width = atoi(res);
|
||||
sdl.desktop.full.height = atoi(height+1);
|
||||
sdl.desktop.full.width = atoi(res);
|
||||
} else {
|
||||
sdl.desktop.width = 0;
|
||||
sdl.desktop.height = 0;
|
||||
sdl.desktop.full.width = 0;
|
||||
sdl.desktop.full.height = 0;
|
||||
}
|
||||
} else {
|
||||
sdl.desktop.width = 0;
|
||||
sdl.desktop.height = 0;
|
||||
sdl.desktop.full.width = 0;
|
||||
sdl.desktop.full.height = 0;
|
||||
}
|
||||
const char* windowresolution=section->Get_string("windowresolution");
|
||||
if(windowresolution && *windowresolution) {
|
||||
char res[100];
|
||||
strncpy( res,windowresolution, sizeof( res ));
|
||||
windowresolution = lowcase (res);//so x and X are allowed
|
||||
|
||||
char* height = const_cast<char*>(strchr(windowresolution,'x'));
|
||||
if(height && *height) {
|
||||
*height = 0;
|
||||
sdl.desktop.window.height = atoi(height+1);
|
||||
sdl.desktop.window.width = atoi(res);
|
||||
} else {
|
||||
sdl.desktop.window.width = 0;
|
||||
sdl.desktop.window.height = 0;
|
||||
}
|
||||
} else {
|
||||
sdl.desktop.window.width = 0;
|
||||
sdl.desktop.window.height = 0;
|
||||
}
|
||||
sdl.desktop.doublebuf=section->Get_bool("fulldouble");
|
||||
sdl.desktop.hwscale=section->Get_float("hwscale");
|
||||
if (sdl.desktop.hwscale<0.1f) {
|
||||
LOG_MSG("SDL:Can't hwscale lower than 0.1");
|
||||
sdl.desktop.hwscale=0.1f;
|
||||
}
|
||||
if (!sdl.desktop.width) {
|
||||
if (!sdl.desktop.full.width) {
|
||||
#ifdef WIN32
|
||||
sdl.desktop.width=GetSystemMetrics(SM_CXSCREEN);
|
||||
sdl.desktop.full.width=GetSystemMetrics(SM_CXSCREEN);
|
||||
#else
|
||||
sdl.desktop.width=1024;
|
||||
sdl.desktop.full.width=1024;
|
||||
#endif
|
||||
}
|
||||
if (!sdl.desktop.height) {
|
||||
if (!sdl.desktop.full.height) {
|
||||
#ifdef WIN32
|
||||
sdl.desktop.height=GetSystemMetrics(SM_CYSCREEN);
|
||||
sdl.desktop.full.height=GetSystemMetrics(SM_CYSCREEN);
|
||||
#else
|
||||
sdl.desktop.height=768;
|
||||
sdl.desktop.full.height=768;
|
||||
#endif
|
||||
}
|
||||
sdl.mouse.autoenable=section->Get_bool("autolock");
|
||||
|
@ -914,6 +1009,7 @@ static void GUI_StartUp(Section * sec) {
|
|||
#if defined(NVIDIA_PixelDataRange)
|
||||
sdl.opengl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") >0 ) &&
|
||||
glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV;
|
||||
sdl.opengl.pixel_data_range = 0;
|
||||
#endif
|
||||
} else {
|
||||
sdl.opengl.packed_pixel=sdl.opengl.paletted_texture=false;
|
||||
|
@ -1018,6 +1114,7 @@ void GFX_Events() {
|
|||
CaptureMouse();
|
||||
}
|
||||
SetPriority(sdl.priority.nofocus);
|
||||
MAPPER_LosingFocus();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1112,9 +1209,9 @@ int main(int argc, char* argv[]) {
|
|||
#endif
|
||||
|
||||
if ( SDL_Init( SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM
|
||||
|SDL_INIT_NOPARACHUTE
|
||||
#ifndef DISABLE_JOYSTICK
|
||||
|SDL_INIT_JOYSTICK
|
||||
|
||||
#endif
|
||||
) < 0 ) E_Exit("Can't init SDL %s",SDL_GetError());
|
||||
Section_prop * sdl_sec=control->AddSection_prop("sdl",&GUI_StartUp);
|
||||
|
@ -1123,8 +1220,8 @@ int main(int argc, char* argv[]) {
|
|||
sdl_sec->Add_bool("fulldouble",false);
|
||||
sdl_sec->Add_bool("fullfixed",false);
|
||||
sdl_sec->Add_string("fullresolution","1024x768");
|
||||
sdl_sec->Add_string("windowresolution","0x0");
|
||||
sdl_sec->Add_string("output","surface");
|
||||
sdl_sec->Add_float("hwscale",1.0);
|
||||
sdl_sec->Add_bool("autolock",true);
|
||||
sdl_sec->Add_int("sensitivity",100);
|
||||
sdl_sec->Add_bool("waitonerror",true);
|
||||
|
|
Loading…
Add table
Reference in a new issue