add simple advmame2x cpu scaling
This commit is contained in:
parent
8ad0f536d6
commit
96f0360d29
4 changed files with 115 additions and 46 deletions
src
|
@ -209,11 +209,13 @@ struct EventCallback {
|
|||
#define AMASK 0x000000ff
|
||||
#endif
|
||||
|
||||
extern void* NullScaler(SDL_Surface *pixels);
|
||||
extern void* Epx_Scale2x_AdvMame2x_Scaler(SDL_Surface *pixels);
|
||||
|
||||
class CVideo
|
||||
{
|
||||
public:
|
||||
CVideo() : Width(0), Height(0), WindowWidth(0), WindowHeight(0), Depth(0), FullScreen(false) {}
|
||||
CVideo() : Width(0), Height(0), WindowWidth(0), WindowHeight(0), Depth(0), Scale(1), Scaler(NullScaler), FullScreen(false) {}
|
||||
|
||||
void LockScreen();
|
||||
void UnlockScreen();
|
||||
|
@ -290,6 +292,8 @@ public:
|
|||
int WindowHeight;
|
||||
SDL_Cursor *blankCursor;
|
||||
int Depth;
|
||||
int Scale;
|
||||
void* (*Scaler)(SDL_Surface* pixels);
|
||||
bool FullScreen;
|
||||
};
|
||||
|
||||
|
|
|
@ -451,7 +451,9 @@ static void Usage()
|
|||
"\t-S speed\tSync speed (100 = 30 frames/s)\n"
|
||||
"\t-u userpath\tPath where stratagus saves preferences, log and savegame\n"
|
||||
"\t-v mode\t\tVideo mode resolution in format <xres>x<yres>\n"
|
||||
"\t-W\t\tWindowed video mode\n"
|
||||
"\t-W\t\tWindowed video mode. Optionally takes a window size in <xres>x<yres>\n"
|
||||
"\t-x\tPostprocessing. Currently available\n"
|
||||
"\t\tscale2x - Double thei nternal pixel the output using the AdvMAME2x scaler.\n"
|
||||
"map is relative to StratagusLibPath=datapath, use ./map for relative to cwd\n",
|
||||
Parameters::Instance.applicationName.c_str());
|
||||
}
|
||||
|
@ -498,7 +500,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
{
|
||||
char *sep;
|
||||
for (;;) {
|
||||
switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:u:v:Wx:Z:?-")) {
|
||||
switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:u:v:Wx:?-")) {
|
||||
case 'a':
|
||||
EnableAssert = true;
|
||||
continue;
|
||||
|
@ -600,6 +602,12 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
VideoForceFullScreen = 1;
|
||||
Video.FullScreen = 0;
|
||||
continue;
|
||||
case 'x':
|
||||
if (!strcmp(optarg, "scale2x")) {
|
||||
Video.Scale = 2;
|
||||
Video.Scaler = Epx_Scale2x_AdvMame2x_Scaler;
|
||||
}
|
||||
continue;
|
||||
case -1:
|
||||
break;
|
||||
case '?':
|
||||
|
|
|
@ -344,18 +344,8 @@ void InitVideoSdl()
|
|||
exit(1);
|
||||
}
|
||||
if (!TheRenderer) TheRenderer = SDL_CreateRenderer(TheWindow, -1, 0);
|
||||
SDL_RenderSetLogicalSize(TheRenderer, Video.Width, Video.Height);
|
||||
SDL_SetRenderDrawColor(TheRenderer, 0, 0, 0, 255);
|
||||
TheScreen = SDL_CreateRGBSurface(0, Video.Width, Video.Height, 32,
|
||||
0x00FF0000,
|
||||
0x0000FF00,
|
||||
0x000000FF,
|
||||
0); //0xFF000000);
|
||||
Assert(SDL_MUSTLOCK(TheScreen) == 0);
|
||||
TheTexture = SDL_CreateTexture(TheRenderer,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
Video.Width, Video.Height);
|
||||
Video.ResizeScreen(Video.Width, Video.Height);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
|
||||
|
||||
#if ! defined(USE_WIN32) && ! defined(USE_MAEMO)
|
||||
|
@ -667,7 +657,7 @@ void RealizeVideoMemory()
|
|||
{
|
||||
if (NumRects) {
|
||||
//SDL_UpdateWindowSurfaceRects(TheWindow, Rects, NumRects);
|
||||
SDL_UpdateTexture(TheTexture, NULL, TheScreen->pixels, TheScreen->pitch);
|
||||
SDL_UpdateTexture(TheTexture, NULL, Video.Scaler(TheScreen), TheScreen->pitch * Video.Scale);
|
||||
SDL_RenderClear(TheRenderer);
|
||||
//for (int i = 0; i < NumRects; i++)
|
||||
// SDL_UpdateTexture(TheTexture, &Rects[i], TheScreen->pixels, TheScreen->pitch);
|
||||
|
|
|
@ -266,38 +266,44 @@ void CVideo::ClearScreen()
|
|||
*/
|
||||
bool CVideo::ResizeScreen(int w, int h)
|
||||
{
|
||||
if (VideoValidResolution(w, h)) {
|
||||
Width = w;
|
||||
Height = h;
|
||||
|
||||
if (!(SDL_GetWindowFlags(TheWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP)) {
|
||||
SDL_SetWindowSize(TheWindow, w, h);
|
||||
}
|
||||
SDL_RenderSetLogicalSize(TheRenderer, w, h);
|
||||
|
||||
// new surface
|
||||
Uint32 flags = TheScreen->flags;
|
||||
Uint32 rmask = TheScreen->format->Rmask;
|
||||
Uint32 gmask = TheScreen->format->Gmask;
|
||||
Uint32 bmask = TheScreen->format->Bmask;
|
||||
Uint32 amask = TheScreen->format->Amask;
|
||||
Uint8 bpp = TheScreen->format->BitsPerPixel;
|
||||
SDL_FreeSurface(TheScreen);
|
||||
TheScreen = SDL_CreateRGBSurface(flags, w, h, bpp, rmask, gmask, bmask, amask);
|
||||
Assert(SDL_MUSTLOCK(TheScreen) == 0);
|
||||
|
||||
// new texture
|
||||
Uint32 format;
|
||||
int access, oldW, oldH;
|
||||
SDL_QueryTexture(TheTexture, &format, &access, &oldW, &oldH);
|
||||
SDL_DestroyTexture(TheTexture);
|
||||
TheTexture = SDL_CreateTexture(TheRenderer, format, access, w, h);
|
||||
|
||||
SetClipping(0, 0, w - 1, h - 1);
|
||||
|
||||
return true;
|
||||
if (!(SDL_GetWindowFlags(TheWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
&& Video.Width == Video.WindowWidth
|
||||
&& Video.Height == Video.WindowHeight) {
|
||||
// if initially window was the same size as res, keep it that way
|
||||
SDL_SetWindowSize(TheWindow, w, h);
|
||||
}
|
||||
return false;
|
||||
Width = w;
|
||||
Height = h;
|
||||
|
||||
SDL_RenderSetLogicalSize(TheRenderer, w, h);
|
||||
|
||||
// new surface
|
||||
if (TheScreen) {
|
||||
if (TheScreen->userdata) {
|
||||
free(TheScreen->userdata);
|
||||
}
|
||||
SDL_FreeSurface(TheScreen);
|
||||
}
|
||||
TheScreen = SDL_CreateRGBSurface(0, w, h, 32,
|
||||
0x00ff0000,
|
||||
0x0000ff00,
|
||||
0x000000ff,
|
||||
0); // 0xff000000);
|
||||
Assert(SDL_MUSTLOCK(TheScreen) == 0);
|
||||
TheScreen->userdata = calloc(w * Video.Scale * h * Video.Scale, sizeof(Uint32));
|
||||
|
||||
// new texture
|
||||
if (TheTexture) {
|
||||
SDL_DestroyTexture(TheTexture);
|
||||
}
|
||||
TheTexture = SDL_CreateTexture(TheRenderer,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
w * Video.Scale, h * Video.Scale);
|
||||
|
||||
SetClipping(0, 0, w - 1, h - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -475,4 +481,65 @@ void RestoreColorCyclingSurface()
|
|||
|
||||
#endif
|
||||
|
||||
void* NullScaler(SDL_Surface *s) {
|
||||
return s->pixels;
|
||||
}
|
||||
|
||||
void* Epx_Scale2x_AdvMame2x_Scaler(SDL_Surface *s) {
|
||||
Assert(Video.Scale == 2);
|
||||
Assert(s->format->BitsPerPixel == 32);
|
||||
Assert(Video.Height * Video.Width == s->h * 2 * s->w * 2);
|
||||
|
||||
Uint32 *in = (Uint32*) s->pixels;
|
||||
Uint32 *out = (Uint32*) s->userdata;
|
||||
int inputW = s->w;
|
||||
int outputW = s->w * 2;
|
||||
|
||||
// Just the algo from wikipedia.
|
||||
//
|
||||
// Input +-----+-----+-----+
|
||||
// | | A | |
|
||||
// +-----+-----+-----+
|
||||
// | C | P | B |
|
||||
// +-----+-----+-----+
|
||||
// | | D | |
|
||||
// +-----+-----+-----+
|
||||
// ||
|
||||
// Output +-----+-----+
|
||||
// for P | o1 | o2 |
|
||||
// +-----+-----+
|
||||
// | o3 | o4 |
|
||||
// +-----+-----+
|
||||
Uint32 a, b, c, d, p, o1, o2, o3, o4;
|
||||
for (int y = 1, y2 = 1; y < Video.Height - 1; y++, y2 += 2) {
|
||||
for (int x = 1, x2 = 1; x < Video.Width - 1; x++, x2 += 2) {
|
||||
o1 = o2 = o3 = o4 = p = in[x + y * inputW];
|
||||
a = in[x + (y - 1) * inputW];
|
||||
b = in[x + 1 + y * inputW];
|
||||
c = in[x - 1 + y * inputW];
|
||||
d = in[x + (y + 1) * inputW];
|
||||
if ((c == a) && (c != d) && (a != b)) {
|
||||
o1 = a;
|
||||
}
|
||||
if ((a == b) && (a != c) && (b != d)) {
|
||||
o2 = b;
|
||||
}
|
||||
if ((d == c) && (d != b) && (c != a)) {
|
||||
o3 = c;
|
||||
}
|
||||
if ((b == d) && (b != a) && (d != c)) {
|
||||
o4 = d;
|
||||
}
|
||||
out[x2 + y2 * outputW] = o1;
|
||||
out[x2 + 1 + y2 * outputW] = o2;
|
||||
out[x2 + (y2 + 1) * outputW] = o3;
|
||||
out[x2 + 1 + (y2 + 1) * outputW] = o4;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//@}
|
||||
|
|
Loading…
Add table
Reference in a new issue