Commit 9d436013 authored by alistert's avatar alistert

Separated concepts of the "screen" that is drawn to (now the "canvas"), and...

Separated concepts of the "screen" that is drawn to (now the "canvas"), and the "screen" that is actually displayed. Setting the resolution now works properly with scaling.
parent 7cacfd05
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Part of the OpenJazz project * Part of the OpenJazz project
* *
* *
* Copyright (c) 2005-2009 Alister Thomson * Copyright (c) 2005-2010 Alister Thomson
* *
* OpenJazz is distributed under the terms of * OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0 * the GNU General Public License, version 2.0
...@@ -74,8 +74,7 @@ ClientGame::ClientGame (char *address) { ...@@ -74,8 +74,7 @@ ClientGame::ClientGame (char *address) {
SDL_Delay(T_FRAME); SDL_Delay(T_FRAME);
clearScreen(0); clearScreen(0);
fontmn2->showString("WAITING FOR REPLY", screenW >> 2, fontmn2->showString("WAITING FOR REPLY", canvasW >> 2, (canvasH >> 1) - 16);
(screenH >> 1) - 16);
ret = net->recv(sock, buffer + count, MTL_G_PROPS - count); ret = net->recv(sock, buffer + count, MTL_G_PROPS - count);
...@@ -207,7 +206,7 @@ ClientGame::ClientGame (char *address) { ...@@ -207,7 +206,7 @@ ClientGame::ClientGame (char *address) {
} }
clearScreen(0); clearScreen(0);
fontmn2->showString("JOINING GAME", screenW >> 2, (screenH >> 1) - 16); fontmn2->showString("JOINING GAME", canvasW >> 2, (canvasH >> 1) - 16);
ret = step(0); ret = step(0);
...@@ -267,8 +266,7 @@ int ClientGame::setLevel (char *fileName) { ...@@ -267,8 +266,7 @@ int ClientGame::setLevel (char *fileName) {
SDL_Delay(T_FRAME); SDL_Delay(T_FRAME);
clearScreen(0); clearScreen(0);
fontmn2->showString("WAITING FOR SERVER", screenW >> 2, fontmn2->showString("WAITING FOR SERVER", canvasW >> 2, (canvasH >> 1) - 16);
(screenH >> 1) - 16);
ret = step(0); ret = step(0);
...@@ -286,9 +284,9 @@ int ClientGame::setLevel (char *fileName) { ...@@ -286,9 +284,9 @@ int ClientGame::setLevel (char *fileName) {
SDL_Delay(T_FRAME); SDL_Delay(T_FRAME);
clearScreen(0); clearScreen(0);
fontmn2->showString("downloaded", screenW >> 2, (screenH >> 1) - 16); fontmn2->showString("downloaded", canvasW >> 2, (canvasH >> 1) - 16);
fontmn2->showNumber(file->tell(), (screenW >> 2) + 56, screenH >> 1); fontmn2->showNumber(file->tell(), (canvasW >> 2) + 56, canvasH >> 1);
fontmn2->showString("bytes", (screenW >> 2) + 64, screenH >> 1); fontmn2->showString("bytes", (canvasW >> 2) + 64, canvasH >> 1);
ret = step(0); ret = step(0);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Part of the OpenJazz project * Part of the OpenJazz project
* *
* *
* Copyright (c) 2005-2009 Alister Thomson * Copyright (c) 2005-2010 Alister Thomson
* *
* OpenJazz is distributed under the terms of * OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0 * the GNU General Public License, version 2.0
...@@ -340,10 +340,8 @@ int Font::showString (const char * s, int x, int y) { ...@@ -340,10 +340,8 @@ int Font::showString (const char * s, int x, int y) {
// Determine the character's position on the screen // Determine the character's position on the screen
src.w = w[(int)(map[(int)(s[count])])]; src.w = w[(int)(map[(int)(s[count])])];
if(s[count] == 32) { if(s[count] == 32) src.w >>= 1;
src.w = src.w /2;
}
dst.y = yOffset; dst.y = yOffset;
dst.x = xOffset; dst.x = xOffset;
...@@ -352,8 +350,8 @@ int Font::showString (const char * s, int x, int y) { ...@@ -352,8 +350,8 @@ int Font::showString (const char * s, int x, int y) {
else src.y = 0; else src.y = 0;
// Draw the character to the screen // Draw the character to the screen
SDL_BlitSurface(surface, &src, screen, &dst); SDL_BlitSurface(surface, &src, canvas, &dst);
xOffset += src.w-1; xOffset += src.w-1;
} }
...@@ -379,15 +377,15 @@ void Font::showNumber (int n, int x, int y) { ...@@ -379,15 +377,15 @@ void Font::showNumber (int n, int x, int y) {
if (!n) { if (!n) {
// Determine 0's position on the screen // Determine 0's position on the screen
src.w = w[(int)(map['0'])]; src.w = w[(int)(map[(int)'0'])];
dst.y = y; dst.y = y;
dst.x = x - src.w; dst.x = x - src.w;
// Determine 0's position in the font // Determine 0's position in the font
src.y = map['0'] * h; src.y = map[(int)'0'] * h;
// Draw 0 to the screen // Draw 0 to the screen
SDL_BlitSurface(surface, &src, screen, &dst); SDL_BlitSurface(surface, &src, canvas, &dst);
return; return;
...@@ -412,7 +410,7 @@ void Font::showNumber (int n, int x, int y) { ...@@ -412,7 +410,7 @@ void Font::showNumber (int n, int x, int y) {
src.y = map['0' + (count % 10)] * h; src.y = map['0' + (count % 10)] * h;
// Draw the digit to the screen // Draw the digit to the screen
SDL_BlitSurface(surface, &src, screen, &dst); SDL_BlitSurface(surface, &src, canvas, &dst);
count /= 10; count /= 10;
...@@ -422,15 +420,15 @@ void Font::showNumber (int n, int x, int y) { ...@@ -422,15 +420,15 @@ void Font::showNumber (int n, int x, int y) {
if (n < 0) { if (n < 0) {
// Determine the negative sign's position on the screen // Determine the negative sign's position on the screen
src.w = w[(int)(map['-'])]; src.w = w[(int)(map[(int)'-'])];
dst.y = y; dst.y = y;
dst.x = offset - src.w; dst.x = offset - src.w;
// Determine the negative sign's position on the screen // Determine the negative sign's position on the screen
src.y = map['-'] * h; src.y = map[(int)'-'] * h;
// Draw the negative sign to the screen // Draw the negative sign to the screen
SDL_BlitSurface(surface, &src, screen, &dst); SDL_BlitSurface(surface, &src, canvas, &dst);
} }
......
...@@ -387,8 +387,8 @@ void SkyPaletteEffect::apply (SDL_Color *shownPalette, bool direct, int mspf) { ...@@ -387,8 +387,8 @@ void SkyPaletteEffect::apply (SDL_Color *shownPalette, bool direct, int mspf) {
position = viewY + (viewH << 9) - F4; position = viewY + (viewH << 9) - F4;
if (screenW > 320) y = ((screenH - 1) / 100) + 1; if (canvasW > 320) y = ((canvasH - 1) / 100) + 1;
else y = ((screenH - 34) / 100) + 1; else y = ((canvasH - 34) / 100) + 1;
count = (((position * speed) / y) >> 20) % 255; count = (((position * speed) / y) >> 20) % 255;
......
/*
* This file is part of the Advance project.
*
* Copyright (C) 2002 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#if !HAVE_GETOPT
/* This source is extracted from the DJGPP LIBC library */
#define unconst(var, type) ((type)(var))
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <string.h>
#include <stdio.h>
int opterr = 1, optind = 1, optopt = 0;
char *optarg = 0;
#define BADCH (int)'?'
#define EMSG ""
int getopt(int nargc, char *const nargv[], char *ostr)
{
static const char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
char *p;
if (!*place)
{
if (optind >= nargc || *(place = nargv[optind]) != '-')
{
place = EMSG;
return(EOF);
}
if (place[1] && *++place == '-')
{
++optind;
place = EMSG;
return(EOF);
}
}
if ((optopt = (int)*place++) == (int)':'
|| !(oli = strchr(ostr, optopt)))
{
/*
* if the user didn't specify '-' as an option,
* assume it means EOF.
*/
if (optopt == (int)'-')
return EOF;
if (!*place)
++optind;
if (opterr)
{
if (!(p = strrchr(*nargv, '/')))
p = *nargv;
else
++p;
fprintf(stderr, "%s: illegal option -- %c\n", p, optopt);
}
return BADCH;
}
if (*++oli != ':')
{ /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else
{ /* need an argument */
if (*place) /* no white space */
optarg = unconst(place, char *);
else if (nargc <= ++optind)
{ /* no arg */
place = EMSG;
if (!(p = strrchr(*nargv, '/')))
p = *nargv;
else
++p;
if (opterr)
fprintf(stderr, "%s: option requires an argument -- %c\n", p, optopt);
return BADCH;
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return optopt; /* dump back option letter */
}
#endif
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "pixel.h"
pixel_t pixel_get(int x, int y, const unsigned char* pix, unsigned slice, unsigned pixel, unsigned dx, unsigned dy, int opt_tes)
{
const unsigned char* p;
unsigned i;
pixel_t v;
if (opt_tes) {
if (x < 0)
x += dx;
if (x >= dx)
x -= dx;
if (y < 0)
y += dy;
if (y >= dy)
y -= dy;
} else {
if (x < 0)
x = 0;
if (x >= dx)
x = dx - 1;
if (y < 0)
y = 0;
if (y >= dy)
y = dy - 1;
}
p = pix + (y * slice) + (x * pixel);
v = 0;
for(i=0;i<pixel;++i)
v |= ((pixel_t)p[i]) << (i*8);
return v;
}
void pixel_put(int x, int y, unsigned char* pix, unsigned slice, unsigned pixel, unsigned dx, unsigned dy, pixel_t v)
{
unsigned char* p;
unsigned i;
p = pix + (y * slice) + (x * pixel);
for(i=0;i<pixel;++i) {
p[i] = v >> (i*8);
}
}
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PIXEL_H
#define __PIXEL_H
typedef unsigned long long pixel_t;
pixel_t pixel_get(int x, int y, const unsigned char* pix, unsigned slice, unsigned pixel, unsigned dx, unsigned dy, int opt_tes);
void pixel_put(int x, int y, unsigned char* pix, unsigned slice, unsigned pixel, unsigned dx, unsigned dy, pixel_t v);
#endif
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PORTABLE_H
#define __PORTABLE_H
#if HAVE_CONFIG_H
#include <config.h>
#endif
/* ------------------------------------------------------------------------ */
/* getopt */
#if HAVE_GETOPT_H
#include <getopt.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if !HAVE_GETOPT
int getopt(int argc, char * const *argv, const char *options);
extern char *optarg;
extern int optind, opterr, optopt;
#endif
#endif
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains a C and MMX implementation of the Scale2x effect.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "scale2x.h"
#include <assert.h>
/***************************************************************************/
/* Scale2x C implementation */
/**
* Define the macro USE_SCALE_RANDOMWRITE to enable
* an optimized version which writes memory in random order.
* This version is a little faster if you write in system memory.
* But it's a lot slower if you write in video memory.
* So, enable it only if you are sure to never write directly in video memory.
*/
/* #define USE_SCALE_RANDOMWRITE */
static inline void scale2x_8_def_whole(scale2x_uint8* restrict dst0, scale2x_uint8* restrict dst1, const scale2x_uint8* restrict src0, const scale2x_uint8* restrict src1, const scale2x_uint8* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst0[0] = src1[0] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[0] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 2;
dst1 += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 2;
dst1 += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[0] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[0] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
}
static inline void scale2x_8_def_border(scale2x_uint8* restrict dst, const scale2x_uint8* restrict src0, const scale2x_uint8* restrict src1, const scale2x_uint8* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[0] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
}
static inline void scale2x_8_def_center(scale2x_uint8* restrict dst, const scale2x_uint8* restrict src0, const scale2x_uint8* restrict src1, const scale2x_uint8* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0];
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
}
static inline void scale2x_16_def_whole(scale2x_uint16* restrict dst0, scale2x_uint16* restrict dst1, const scale2x_uint16* restrict src0, const scale2x_uint16* restrict src1, const scale2x_uint16* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst0[0] = src1[0] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[0] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 2;
dst1 += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 2;
dst1 += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[0] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[0] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
}
static inline void scale2x_16_def_border(scale2x_uint16* restrict dst, const scale2x_uint16* restrict src0, const scale2x_uint16* restrict src1, const scale2x_uint16* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[0] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
}
static inline void scale2x_16_def_center(scale2x_uint16* restrict dst, const scale2x_uint16* restrict src0, const scale2x_uint16* restrict src1, const scale2x_uint16* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0];
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
}
static inline void scale2x_32_def_whole(scale2x_uint32* restrict dst0, scale2x_uint32* restrict dst1, const scale2x_uint32* restrict src0, const scale2x_uint32* restrict src1, const scale2x_uint32* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst0[0] = src1[0] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[0] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 2;
dst1 += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 2;
dst1 += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst0[1] = src1[0] == src0[0] ? src0[0] : src1[0];
dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
dst1[1] = src1[0] == src2[0] ? src2[0] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
}
}
static inline void scale2x_32_def_border(scale2x_uint32* restrict dst, const scale2x_uint32* restrict src0, const scale2x_uint32* restrict src1, const scale2x_uint32* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
dst[1] = src1[0] == src0[0] ? src0[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
}
static inline void scale2x_32_def_center(scale2x_uint32* restrict dst, const scale2x_uint32* restrict src0, const scale2x_uint32* restrict src1, const scale2x_uint32* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0];
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
++src0;
++src1;
++src2;
dst += 2;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
}
}
/**
* Scale by a factor of 2 a row of pixels of 8 bits.
* The function is implemented in C.
* The pixels over the left and right borders are assumed of the same color of
* the pixels on the border.
* Note that the implementation is optimized to write data sequentially to
* maximize the bandwidth on video memory.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_8_def_whole(dst0, dst1, src0, src1, src2, count);
#else
scale2x_8_def_border(dst0, src0, src1, src2, count);
scale2x_8_def_border(dst1, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2 a row of pixels of 16 bits.
* This function operates like scale2x_8_def() but for 16 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_16_def_whole(dst0, dst1, src0, src1, src2, count);
#else
scale2x_16_def_border(dst0, src0, src1, src2, count);
scale2x_16_def_border(dst1, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2 a row of pixels of 32 bits.
* This function operates like scale2x_8_def() but for 32 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_32_def_whole(dst0, dst1, src0, src1, src2, count);
#else
scale2x_32_def_border(dst0, src0, src1, src2, count);
scale2x_32_def_border(dst1, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2x3 a row of pixels of 8 bits.
* \note Like scale2x_8_def();
*/
void scale2x3_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_8_def_whole(dst0, dst2, src0, src1, src2, count);
scale2x_8_def_center(dst1, src0, src1, src2, count);
#else
scale2x_8_def_border(dst0, src0, src1, src2, count);
scale2x_8_def_center(dst1, src0, src1, src2, count);
scale2x_8_def_border(dst2, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2x3 a row of pixels of 16 bits.
* \note Like scale2x_16_def();
*/
void scale2x3_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_16_def_whole(dst0, dst2, src0, src1, src2, count);
scale2x_16_def_center(dst1, src0, src1, src2, count);
#else
scale2x_16_def_border(dst0, src0, src1, src2, count);
scale2x_16_def_center(dst1, src0, src1, src2, count);
scale2x_16_def_border(dst2, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2x3 a row of pixels of 32 bits.
* \note Like scale2x_32_def();
*/
void scale2x3_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_32_def_whole(dst0, dst2, src0, src1, src2, count);
scale2x_32_def_center(dst1, src0, src1, src2, count);
#else
scale2x_32_def_border(dst0, src0, src1, src2, count);
scale2x_32_def_center(dst1, src0, src1, src2, count);
scale2x_32_def_border(dst2, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2x4 a row of pixels of 8 bits.
* \note Like scale2x_8_def();
*/
void scale2x4_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_8_def_whole(dst0, dst3, src0, src1, src2, count);
scale2x_8_def_center(dst1, src0, src1, src2, count);
scale2x_8_def_center(dst2, src0, src1, src2, count);
#else
scale2x_8_def_border(dst0, src0, src1, src2, count);
scale2x_8_def_center(dst1, src0, src1, src2, count);
scale2x_8_def_center(dst2, src0, src1, src2, count);
scale2x_8_def_border(dst3, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2x4 a row of pixels of 16 bits.
* \note Like scale2x_16_def();
*/
void scale2x4_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_16_def_whole(dst0, dst3, src0, src1, src2, count);
scale2x_16_def_center(dst1, src0, src1, src2, count);
scale2x_16_def_center(dst2, src0, src1, src2, count);
#else
scale2x_16_def_border(dst0, src0, src1, src2, count);
scale2x_16_def_center(dst1, src0, src1, src2, count);
scale2x_16_def_center(dst2, src0, src1, src2, count);
scale2x_16_def_border(dst3, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 2x4 a row of pixels of 32 bits.
* \note Like scale2x_32_def();
*/
void scale2x4_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale2x_32_def_whole(dst0, dst3, src0, src1, src2, count);
scale2x_32_def_center(dst1, src0, src1, src2, count);
scale2x_32_def_center(dst2, src0, src1, src2, count);
#else
scale2x_32_def_border(dst0, src0, src1, src2, count);
scale2x_32_def_center(dst1, src0, src1, src2, count);
scale2x_32_def_center(dst2, src0, src1, src2, count);
scale2x_32_def_border(dst3, src2, src1, src0, count);
#endif
}
/***************************************************************************/
/* Scale2x MMX implementation */
#if defined(__GNUC__) && defined(__i386__)
/*
* Apply the Scale2x effect at a single row.
* This function must be called only by the other scale2x functions.
*
* Considering the pixel map :
*
* ABC (src0)
* DEF (src1)
* GHI (src2)
*
* this functions compute 2 new pixels in substitution of the source pixel E
* like this map :
*
* ab (dst)
*
* with these variables :
*
* &current -> E
* &current_left -> D
* &current_right -> F
* &current_upper -> B
* &current_lower -> H
*
* %0 -> current_upper
* %1 -> current
* %2 -> current_lower
* %3 -> dst
* %4 -> counter
*
* %mm0 -> *current_left
* %mm1 -> *current_next
* %mm2 -> tmp0
* %mm3 -> tmp1
* %mm4 -> tmp2
* %mm5 -> tmp3
* %mm6 -> *current_upper
* %mm7 -> *current
*/
static inline void scale2x_8_mmx_border(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
assert(count >= 16);
assert(count % 8 == 0);
/* always do the first and last run */
count -= 2*8;
__asm__ __volatile__(
/* first run */
/* set the current, current_pre, current_next registers */
"movq 0(%1), %%mm0\n"
"movq 0(%1), %%mm7\n"
"movq 8(%1), %%mm1\n"
"psllq $56, %%mm0\n"
"psllq $56, %%mm1\n"
"psrlq $56, %%mm0\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $8, %%mm2\n"
"psrlq $8, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqb %%mm6, %%mm2\n"
"pcmpeqb %%mm6, %%mm4\n"
"pcmpeqb (%2), %%mm3\n"
"pcmpeqb (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqb %%mm1, %%mm2\n"
"pcmpeqb %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpcklbw %%mm4, %%mm2\n"
"punpckhbw %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
/* next */
"addl $8, %0\n"
"addl $8, %1\n"
"addl $8, %2\n"
"addl $16, %3\n"
/* central runs */
"shrl $3, %4\n"
"jz 1f\n"
"0:\n"
/* set the current, current_pre, current_next registers */
"movq -8(%1), %%mm0\n"
"movq (%1), %%mm7\n"
"movq 8(%1), %%mm1\n"
"psrlq $56, %%mm0\n"
"psllq $56, %%mm1\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $8, %%mm2\n"
"psrlq $8, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqb %%mm6, %%mm2\n"
"pcmpeqb %%mm6, %%mm4\n"
"pcmpeqb (%2), %%mm3\n"
"pcmpeqb (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqb %%mm1, %%mm2\n"
"pcmpeqb %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpcklbw %%mm4, %%mm2\n"
"punpckhbw %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
/* next */
"addl $8, %0\n"
"addl $8, %1\n"
"addl $8, %2\n"
"addl $16, %3\n"
"decl %4\n"
"jnz 0b\n"
"1:\n"
/* final run */
/* set the current, current_pre, current_next registers */
"movq (%1), %%mm1\n"
"movq (%1), %%mm7\n"
"movq -8(%1), %%mm0\n"
"psrlq $56, %%mm1\n"
"psrlq $56, %%mm0\n"
"psllq $56, %%mm1\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $8, %%mm2\n"
"psrlq $8, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqb %%mm6, %%mm2\n"
"pcmpeqb %%mm6, %%mm4\n"
"pcmpeqb (%2), %%mm3\n"
"pcmpeqb (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqb %%mm1, %%mm2\n"
"pcmpeqb %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpcklbw %%mm4, %%mm2\n"
"punpckhbw %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
:
: "cc"
);
}
static inline void scale2x_16_mmx_border(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
{
assert(count >= 8);
assert(count % 4 == 0);
/* always do the first and last run */
count -= 2*4;
__asm__ __volatile__(
/* first run */
/* set the current, current_pre, current_next registers */
"movq 0(%1), %%mm0\n"
"movq 0(%1), %%mm7\n"
"movq 8(%1), %%mm1\n"
"psllq $48, %%mm0\n"
"psllq $48, %%mm1\n"
"psrlq $48, %%mm0\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $16, %%mm2\n"
"psrlq $16, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqw %%mm6, %%mm2\n"
"pcmpeqw %%mm6, %%mm4\n"
"pcmpeqw (%2), %%mm3\n"
"pcmpeqw (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqw %%mm1, %%mm2\n"
"pcmpeqw %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpcklwd %%mm4, %%mm2\n"
"punpckhwd %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
/* next */
"addl $8, %0\n"
"addl $8, %1\n"
"addl $8, %2\n"
"addl $16, %3\n"
/* central runs */
"shrl $2, %4\n"
"jz 1f\n"
"0:\n"
/* set the current, current_pre, current_next registers */
"movq -8(%1), %%mm0\n"
"movq (%1), %%mm7\n"
"movq 8(%1), %%mm1\n"
"psrlq $48, %%mm0\n"
"psllq $48, %%mm1\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $16, %%mm2\n"
"psrlq $16, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqw %%mm6, %%mm2\n"
"pcmpeqw %%mm6, %%mm4\n"
"pcmpeqw (%2), %%mm3\n"
"pcmpeqw (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqw %%mm1, %%mm2\n"
"pcmpeqw %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpcklwd %%mm4, %%mm2\n"
"punpckhwd %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
/* next */
"addl $8, %0\n"
"addl $8, %1\n"
"addl $8, %2\n"
"addl $16, %3\n"
"decl %4\n"
"jnz 0b\n"
"1:\n"
/* final run */
/* set the current, current_pre, current_next registers */
"movq (%1), %%mm1\n"
"movq (%1), %%mm7\n"
"movq -8(%1), %%mm0\n"
"psrlq $48, %%mm1\n"
"psrlq $48, %%mm0\n"
"psllq $48, %%mm1\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $16, %%mm2\n"
"psrlq $16, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqw %%mm6, %%mm2\n"
"pcmpeqw %%mm6, %%mm4\n"
"pcmpeqw (%2), %%mm3\n"
"pcmpeqw (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqw %%mm1, %%mm2\n"
"pcmpeqw %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpcklwd %%mm4, %%mm2\n"
"punpckhwd %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
:
: "cc"
);
}
static inline void scale2x_32_mmx_border(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
{
assert(count >= 4);
assert(count % 2 == 0);
/* always do the first and last run */
count -= 2*2;
__asm__ __volatile__(
/* first run */
/* set the current, current_pre, current_next registers */
"movq 0(%1), %%mm0\n"
"movq 0(%1), %%mm7\n"
"movq 8(%1), %%mm1\n"
"psllq $32, %%mm0\n"
"psllq $32, %%mm1\n"
"psrlq $32, %%mm0\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $32, %%mm2\n"
"psrlq $32, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqd %%mm6, %%mm2\n"
"pcmpeqd %%mm6, %%mm4\n"
"pcmpeqd (%2), %%mm3\n"
"pcmpeqd (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqd %%mm1, %%mm2\n"
"pcmpeqd %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpckldq %%mm4, %%mm2\n"
"punpckhdq %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
/* next */
"addl $8, %0\n"
"addl $8, %1\n"
"addl $8, %2\n"
"addl $16, %3\n"
/* central runs */
"shrl $1, %4\n"
"jz 1f\n"
"0:\n"
/* set the current, current_pre, current_next registers */
"movq -8(%1), %%mm0\n"
"movq (%1), %%mm7\n"
"movq 8(%1), %%mm1\n"
"psrlq $32, %%mm0\n"
"psllq $32, %%mm1\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $32, %%mm2\n"
"psrlq $32, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqd %%mm6, %%mm2\n"
"pcmpeqd %%mm6, %%mm4\n"
"pcmpeqd (%2), %%mm3\n"
"pcmpeqd (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqd %%mm1, %%mm2\n"
"pcmpeqd %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpckldq %%mm4, %%mm2\n"
"punpckhdq %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
/* next */
"addl $8, %0\n"
"addl $8, %1\n"
"addl $8, %2\n"
"addl $16, %3\n"
"decl %4\n"
"jnz 0b\n"
"1:\n"
/* final run */
/* set the current, current_pre, current_next registers */
"movq (%1), %%mm1\n"
"movq (%1), %%mm7\n"
"movq -8(%1), %%mm0\n"
"psrlq $32, %%mm1\n"
"psrlq $32, %%mm0\n"
"psllq $32, %%mm1\n"
"movq %%mm7, %%mm2\n"
"movq %%mm7, %%mm3\n"
"psllq $32, %%mm2\n"
"psrlq $32, %%mm3\n"
"por %%mm2, %%mm0\n"
"por %%mm3, %%mm1\n"
/* current_upper */
"movq (%0), %%mm6\n"
/* compute the upper-left pixel for dst on %%mm2 */
/* compute the upper-right pixel for dst on %%mm4 */
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"movq %%mm0, %%mm3\n"
"movq %%mm1, %%mm5\n"
"pcmpeqd %%mm6, %%mm2\n"
"pcmpeqd %%mm6, %%mm4\n"
"pcmpeqd (%2), %%mm3\n"
"pcmpeqd (%2), %%mm5\n"
"pandn %%mm2, %%mm3\n"
"pandn %%mm4, %%mm5\n"
"movq %%mm0, %%mm2\n"
"movq %%mm1, %%mm4\n"
"pcmpeqd %%mm1, %%mm2\n"
"pcmpeqd %%mm0, %%mm4\n"
"pandn %%mm3, %%mm2\n"
"pandn %%mm5, %%mm4\n"
"movq %%mm2, %%mm3\n"
"movq %%mm4, %%mm5\n"
"pand %%mm6, %%mm2\n"
"pand %%mm6, %%mm4\n"
"pandn %%mm7, %%mm3\n"
"pandn %%mm7, %%mm5\n"
"por %%mm3, %%mm2\n"
"por %%mm5, %%mm4\n"
/* set *dst */
"movq %%mm2, %%mm3\n"
"punpckldq %%mm4, %%mm2\n"
"punpckhdq %%mm4, %%mm3\n"
"movq %%mm2, (%3)\n"
"movq %%mm3, 8(%3)\n"
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
:
: "cc"
);
}
/**
* Scale by a factor of 2 a row of pixels of 8 bits.
* This is a very fast MMX implementation.
* The implementation uses a combination of cmp/and/not operations to
* completly remove the need of conditional jumps. This trick give the
* major speed improvement.
* Also, using the 8 bytes MMX registers more than one pixel are computed
* at the same time.
* Before calling this function you must ensure that the currenct CPU supports
* the MMX instruction set. After calling it you must be sure to call the EMMS
* instruction before any floating-point operation.
* The pixels over the left and right borders are assumed of the same color of
* the pixels on the border.
* Note that the implementation is optimized to write data sequentially to
* maximize the bandwidth on video memory.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows. It must
* be at least 16 and a multiple of 8.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
if (count % 8 != 0 || count < 16) {
scale2x_8_def(dst0, dst1, src0, src1, src2, count);
} else {
scale2x_8_mmx_border(dst0, src0, src1, src2, count);
scale2x_8_mmx_border(dst1, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2 a row of pixels of 16 bits.
* This function operates like scale2x_8_mmx() but for 16 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows. It must
* be at least 8 and a multiple of 4.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
{
if (count % 4 != 0 || count < 8) {
scale2x_16_def(dst0, dst1, src0, src1, src2, count);
} else {
scale2x_16_mmx_border(dst0, src0, src1, src2, count);
scale2x_16_mmx_border(dst1, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2 a row of pixels of 32 bits.
* This function operates like scale2x_8_mmx() but for 32 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows. It must
* be at least 4 and a multiple of 2.
* \param dst0 First destination row, double length in pixels.
* \param dst1 Second destination row, double length in pixels.
*/
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
{
if (count % 2 != 0 || count < 4) {
scale2x_32_def(dst0, dst1, src0, src1, src2, count);
} else {
scale2x_32_mmx_border(dst0, src0, src1, src2, count);
scale2x_32_mmx_border(dst1, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2x3 a row of pixels of 8 bits.
* This function operates like scale2x_8_mmx() but with an expansion
* factor of 2x3 instead of 2x2.
*/
void scale2x3_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
if (count % 8 != 0 || count < 16) {
scale2x3_8_def(dst0, dst1, dst2, src0, src1, src2, count);
} else {
scale2x_8_mmx_border(dst0, src0, src1, src2, count);
scale2x_8_def_center(dst1, src0, src1, src2, count);
scale2x_8_mmx_border(dst2, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2x3 a row of pixels of 16 bits.
* This function operates like scale2x_16_mmx() but with an expansion
* factor of 2x3 instead of 2x2.
*/
void scale2x3_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
{
if (count % 4 != 0 || count < 8) {
scale2x3_16_def(dst0, dst1, dst2, src0, src1, src2, count);
} else {
scale2x_16_mmx_border(dst0, src0, src1, src2, count);
scale2x_16_def_center(dst1, src0, src1, src2, count);
scale2x_16_mmx_border(dst2, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2x3 a row of pixels of 32 bits.
* This function operates like scale2x_32_mmx() but with an expansion
* factor of 2x3 instead of 2x2.
*/
void scale2x3_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
{
if (count % 2 != 0 || count < 4) {
scale2x3_32_def(dst0, dst1, dst2, src0, src1, src2, count);
} else {
scale2x_32_mmx_border(dst0, src0, src1, src2, count);
scale2x_32_def_center(dst1, src0, src1, src2, count);
scale2x_32_mmx_border(dst2, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2x4 a row of pixels of 8 bits.
* This function operates like scale2x_8_mmx() but with an expansion
* factor of 2x4 instead of 2x2.
*/
void scale2x4_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
{
if (count % 8 != 0 || count < 16) {
scale2x4_8_def(dst0, dst1, dst2, dst3, src0, src1, src2, count);
} else {
scale2x_8_mmx_border(dst0, src0, src1, src2, count);
scale2x_8_def_center(dst1, src0, src1, src2, count);
scale2x_8_def_center(dst2, src0, src1, src2, count);
scale2x_8_mmx_border(dst3, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2x4 a row of pixels of 16 bits.
* This function operates like scale2x_16_mmx() but with an expansion
* factor of 2x4 instead of 2x2.
*/
void scale2x4_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
{
if (count % 4 != 0 || count < 8) {
scale2x4_16_def(dst0, dst1, dst2, dst3, src0, src1, src2, count);
} else {
scale2x_16_mmx_border(dst0, src0, src1, src2, count);
scale2x_16_def_center(dst1, src0, src1, src2, count);
scale2x_16_def_center(dst2, src0, src1, src2, count);
scale2x_16_mmx_border(dst3, src2, src1, src0, count);
}
}
/**
* Scale by a factor of 2x4 a row of pixels of 32 bits.
* This function operates like scale2x_32_mmx() but with an expansion
* factor of 2x4 instead of 2x2.
*/
void scale2x4_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
{
if (count % 2 != 0 || count < 4) {
scale2x4_32_def(dst0, dst1, dst2, dst3, src0, src1, src2, count);
} else {
scale2x_32_mmx_border(dst0, src0, src1, src2, count);
scale2x_32_def_center(dst1, src0, src1, src2, count);
scale2x_32_def_center(dst2, src0, src1, src2, count);
scale2x_32_mmx_border(dst3, src2, src1, src0, count);
}
}
#endif
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __SCALE2X_H
#define __SCALE2X_H
#define restrict
typedef unsigned char scale2x_uint8;
typedef unsigned short scale2x_uint16;
typedef unsigned scale2x_uint32;
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
void scale2x3_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
void scale2x3_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
void scale2x3_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
void scale2x4_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
void scale2x4_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
void scale2x4_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
#if defined(__GNUC__) && defined(__i386__)
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
void scale2x3_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
void scale2x3_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
void scale2x3_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
void scale2x4_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
void scale2x4_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
void scale2x4_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
/**
* End the use of the MMX instructions.
* This function must be called before using any floating-point operations.
*/
static inline void scale2x_mmx_emms(void)
{
__asm__ __volatile__ (
"emms"
);
}
#endif
#endif
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains a C and MMX implementation of the Scale2x effect.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "scale3x.h"
#include <assert.h>
/***************************************************************************/
/* Scale3x C implementation */
/**
* Define the macro USE_SCALE_RANDOMWRITE to enable
* an optimized version which writes memory in random order.
* This version is a little faster if you write in system memory.
* But it's a lot slower if you write in video memory.
* So, enable it only if you are sure to never write directly in video memory.
*/
/* #define USE_SCALE_RANDOMWRITE */
static inline void scale3x_8_def_whole(scale3x_uint8* restrict dst0, scale3x_uint8* restrict dst1, scale3x_uint8* restrict dst2, const scale3x_uint8* restrict src0, const scale3x_uint8* restrict src1, const scale3x_uint8* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst0[0] = src1[0];
dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
dst2[0] = src1[0];
dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 3;
dst1 += 3;
dst2 += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 3;
dst1 += 3;
dst2 += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst0[2] = src1[0];
dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
dst2[2] = src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
}
static inline void scale3x_8_def_border(scale3x_uint8* restrict dst, const scale3x_uint8* restrict src0, const scale3x_uint8* restrict src1, const scale3x_uint8* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0];
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst[2] = src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
}
static inline void scale3x_8_def_center(scale3x_uint8* restrict dst, const scale3x_uint8* restrict src0, const scale3x_uint8* restrict src1, const scale3x_uint8* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
}
static inline void scale3x_16_def_whole(scale3x_uint16* restrict dst0, scale3x_uint16* restrict dst1, scale3x_uint16* restrict dst2, const scale3x_uint16* restrict src0, const scale3x_uint16* restrict src1, const scale3x_uint16* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst0[0] = src1[0];
dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
dst2[0] = src1[0];
dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 3;
dst1 += 3;
dst2 += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 3;
dst1 += 3;
dst2 += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst0[2] = src1[0];
dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
dst2[2] = src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
}
static inline void scale3x_16_def_border(scale3x_uint16* restrict dst, const scale3x_uint16* restrict src0, const scale3x_uint16* restrict src1, const scale3x_uint16* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0];
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst[2] = src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
}
static inline void scale3x_16_def_center(scale3x_uint16* restrict dst, const scale3x_uint16* restrict src0, const scale3x_uint16* restrict src1, const scale3x_uint16* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
}
static inline void scale3x_32_def_whole(scale3x_uint32* restrict dst0, scale3x_uint32* restrict dst1, scale3x_uint32* restrict dst2, const scale3x_uint32* restrict src0, const scale3x_uint32* restrict src1, const scale3x_uint32* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst0[0] = src1[0];
dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
dst2[0] = src1[0];
dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 3;
dst1 += 3;
dst2 += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
++src0;
++src1;
++src2;
dst0 += 3;
dst1 += 3;
dst2 += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst0[2] = src1[0];
dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst1[1] = src1[0];
dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
dst2[2] = src1[0];
} else {
dst0[0] = src1[0];
dst0[1] = src1[0];
dst0[2] = src1[0];
dst1[0] = src1[0];
dst1[1] = src1[0];
dst1[2] = src1[0];
dst2[0] = src1[0];
dst2[1] = src1[0];
dst2[2] = src1[0];
}
}
static inline void scale3x_32_def_border(scale3x_uint32* restrict dst, const scale3x_uint32* restrict src0, const scale3x_uint32* restrict src1, const scale3x_uint32* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = src1[0];
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
dst[2] = src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
}
static inline void scale3x_32_def_center(scale3x_uint32* restrict dst, const scale3x_uint32* restrict src0, const scale3x_uint32* restrict src1, const scale3x_uint32* restrict src2, unsigned count)
{
assert(count >= 2);
/* first pixel */
if (src0[0] != src2[0] && src1[0] != src1[1]) {
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
/* central pixels */
count -= 2;
while (count) {
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
++src0;
++src1;
++src2;
dst += 3;
--count;
}
/* last pixel */
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
dst[1] = src1[0];
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
} else {
dst[0] = src1[0];
dst[1] = src1[0];
dst[2] = src1[0];
}
}
/**
* Scale by a factor of 3 a row of pixels of 8 bits.
* The function is implemented in C.
* The pixels over the left and right borders are assumed of the same color of
* the pixels on the border.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, triple length in pixels.
* \param dst1 Second destination row, triple length in pixels.
* \param dst2 Third destination row, triple length in pixels.
*/
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale3x_8_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
#else
scale3x_8_def_border(dst0, src0, src1, src2, count);
scale3x_8_def_center(dst1, src0, src1, src2, count);
scale3x_8_def_border(dst2, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 3 a row of pixels of 16 bits.
* This function operates like scale3x_8_def() but for 16 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, triple length in pixels.
* \param dst1 Second destination row, triple length in pixels.
* \param dst2 Third destination row, triple length in pixels.
*/
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
#else
scale3x_16_def_border(dst0, src0, src1, src2, count);
scale3x_16_def_center(dst1, src0, src1, src2, count);
scale3x_16_def_border(dst2, src2, src1, src0, count);
#endif
}
/**
* Scale by a factor of 3 a row of pixels of 32 bits.
* This function operates like scale3x_8_def() but for 32 bits pixels.
* \param src0 Pointer at the first pixel of the previous row.
* \param src1 Pointer at the first pixel of the current row.
* \param src2 Pointer at the first pixel of the next row.
* \param count Length in pixels of the src0, src1 and src2 rows.
* It must be at least 2.
* \param dst0 First destination row, triple length in pixels.
* \param dst1 Second destination row, triple length in pixels.
* \param dst2 Third destination row, triple length in pixels.
*/
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
{
#ifdef USE_SCALE_RANDOMWRITE
scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
#else
scale3x_32_def_border(dst0, src0, src1, src2, count);
scale3x_32_def_center(dst1, src0, src1, src2, count);
scale3x_32_def_border(dst2, src2, src1, src0, count);
#endif
}
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __SCALE3X_H
#define __SCALE3X_H
#define restrict
typedef unsigned char scale3x_uint8;
typedef unsigned short scale3x_uint16;
typedef unsigned scale3x_uint32;
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count);
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count);
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count);
#endif
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003, 2004 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains an example implementation of the Scale effect
* applyed to a generic bitmap.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "scale2x.h"
#include "scale3x.h"
#if HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include <assert.h>
#include <stdlib.h>
#define SSDST(bits, num) (scale2x_uint##bits *)dst##num
#define SSSRC(bits, num) (const scale2x_uint##bits *)src##num
/**
* Apply the Scale2x effect on a group of rows. Used internally.
*/
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
{
switch (pixel) {
#if defined(__GNUC__) && defined(__i386__)
case 1 : scale2x_8_mmx(SSDST(8,0), SSDST(8,1), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
case 2 : scale2x_16_mmx(SSDST(16,0), SSDST(16,1), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
case 4 : scale2x_32_mmx(SSDST(32,0), SSDST(32,1), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
#else
case 1 : scale2x_8_def(SSDST(8,0), SSDST(8,1), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
case 2 : scale2x_16_def(SSDST(16,0), SSDST(16,1), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
case 4 : scale2x_32_def(SSDST(32,0), SSDST(32,1), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
#endif
}
}
/**
* Apply the Scale2x3 effect on a group of rows. Used internally.
*/
static inline void stage_scale2x3(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
{
switch (pixel) {
#if defined(__GNUC__) && defined(__i386__)
case 1 : scale2x3_8_mmx(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
case 2 : scale2x3_16_mmx(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
case 4 : scale2x3_32_mmx(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
#else
case 1 : scale2x3_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
case 2 : scale2x3_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
case 4 : scale2x3_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
#endif
}
}
/**
* Apply the Scale2x4 effect on a group of rows. Used internally.
*/
static inline void stage_scale2x4(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
{
switch (pixel) {
#if defined(__GNUC__) && defined(__i386__)
case 1 : scale2x4_8_mmx(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSDST(8,3), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
case 2 : scale2x4_16_mmx(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSDST(16,3), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
case 4 : scale2x4_32_mmx(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSDST(32,3), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
#else
case 1 : scale2x4_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSDST(8,3), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
case 2 : scale2x4_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSDST(16,3), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
case 4 : scale2x4_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSDST(32,3), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
#endif
}
}
/**
* Apply the Scale3x effect on a group of rows. Used internally.
*/
static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
{
switch (pixel) {
case 1 : scale3x_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
case 2 : scale3x_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
case 4 : scale3x_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
}
}
/**
* Apply the Scale4x effect on a group of rows. Used internally.
*/
static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
{
stage_scale2x(dst0, dst1, src0, src1, src2, pixel, 2 * pixel_per_row);
stage_scale2x(dst2, dst3, src1, src2, src3, pixel, 2 * pixel_per_row);
}
#define SCDST(i) (dst+(i)*dst_slice)
#define SCSRC(i) (src+(i)*src_slice)
#define SCMID(i) (mid[(i)])
/**
* Apply the Scale2x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 2x2 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
unsigned char* dst = (unsigned char*)void_dst;
const unsigned char* src = (const unsigned char*)void_src;
unsigned count;
assert(height >= 2);
count = height;
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
dst = SCDST(2);
count -= 2;
while (count) {
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
dst = SCDST(2);
src = SCSRC(1);
--count;
}
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms();
#endif
}
/**
* Apply the Scale2x3 effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 2x3 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static void scale2x3(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
unsigned char* dst = (unsigned char*)void_dst;
const unsigned char* src = (const unsigned char*)void_src;
unsigned count;
assert(height >= 2);
count = height;
stage_scale2x3(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
dst = SCDST(3);
count -= 2;
while (count) {
stage_scale2x3(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
dst = SCDST(3);
src = SCSRC(1);
--count;
}
stage_scale2x3(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms();
#endif
}
/**
* Apply the Scale2x4 effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 2x4 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static void scale2x4(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
unsigned char* dst = (unsigned char*)void_dst;
const unsigned char* src = (const unsigned char*)void_src;
unsigned count;
assert(height >= 2);
count = height;
stage_scale2x4(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
dst = SCDST(4);
count -= 2;
while (count) {
stage_scale2x4(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
dst = SCDST(4);
src = SCSRC(1);
--count;
}
stage_scale2x4(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms();
#endif
}
/**
* Apply the Scale3x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 3x3 times the size of the source bitmap.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
unsigned char* dst = (unsigned char*)void_dst;
const unsigned char* src = (const unsigned char*)void_src;
unsigned count;
assert(height >= 2);
count = height;
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
dst = SCDST(3);
count -= 2;
while (count) {
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
dst = SCDST(3);
src = SCSRC(1);
--count;
}
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(1), pixel, width);
}
/**
* Apply the Scale4x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
* \note This function requires also a small buffer bitmap used internally to store
* intermediate results. This bitmap must have at least an horizontal size in bytes of 2*width*pixel,
* and a vertical size of 6 rows. The memory of this buffer must not be allocated
* in video memory because it's also read and not only written. Generally
* a heap (malloc) or a stack (alloca) buffer is the best choice.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_mid Pointer at the first pixel of the buffer bitmap.
* \param mid_slice Size in bytes of a buffer bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
unsigned char* dst = (unsigned char*)void_dst;
const unsigned char* src = (const unsigned char*)void_src;
unsigned count;
unsigned char* mid[6];
assert(height >= 4);
count = height;
/* set the 6 buffer pointers */
mid[0] = (unsigned char*)void_mid;
mid[1] = mid[0] + mid_slice;
mid[2] = mid[1] + mid_slice;
mid[3] = mid[2] + mid_slice;
mid[4] = mid[3] + mid_slice;
mid[5] = mid[4] + mid_slice;
stage_scale2x(SCMID(-2+6), SCMID(-1+6), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
stage_scale2x(SCMID(0), SCMID(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
stage_scale2x(SCMID(2), SCMID(3), SCSRC(1), SCSRC(2), SCSRC(3), pixel, width);
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-2+6), SCMID(-2+6), SCMID(-1+6), SCMID(0), pixel, width);
dst = SCDST(4);
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-1+6), SCMID(0), SCMID(1), SCMID(2), pixel, width);
dst = SCDST(4);
count -= 4;
while (count) {
unsigned char* tmp;
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
dst = SCDST(4);
src = SCSRC(1);
tmp = SCMID(0); /* shift by 2 position */
SCMID(0) = SCMID(2);
SCMID(2) = SCMID(4);
SCMID(4) = tmp;
tmp = SCMID(1);
SCMID(1) = SCMID(3);
SCMID(3) = SCMID(5);
SCMID(5) = tmp;
--count;
}
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(3), pixel, width);
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
dst = SCDST(4);
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(3), SCMID(4), SCMID(5), SCMID(5), pixel, width);
#if defined(__GNUC__) && defined(__i386__)
scale2x_mmx_emms();
#endif
}
/**
* Apply the Scale4x effect on a bitmap.
* The destination bitmap is filled with the scaled version of the source bitmap.
* The source bitmap isn't modified.
* The destination bitmap must be manually allocated before calling the function,
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
* \note This function operates like ::scale4x_buf() but the intermediate buffer is
* automatically allocated in the stack.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
unsigned mid_slice;
void* mid;
mid_slice = 2 * pixel * width; /* required space for 1 row buffer */
mid_slice = (mid_slice + 0x7) & ~0x7; /* align to 8 bytes */
#if HAVE_ALLOCA
mid = alloca(6 * mid_slice); /* allocate space for 6 row buffers */
assert(mid != 0); /* alloca should never fails */
#else
mid = malloc(6 * mid_slice); /* allocate space for 6 row buffers */
if (!mid)
return;
#endif
scale4x_buf(void_dst, dst_slice, mid, mid_slice, void_src, src_slice, pixel, width, height);
#if !HAVE_ALLOCA
free(mid);
#endif
}
/**
* Check if the scale implementation is applicable at the given arguments.
* \param scale Scale factor. 2, 203 (fox 2x3), 204 (for 2x4), 3 or 4.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
* \return
* - -1 on precondition violated.
* - 0 on success.
*/
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height)
{
if (pixel != 1 && pixel != 2 && pixel != 4)
return -1;
switch (scale) {
case 202 :
case 203 :
case 204 :
case 2 :
case 303 :
case 3 :
if (height < 2)
return -1;
break;
case 404 :
case 4 :
if (height < 4)
return -1;
break;
default:
return -1;
}
if (width < 2)
return -1;
return 0;
}
/**
* Apply the Scale effect on a bitmap.
* This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
* \param scale Scale factor. 2, 203 (fox 2x3), 204 (for 2x4), 3 or 4.
* \param void_dst Pointer at the first pixel of the destination bitmap.
* \param dst_slice Size in bytes of a destination bitmap row.
* \param void_src Pointer at the first pixel of the source bitmap.
* \param src_slice Size in bytes of a source bitmap row.
* \param pixel Bytes per pixel of the source and destination bitmap.
* \param width Horizontal size in pixels of the source bitmap.
* \param height Vertical size in pixels of the source bitmap.
*/
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
switch (scale) {
case 202 :
case 2 :
scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
case 203 :
scale2x3(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
case 204 :
scale2x4(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
case 303 :
case 3 :
scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
case 404 :
case 4 :
scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
}
}
/*
* This file is part of the Scale2x project.
*
* Copyright (C) 2003 Andrea Mazzoleni
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This file contains an example implementation of the Scale effect
* applyed to a generic bitmap.
*
* You can find an high level description of the effect at :
*
* http://scale2x.sourceforge.net/
*
* Alternatively at the previous license terms, you are allowed to use this
* code in your program with these conditions:
* - the program is not used in commercial activities.
* - the whole source code of the program is released with the binary.
* - derivative works of the program are allowed.
*/
#ifndef __SCALEBIT_H
#define __SCALEBIT_H
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height);
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height);
void Simple2x(unsigned char *srcPtr, unsigned int srcPitch, unsigned char *deltaPtr, unsigned char *dstPtr, unsigned int dstPitch, int width, int height);
#endif
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development 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, 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.
/*
* Code adapted To openjazz by Pickle (from Openbor adapted by SX
* simple2x.c - Trying to scale 2x.
*
*
*/
#include "scalebit.h"
void Simple2x(unsigned char *srcPtr, unsigned int srcPitch, unsigned char *deltaPtr, unsigned char *dstPtr, unsigned int dstPitch, int width, int height)
{
unsigned char *nextLine, *finish;
nextLine = dstPtr + dstPitch;
do
{
unsigned char *bP = (unsigned char *) srcPtr;
unsigned char *dP = (unsigned char *) dstPtr;
unsigned char *nL = (unsigned char *) nextLine;
unsigned char currentPixel;
finish = (unsigned char *) bP + ((width+2) << 1);
currentPixel = *bP++;
do
{
#ifdef BIG_ENDIAN
unsigned char color = currentPixel >> 16;
#else
unsigned char color = currentPixel & 0xffff;
#endif
color = color | (color << 16);
*(dP) = color;
*(nL) = color;
//#ifdef BIG_ENDIAN
// color = currentPixel & 0xffff;
//#else
// color = currentPixel >> 16;
//#endif
color = color| (color << 16);
*(dP + 1) = color;
*(nL + 1) = color;
currentPixel = *bP++;
dP += 2;
nL += 2;
}
while ((unsigned char *) bP < finish);
srcPtr += srcPitch;
dstPtr += dstPitch << 1;
nextLine += dstPitch << 1;
}
while (--height);
}
void Simple2x32(unsigned char *srcPtr, unsigned int srcPitch, unsigned char *deltaPtr, unsigned char *dstPtr, unsigned int dstPitch, int width, int height)
{
unsigned char *nextLine, *finish;
nextLine = dstPtr + dstPitch;
do
{
unsigned int *bP = (unsigned int *) srcPtr;
unsigned int *dP = (unsigned int *) dstPtr;
unsigned int *nL = (unsigned int *) nextLine;
unsigned int currentPixel;
finish = (unsigned char *) bP + ((width+1) << 2);
currentPixel = *bP++;
do
{
unsigned int color = currentPixel;
*(dP) = color;
*(dP+1) = color;
*(nL) = color;
*(nL + 1) = color;
currentPixel = *bP++;
dP += 2;
nL += 2;
}
while ((unsigned char *) bP < finish);
srcPtr += srcPitch;
dstPtr += dstPitch << 1;
nextLine += dstPitch << 1;
}
while (--height);
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Part of the OpenJazz project * Part of the OpenJazz project
* *
* *
* Copyright (c) 2005-2009 Alister Thomson * Copyright (c) 2005-2010 Alister Thomson
* *
* OpenJazz is distributed under the terms of * OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0 * the GNU General Public License, version 2.0
...@@ -127,7 +127,7 @@ void Sprite::draw (int x, int y) { ...@@ -127,7 +127,7 @@ void Sprite::draw (int x, int y) {
dst.x = x + xOffset; dst.x = x + xOffset;
dst.y = y + yOffset; dst.y = y + yOffset;
SDL_BlitSurface(pixels, NULL, screen, &dst); SDL_BlitSurface(pixels, NULL, canvas, &dst);
return; return;
......
...@@ -42,8 +42,8 @@ SDL_Surface * createSurface (unsigned char * pixels, int width, int height) { ...@@ -42,8 +42,8 @@ SDL_Surface * createSurface (unsigned char * pixels, int width, int height) {
// Set the surface's palette // Set the surface's palette
SDL_SetPalette(ret, SDL_LOGPAL, logicalPalette, 0, 256); SDL_SetPalette(ret, SDL_LOGPAL, logicalPalette, 0, 256);
if (pixels != NULL ) if (pixels != NULL) {
{
// Upload pixel data to the surface // Upload pixel data to the surface
if (SDL_MUSTLOCK(ret)) SDL_LockSurface(ret); if (SDL_MUSTLOCK(ret)) SDL_LockSurface(ret);
...@@ -55,6 +55,7 @@ SDL_Surface * createSurface (unsigned char * pixels, int width, int height) { ...@@ -55,6 +55,7 @@ SDL_Surface * createSurface (unsigned char * pixels, int width, int height) {
// Free redundant pixel data // Free redundant pixel data
delete[] pixels; delete[] pixels;
} }
return ret; return ret;
...@@ -63,33 +64,39 @@ SDL_Surface * createSurface (unsigned char * pixels, int width, int height) { ...@@ -63,33 +64,39 @@ SDL_Surface * createSurface (unsigned char * pixels, int width, int height) {
void createFullscreen () { void createFullscreen () {
#ifdef SCALE
if (canvas != screen) SDL_FreeSurface(canvas);
#endif
#if defined(WIZ) || defined(GP2X) #if defined(WIZ) || defined(GP2X)
screen = SDL_SetVideoMode(320, 240, 8, screen = SDL_SetVideoMode(320, 240, 8, V_FULLSCREEN);
SDL_FULLSCREEN | SDL_SWSURFACE | SDL_HWPALETTE);
#else #else
screen = SDL_SetVideoMode(screenW, screenH, 8, V_FULLSCREEN);
#endif
#ifdef SCALE #ifdef SCALE
screen_scaled = SDL_SetVideoMode(screenW*scalar, screenH*scalar, 8, if (scaleFactor > 1) {
SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE);
if (screen)
SDL_FreeSurface(screen);
screen = createSurface( NULL, screenW, screenH ); canvasW = screenW / scaleFactor;
canvasH = screenH / scaleFactor;
canvas = createSurface(NULL, canvasW, canvasH);
SDL_SetPalette(screen_scaled, SDL_LOGPAL, logicalPalette, 0, 256); } else {
SDL_SetPalette(screen_scaled, SDL_PHYSPAL, currentPalette, 0, 256);
#else
screen = SDL_SetVideoMode(screenW, screenH, 8,
SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE);
SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256);
#endif #endif
canvasW = screenW;
canvasH = screenH;
canvas = screen;
#ifdef SCALE
}
#endif #endif
SDL_ShowCursor(SDL_DISABLE);
#if !(defined(WIZ) || defined(GP2X))
SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256);
#endif
/* A real 8-bit display is quite likely if the user has the right video /* A real 8-bit display is quite likely if the user has the right video
...@@ -109,26 +116,34 @@ void createFullscreen () { ...@@ -109,26 +116,34 @@ void createFullscreen () {
#ifndef FULLSCREEN_ONLY #ifndef FULLSCREEN_ONLY
void createWindow () { void createWindow () {
#ifdef SCALE
screen_scaled = SDL_SetVideoMode(screenW*scalar, screenH*scalar, 8,
SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_HWSURFACE);
if (screen) #ifdef SCALE
SDL_FreeSurface(screen); if (canvas != screen) SDL_FreeSurface(canvas);
#endif
screen = SDL_SetVideoMode(screenW, screenH, 8, V_WINDOWED);
#ifdef SCALE
if (scaleFactor > 1) {
canvasW = screenW / scaleFactor;
canvasH = screenH / scaleFactor;
canvas = createSurface(NULL, canvasW, canvasH);
} else {
#endif
canvasW = screenW;
canvasH = screenH;
canvas = screen;
#ifdef SCALE
}
#endif
screen = createSurface( NULL, screenW, screenH );
SDL_SetPalette(screen_scaled, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen_scaled, SDL_PHYSPAL, currentPalette, 0, 256);
#else
screen = SDL_SetVideoMode(screenW, screenH, 8,
SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE);
SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256); SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256); SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256);
#endif
SDL_ShowCursor(SDL_ENABLE);
/* Assume that in windowed mode the palette is being emulated. /* Assume that in windowed mode the palette is being emulated.
This is extremely likely. */ This is extremely likely. */
...@@ -150,9 +165,6 @@ void usePalette (SDL_Color *palette) { ...@@ -150,9 +165,6 @@ void usePalette (SDL_Color *palette) {
#endif #endif
SDL_SetPalette(screen, SDL_PHYSPAL, palette, 0, 256); SDL_SetPalette(screen, SDL_PHYSPAL, palette, 0, 256);
#ifdef SCALE
SDL_SetPalette(screen_scaled, SDL_PHYSPAL, palette, 0, 256);
#endif
currentPalette = palette; currentPalette = palette;
return; return;
...@@ -171,12 +183,13 @@ void restorePalette (SDL_Surface *surface) { ...@@ -171,12 +183,13 @@ void restorePalette (SDL_Surface *surface) {
void clearScreen (int index) { void clearScreen (int index) {
#if defined(WIZ) || defined(GP2X) #if defined(WIZ) || defined(GP2X)
// always 240 lines cleared to black // always 240 lines cleared to black
memset(screen->pixels, index, 320*240); memset(screen->pixels, index, 320*240);
#else #else
SDL_FillRect(screen, NULL, index); SDL_FillRect(canvas, NULL, index);
#endif #endif
return; return;
} }
...@@ -191,7 +204,7 @@ void drawRect (int x, int y, int width, int height, int index) { ...@@ -191,7 +204,7 @@ void drawRect (int x, int y, int width, int height, int index) {
dst.w = width; dst.w = width;
dst.h = height; dst.h = height;
SDL_FillRect(screen, &dst, index); SDL_FillRect(canvas, &dst, index);
return; return;
......
...@@ -31,17 +31,24 @@ ...@@ -31,17 +31,24 @@
// Constants // Constants
#define V_WINDOWED (SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE)
#if defined(WIZ) || defined(GP2X)
#define V_FULLSCREEN (SDL_FULLSCREEN | SDL_SWSURFACE | SDL_HWPALETTE)
#else
#define V_FULLSCREEN (SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE)
#endif
// Black palette index // Black palette index
#define BLACK 31 #define BLACK 31
// Variables // Variables
EXTERN SDL_Surface *screen; EXTERN SDL_Surface *screen, *canvas;
EXTERN int viewW, viewH, screenW, screenH; EXTERN int viewW, viewH, canvasW, canvasH, screenW, screenH;
EXTERN int scalar;
#ifdef SCALE #ifdef SCALE
EXTERN SDL_Surface *screen_scaled; EXTERN int scaleFactor;
#endif #endif
#ifndef FULLSCREEN_ONLY #ifndef FULLSCREEN_ONLY
EXTERN bool fullscreen; EXTERN bool fullscreen;
...@@ -68,8 +75,7 @@ EXTERN void createWindow (); ...@@ -68,8 +75,7 @@ EXTERN void createWindow ();
EXTERN void usePalette (SDL_Color *palette); EXTERN void usePalette (SDL_Color *palette);
EXTERN void restorePalette (SDL_Surface *surface); EXTERN void restorePalette (SDL_Surface *surface);
EXTERN void clearScreen (int index); EXTERN void clearScreen (int index);
EXTERN void drawRect (int x, int y, int width, int height, EXTERN void drawRect (int x, int y, int width, int height, int index);
int index);
#endif #endif
......
...@@ -126,7 +126,7 @@ int Network::host () { ...@@ -126,7 +126,7 @@ int Network::host () {
return sock; return sock;
#elif defined USE_SDL_NET #elif defined USE_SDL_NET
ipAddress.port = NET_PORT; ipAddress.port = NET_PORT;
ipAddress.host = 0; ipAddress.host = 0;
socket = SDLNet_TCP_Open(&ipAddress); socket = SDLNet_TCP_Open(&ipAddress);
if (socket == NULL) return E_N_SOCKET; if (socket == NULL) return E_N_SOCKET;
...@@ -142,7 +142,7 @@ int Network::join (char *address) { ...@@ -142,7 +142,7 @@ int Network::join (char *address) {
#ifdef USE_SOCKETS #ifdef USE_SOCKETS
sockaddr_in sockAddr; sockaddr_in sockAddr;
fd_set writefds; fd_set writefds;
timeval timeouttv; timeval timeouttv;
unsigned int timeout; unsigned int timeout;
int sock, con; int sock, con;
...@@ -181,7 +181,7 @@ int Network::join (char *address) { ...@@ -181,7 +181,7 @@ int Network::join (char *address) {
con = 0; con = 0;
timeout = globalTicks + T_TIMEOUT; timeout = globalTicks + T_TIMEOUT;
while (!con) { while (!con) {
if (loop(NORMAL_LOOP) == E_QUIT) { if (loop(NORMAL_LOOP) == E_QUIT) {
...@@ -201,8 +201,7 @@ int Network::join (char *address) { ...@@ -201,8 +201,7 @@ int Network::join (char *address) {
} }
clearScreen(0); clearScreen(0);
fontmn2->showString("CONNECTING TO SERVER", screenW >> 2, fontmn2->showString("CONNECTING TO SERVER", canvasW >> 2, (canvasH >> 1) - 16);
(screenH >> 1) - 16);
FD_ZERO(&writefds); FD_ZERO(&writefds);
FD_SET(sock, &writefds); FD_SET(sock, &writefds);
...@@ -233,11 +232,10 @@ int Network::join (char *address) { ...@@ -233,11 +232,10 @@ int Network::join (char *address) {
return sock; return sock;
#elif defined USE_SDL_NET #elif defined USE_SDL_NET
clearScreen(0); clearScreen(0);
fontmn2->showString("CONNECTING TO SERVER", screenW >> 2, fontmn2->showString("CONNECTING TO SERVER", canvasW >> 2, (canvasH >> 1) - 16);
(screenH >> 1) - 16);
loop(NORMAL_LOOP); loop(NORMAL_LOOP);
ipAddress.port = NET_PORT; ipAddress.port = NET_PORT;
ipAddress.host = inet_addr(address); ipAddress.host = inet_addr(address);
socket = SDLNet_TCP_Open(&ipAddress); socket = SDLNet_TCP_Open(&ipAddress);
if (socket == NULL) return -1; if (socket == NULL) return -1;
...@@ -301,7 +299,7 @@ int Network::send (int sock, unsigned char *buffer) { ...@@ -301,7 +299,7 @@ int Network::send (int sock, unsigned char *buffer) {
#ifdef USE_SOCKETS #ifdef USE_SOCKETS
return ::send(sock, (char *)buffer, buffer[0], MSG_NOSIGNAL); return ::send(sock, (char *)buffer, buffer[0], MSG_NOSIGNAL);
#elif defined USE_SDL_NET #elif defined USE_SDL_NET
return SDLNet_TCP_Send((TCPsocket)sock, (char *)buffer, buffer[0]); return SDLNet_TCP_Send((TCPsocket)sock, (char *)buffer, buffer[0]);
#else #else
return 0; return 0;
#endif #endif
......
...@@ -173,7 +173,7 @@ int DemoLevel::play () { ...@@ -173,7 +173,7 @@ int DemoLevel::play () {
draw(); draw();
fontmn1->showString("DEMO", (screenW >> 1) - 36, 32); fontmn1->showString("DEMO", (canvasW >> 1) - 36, 32);
// Draw graphics statistics // Draw graphics statistics
...@@ -182,9 +182,9 @@ int DemoLevel::play () { ...@@ -182,9 +182,9 @@ int DemoLevel::play () {
drawRect(236, 9, 80, 32, BLACK); drawRect(236, 9, 80, 32, BLACK);
panelBigFont->showNumber(screenW, 268, 15); panelBigFont->showNumber(canvasW, 268, 15);
panelBigFont->showString("x", 272, 15); panelBigFont->showString("x", 272, 15);
panelBigFont->showNumber(screenH, 308, 15); panelBigFont->showNumber(canvasH, 308, 15);
panelBigFont->showString("fps", 244, 27); panelBigFont->showString("fps", 244, 27);
panelBigFont->showNumber((int)smoothfps, 308, 27); panelBigFont->showNumber((int)smoothfps, 308, 27);
......
...@@ -524,7 +524,7 @@ void Level::timeCalcs (bool paused) { ...@@ -524,7 +524,7 @@ void Level::timeCalcs (bool paused) {
where c = (1 / fps) where c = (1 / fps)
and fps = 1000 / (ticks - prevTicks) and fps = 1000 / (ticks - prevTicks)
In other words, the response of smoothFPS to changes in FPS decreases as the In other words, the response of smoothFPS to changes in FPS decreases as the
framerate increases framerate increases
The following version is for c = (1 / smoothfps) The following version is for c = (1 / smoothfps)
*/ */
// smoothfps = (fps / smoothfps) + smoothfps - 1; // smoothfps = (fps / smoothfps) + smoothfps - 1;
...@@ -733,7 +733,7 @@ int Level::play () { ...@@ -733,7 +733,7 @@ int Level::play () {
// If paused, draw "PAUSE" // If paused, draw "PAUSE"
if (paused && !pmenu) if (paused && !pmenu)
fontmn1->showString("PAUSE", (screenW >> 1) - 44, 32); fontmn1->showString("PAUSE", (canvasW >> 1) - 44, 32);
// If this is a competitive game, draw the score // If this is a competitive game, draw the score
...@@ -772,9 +772,9 @@ int Level::play () { ...@@ -772,9 +772,9 @@ int Level::play () {
drawRect(viewW - 84, 11, 80, 25, BLACK); drawRect(viewW - 84, 11, 80, 25, BLACK);
panelBigFont->showNumber(screenW, viewW - 52, 14); panelBigFont->showNumber(canvasW, viewW - 52, 14);
panelBigFont->showString("x", viewW - 48, 14); panelBigFont->showString("x", viewW - 48, 14);
panelBigFont->showNumber(screenH, viewW - 12, 14); panelBigFont->showNumber(canvasH, viewW - 12, 14);
panelBigFont->showString("fps", viewW - 76, 26); panelBigFont->showString("fps", viewW - 76, 26);
panelBigFont->showNumber((int)smoothfps, viewW - 12, 26); panelBigFont->showNumber((int)smoothfps, viewW - 12, 26);
...@@ -826,38 +826,28 @@ int Level::play () { ...@@ -826,38 +826,28 @@ int Level::play () {
// Display statistics & bonuses // Display statistics & bonuses
// TODO: Display percentage symbol // TODO: Display percentage symbol
fontmn1->showString("TIME", (screenW >> 1) - 152, fontmn1->showString("TIME", (canvasW >> 1) - 152, (canvasH >> 1) - 60);
(screenH >> 1) - 60); fontmn1->showNumber(timeBonus, (canvasW >> 1) + 124, (canvasH >> 1) - 60);
fontmn1->showNumber(timeBonus, (screenW >> 1) + 124,
(screenH >> 1) - 60);
fontmn1->showString("ENEMIES", (screenW >> 1) - 152, fontmn1->showString("ENEMIES", (canvasW >> 1) - 152, (canvasH >> 1) - 40);
(screenH >> 1) - 40);
if (enemies) if (enemies)
fontmn1->showNumber((localPlayer->getEnemies() * 100) / enemies, fontmn1->showNumber((localPlayer->getEnemies() * 100) / enemies, (canvasW >> 1) + 124, (canvasH >> 1) - 40);
(screenW >> 1) + 124, (screenH >> 1) - 40);
else else
fontmn1->showNumber(0, (screenW >> 1) + 124, fontmn1->showNumber(0, (canvasW >> 1) + 124, (canvasH >> 1) - 40);
(screenH >> 1) - 40);
fontmn1->showString("ITEMS", (screenW >> 1) - 152, fontmn1->showString("ITEMS", (canvasW >> 1) - 152, (canvasH >> 1) - 20);
(screenH >> 1) - 20);
if (items) if (items)
fontmn1->showNumber((localPlayer->getItems() * 100) / items, fontmn1->showNumber((localPlayer->getItems() * 100) / items, (canvasW >> 1) + 124, (canvasH >> 1) - 20);
(screenW >> 1) + 124, (screenH >> 1) - 20);
else else
fontmn1->showNumber(0, (screenW >> 1) + 124, fontmn1->showNumber(0, (canvasW >> 1) + 124, (canvasH >> 1) - 20);
(screenH >> 1) - 20);
fontmn1->showString("PERFECT", (screenW >> 1) - 152, screenH >> 1); fontmn1->showString("PERFECT", (canvasW >> 1) - 152, canvasH >> 1);
fontmn1->showNumber(perfect, (screenW >> 1) + 124, screenH >> 1); fontmn1->showNumber(perfect, (canvasW >> 1) + 124, canvasH >> 1);
fontmn1->showString("SCORE", (screenW >> 1) - 152, fontmn1->showString("SCORE", (canvasW >> 1) - 152, (canvasH >> 1) + 40);
(screenH >> 1) + 40); fontmn1->showNumber(localPlayer->getScore(), (canvasW >> 1) + 124, (canvasH >> 1) + 40);
fontmn1->showNumber(localPlayer->getScore(), (screenW >> 1) + 124,
(screenH >> 1) + 40);
} }
...@@ -866,15 +856,14 @@ int Level::play () { ...@@ -866,15 +856,14 @@ int Level::play () {
// Draw the menu // Draw the menu
drawRect((screenW >> 2) - 8, (screenH >> 1) - 46, 144, 92, BLACK); drawRect((canvasW >> 2) - 8, (canvasH >> 1) - 46, 144, 92, BLACK);
for (count = 0; count < 5; count++) { for (count = 0; count < 5; count++) {
if (count == option) fontmn2->mapPalette(240, 8, 47, -16); if (count == option) fontmn2->mapPalette(240, 8, 47, -16);
else fontmn2->mapPalette(240, 8, 15, -16); else fontmn2->mapPalette(240, 8, 15, -16);
fontmn2->showString(options[count], screenW >> 2, fontmn2->showString(options[count], canvasW >> 2, (canvasH >> 1) + (count << 4) - 38);
(screenH >> 1) + (count << 4) - 38);
} }
......
...@@ -206,20 +206,20 @@ void Level::draw () { ...@@ -206,20 +206,20 @@ void Level::draw () {
vY = FTOI(viewY); vY = FTOI(viewY);
dst.w = viewW; dst.w = viewW;
dst.h = viewH; dst.h = viewH;
SDL_SetClipRect(screen, &dst); SDL_SetClipRect(canvas, &dst);
if ((viewW < screenW) || (viewH < screenH)) clearScreen(15); if ((viewW < canvasW) || (viewH < canvasH)) clearScreen(15);
// If there is a sky, draw it // If there is a sky, draw it
if (sky) { if (sky) {
// Background scale // Background scale
if (screenW > 320) bgScale = ((screenH - 1) / 100) + 1; if (canvasW > 320) bgScale = ((canvasH - 1) / 100) + 1;
else bgScale = ((screenH - 34) / 100) + 1; else bgScale = ((canvasH - 34) / 100) + 1;
for (y = 0; y < viewH; y += bgScale) for (y = 0; y < viewH; y += bgScale)
drawRect(0, y, screenW, bgScale, 156 + (y / bgScale)); drawRect(0, y, canvasW, bgScale, 156 + (y / bgScale));
// Show sun / moon / etc. // Show sun / moon / etc.
...@@ -228,7 +228,7 @@ void Level::draw () { ...@@ -228,7 +228,7 @@ void Level::draw () {
dst.x = (viewW * 4) / 5; dst.x = (viewW * 4) / 5;
dst.y = (viewH * 3) / 25; dst.y = (viewH * 3) / 25;
src.y = TTOI(skyOrb); src.y = TTOI(skyOrb);
SDL_BlitSurface(tileSet, &src, screen, &dst); SDL_BlitSurface(tileSet, &src, canvas, &dst);
} }
...@@ -264,7 +264,7 @@ void Level::draw () { ...@@ -264,7 +264,7 @@ void Level::draw () {
dst.x = TTOI(x) - (vX & 31); dst.x = TTOI(x) - (vX & 31);
dst.y = TTOI(y) - (vY & 31); dst.y = TTOI(y) - (vY & 31);
src.y = TTOI(ge->tile); src.y = TTOI(ge->tile);
SDL_BlitSurface(tileSet, &src, screen, &dst); SDL_BlitSurface(tileSet, &src, canvas, &dst);
} }
...@@ -317,7 +317,7 @@ void Level::draw () { ...@@ -317,7 +317,7 @@ void Level::draw () {
dst.y = TTOI(y) - (vY & 31); dst.y = TTOI(y) - (vY & 31);
if (ticks & 64) src.y = TTOI(eventSet[ge->event][E_YAXIS]); if (ticks & 64) src.y = TTOI(eventSet[ge->event][E_YAXIS]);
else src.y = TTOI(eventSet[ge->event][E_MULTIPURPOSE]); else src.y = TTOI(eventSet[ge->event][E_MULTIPURPOSE]);
SDL_BlitSurface(tileSet, &src, screen, &dst); SDL_BlitSurface(tileSet, &src, canvas, &dst);
} }
...@@ -328,7 +328,7 @@ void Level::draw () { ...@@ -328,7 +328,7 @@ void Level::draw () {
dst.x = TTOI(x) - (vX & 31); dst.x = TTOI(x) - (vX & 31);
dst.y = TTOI(y) - (vY & 31); dst.y = TTOI(y) - (vY & 31);
src.y = TTOI(ge->tile); src.y = TTOI(ge->tile);
SDL_BlitSurface(tileSet, &src, screen, &dst); SDL_BlitSurface(tileSet, &src, canvas, &dst);
} }
...@@ -337,13 +337,13 @@ void Level::draw () { ...@@ -337,13 +337,13 @@ void Level::draw () {
} }
// Temporary lines showing the water level // Temporary lines showing the water level
drawRect(0, FTOI(waterLevel - viewY), screenW, 2, 24); drawRect(0, FTOI(waterLevel - viewY), canvasW, 2, 24);
drawRect(0, FTOI(waterLevel - viewY) + 3, screenW, 1, 24); drawRect(0, FTOI(waterLevel - viewY) + 3, canvasW, 1, 24);
drawRect(0, FTOI(waterLevel - viewY) + 6, screenW, 1, 24); drawRect(0, FTOI(waterLevel - viewY) + 6, canvasW, 1, 24);
drawRect(0, FTOI(waterLevel - viewY) + 10, screenW, 1, 24); drawRect(0, FTOI(waterLevel - viewY) + 10, canvasW, 1, 24);
SDL_SetClipRect(screen, NULL); SDL_SetClipRect(canvas, NULL);
// Show panel // Show panel
...@@ -355,48 +355,48 @@ void Level::draw () { ...@@ -355,48 +355,48 @@ void Level::draw () {
&dst); &dst);
dst.x = 0; dst.x = 0;
dst.y = screenH - 33; dst.y = canvasH - 33;
SDL_BlitSurface(panel, NULL, screen, &dst); SDL_BlitSurface(panel, NULL, canvas, &dst);
drawRect(0, screenH - 1, 320, 1, BLACK); drawRect(0, canvasH - 1, 320, 1, BLACK);
// Show panel data // Show panel data
// Show score // Show score
panelSmallFont->showNumber(localPlayer->getScore(), 84, screenH - 27); panelSmallFont->showNumber(localPlayer->getScore(), 84, canvasH - 27);
// Show time remaining // Show time remaining
if (endTime > ticks) x = endTime - ticks; if (endTime > ticks) x = endTime - ticks;
else x = 0; else x = 0;
y = x / (60 * 1000); y = x / (60 * 1000);
panelSmallFont->showNumber(y, 116, screenH - 27); panelSmallFont->showNumber(y, 116, canvasH - 27);
x -= (y * 60 * 1000); x -= (y * 60 * 1000);
y = x / 1000; y = x / 1000;
panelSmallFont->showNumber(y, 136, screenH - 27); panelSmallFont->showNumber(y, 136, canvasH - 27);
x -= (y * 1000); x -= (y * 1000);
y = x / 100; y = x / 100;
panelSmallFont->showNumber(y, 148, screenH - 27); panelSmallFont->showNumber(y, 148, canvasH - 27);
// Show lives // Show lives
panelSmallFont->showNumber(localPlayer->getLives(), 124, screenH - 13); panelSmallFont->showNumber(localPlayer->getLives(), 124, canvasH - 13);
// Show planet number // Show planet number
if (worldNum <= 41) // Main game levels if (worldNum <= 41) // Main game levels
panelSmallFont->showNumber((worldNum % 3) + 1, 184, screenH - 13); panelSmallFont->showNumber((worldNum % 3) + 1, 184, canvasH - 13);
else if ((worldNum >= 50) && (worldNum <= 52)) // Christmas levels else if ((worldNum >= 50) && (worldNum <= 52)) // Christmas levels
panelSmallFont->showNumber(worldNum - 49, 184, screenH - 13); panelSmallFont->showNumber(worldNum - 49, 184, canvasH - 13);
else panelSmallFont->showNumber(worldNum, 184, screenH - 13); else panelSmallFont->showNumber(worldNum, 184, canvasH - 13);
// Show level number // Show level number
panelSmallFont->showNumber(levelNum + 1, 196, screenH - 13); panelSmallFont->showNumber(levelNum + 1, 196, canvasH - 13);
// Show ammo // Show ammo
if (localPlayer->getAmmo(false) == -1) if (localPlayer->getAmmo(false) == -1)
panelSmallFont->showString(":;", 225, screenH - 13); panelSmallFont->showString(":;", 225, canvasH - 13);
else panelSmallFont->showNumber(localPlayer->getAmmo(true), 245, else panelSmallFont->showNumber(localPlayer->getAmmo(true), 245,
screenH - 13); canvasH - 13);
// Draw the health bar // Draw the health bar
...@@ -428,7 +428,7 @@ void Level::draw () { ...@@ -428,7 +428,7 @@ void Level::draw () {
else if (x <= 1) x = 32 + (((ticks / 75) * 4) & 15); else if (x <= 1) x = 32 + (((ticks / 75) * 4) & 15);
// Draw energy bar // Draw energy bar
drawRect(dst.x, screenH - 13, dst.w, 7, x); drawRect(dst.x, canvasH - 13, dst.w, 7, x);
dst.x += dst.w; dst.x += dst.w;
dst.w = 64 - dst.w; dst.w = 64 - dst.w;
...@@ -437,7 +437,7 @@ void Level::draw () { ...@@ -437,7 +437,7 @@ void Level::draw () {
// Fill in remaining energy bar space with black // Fill in remaining energy bar space with black
drawRect(dst.x, screenH - 13, dst.w, 7, BLACK); drawRect(dst.x, canvasH - 13, dst.w, 7, BLACK);
return; return;
......
...@@ -490,10 +490,10 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -490,10 +490,10 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
clearScreen(0); clearScreen(0);
x = (screenW >> 1) - ((strlen(string) + strlen(ext)) << 2); x = (canvasW >> 1) - ((strlen(string) + strlen(ext)) << 2);
x = fontmn2->showString("LOADING ", x - 60, (screenH >> 1) - 16); x = fontmn2->showString("LOADING ", x - 60, (canvasH >> 1) - 16);
x = fontmn2->showString(string, x, (screenH >> 1) - 16); x = fontmn2->showString(string, x, (canvasH >> 1) - 16);
fontmn2->showString(ext, x, (screenH >> 1) - 16); fontmn2->showString(ext, x, (canvasH >> 1) - 16);
delete[] string; delete[] string;
......
...@@ -58,7 +58,7 @@ extern char KOpenJazzPath[256]; ...@@ -58,7 +58,7 @@ extern char KOpenJazzPath[256];
#endif #endif
#ifdef SCALE #ifdef SCALE
#include "scale2x/scalebit.h" #include "io/gfx/scale2x/scalebit.h"
#endif #endif
int loadMain (int argc, char *argv[]) { int loadMain (int argc, char *argv[]) {
...@@ -66,6 +66,9 @@ int loadMain (int argc, char *argv[]) { ...@@ -66,6 +66,9 @@ int loadMain (int argc, char *argv[]) {
File *file; File *file;
unsigned char *pixels, *sorted; unsigned char *pixels, *sorted;
int count, x, y; int count, x, y;
#ifndef SCALE
int scaleFactor;
#endif
// Determine paths // Determine paths
...@@ -195,18 +198,14 @@ int loadMain (int argc, char *argv[]) { ...@@ -195,18 +198,14 @@ int loadMain (int argc, char *argv[]) {
// Read video settings // Read video settings
screenW = file->loadShort(); screenW = file->loadShort();
screenH = file->loadShort(); screenH = file->loadShort();
#ifdef SCALE
scalar = file->loadChar();
#else
scalar = 1;
file->loadChar();
#endif
#ifdef FULLSCREEN_ONLY scaleFactor = file->loadChar();
file->loadChar(); #ifndef FULLSCREEN_ONLY
#else fullscreen = scaleFactor & 1;
fullscreen = file->loadChar();
#endif #endif
scaleFactor >>= 1;
if (scaleFactor > 4) scaleFactor = 1;
// Read controls // Read controls
for (count = 0; count < CONTROLS - 4; count++) for (count = 0; count < CONTROLS - 4; count++)
...@@ -255,22 +254,31 @@ int loadMain (int argc, char *argv[]) { ...@@ -255,22 +254,31 @@ int loadMain (int argc, char *argv[]) {
#endif #endif
// Generate the logical palette
for (count = 0; count < 256; count++)
logicalPalette[count].r = logicalPalette[count].g =
logicalPalette[count].b = count;
// Create the game's window // Create the game's window
currentPalette = logicalPalette; currentPalette = logicalPalette;
canvas = screen = NULL;
#ifdef FULLSCREEN_ONLY #ifndef FULLSCREEN_ONLY
createFullscreen(); if (!fullscreen) createWindow();
#else else {
if (fullscreen) createFullscreen();
else createWindow();
#endif #endif
#ifdef SCALE SDL_ShowCursor(SDL_DISABLE);
if (!screen_scaled) { createFullscreen();
#else
if (!screen) { #ifndef FULLSCREEN_ONLY
}
#endif #endif
if (!screen) {
logError("Could not set video mode", SDL_GetError()); logError("Could not set video mode", SDL_GetError());
delete characterName; delete characterName;
...@@ -287,15 +295,7 @@ int loadMain (int argc, char *argv[]) { ...@@ -287,15 +295,7 @@ int loadMain (int argc, char *argv[]) {
if (SDL_NumJoysticks() > 0) SDL_JoystickOpen(0); if (SDL_NumJoysticks() > 0) SDL_JoystickOpen(0);
// Generate the logical palette
for (count = 0; count < 256; count++)
logicalPalette[count].r = logicalPalette[count].g =
logicalPalette[count].b = count;
restorePalette(screen); restorePalette(screen);
#ifdef SCALE
restorePalette(screen_scaled);
#endif
firstPE = NULL; firstPE = NULL;
...@@ -464,6 +464,9 @@ void freeMain () { ...@@ -464,6 +464,9 @@ void freeMain () {
File *file; File *file;
int count; int count;
#ifndef SCALE
int scaleFactor = 1;
#endif
delete net; delete net;
...@@ -483,7 +486,7 @@ void freeMain () { ...@@ -483,7 +486,7 @@ void freeMain () {
SDL_FreeSurface(panelAmmo[4]); SDL_FreeSurface(panelAmmo[4]);
#ifdef SCALE #ifdef SCALE
SDL_FreeSurface(screen); if (canvas != screen) SDL_FreeSurface(canvas);
#endif #endif
closeAudio(); closeAudio();
...@@ -509,17 +512,12 @@ void freeMain () { ...@@ -509,17 +512,12 @@ void freeMain () {
// Write video settings // Write video settings
file->storeShort(screenW); file->storeShort(screenW);
file->storeShort(screenH); file->storeShort(screenH);
#ifdef SCALE scaleFactor <<= 1;
file->storeChar(scalar); #ifndef FULLSCREEN_ONLY
#else scaleFactor |= fullscreen? 1: 0;
file->storeChar(1);
#endif
#ifdef FULLSCREEN_ONLY
file->storeChar(1);
#else
file->storeChar(fullscreen? ~0: 0);
#endif #endif
file->storeChar(scaleFactor);
// Write controls // Write controls
for (count = 0; count < CONTROLS - 4; count++) for (count = 0; count < CONTROLS - 4; count++)
...@@ -572,25 +570,18 @@ int loop (int type) { ...@@ -572,25 +570,18 @@ int loop (int type) {
// Show everything that has been drawn so far // Show everything that has been drawn so far
#ifdef SCALE #ifdef SCALE
if (scalar>1) { if (canvas != screen) {
int depth = screen_scaled->format->BytesPerPixel;
scale(scaleFactor,
scale(scalar, screen_scaled->pixels, screen->w*depth*scalar, screen->pixels, screen->w*depth, screen->pixels, screen->pitch,
depth, screen->w, screen->h ); canvas->pixels, canvas->pitch,
screen->format->BytesPerPixel, canvas->w, canvas->h);
//Simple2x((unsigned char*)screen->pixels, screen->w*depth, 0, (unsigned char*)screen_scaled->pixels, screen->w*depth*2,
// screen->w, screen->h );
}
else
{
SDL_BlitSurface(screen, NULL, screen_scaled, NULL);
} }
SDL_Flip(screen_scaled);
#else
SDL_Flip(screen);
#endif #endif
SDL_Flip(screen);
prevTicks = globalTicks; prevTicks = globalTicks;
globalTicks = SDL_GetTicks(); globalTicks = SDL_GetTicks();
...@@ -609,8 +600,17 @@ int loop (int type) { ...@@ -609,8 +600,17 @@ int loop (int type) {
fullscreen = !fullscreen; fullscreen = !fullscreen;
if (fullscreen) createFullscreen(); if (fullscreen) {
else createWindow();
SDL_ShowCursor(SDL_DISABLE);
createFullscreen();
} else {
createWindow();
SDL_ShowCursor(SDL_ENABLE);
}
} }
#endif #endif
...@@ -649,31 +649,15 @@ int loop (int type) { ...@@ -649,31 +649,15 @@ int loop (int type) {
screenW = event.resize.w; screenW = event.resize.w;
screenH = event.resize.h; screenH = event.resize.h;
#ifdef SCALE
screen_scaled = SDL_SetVideoMode(screenW*scalar, screenH*scalar, 8,
SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_HWSURFACE |
SDL_HWPALETTE);
if (screen)
SDL_FreeSurface(screen);
screen = SDL_CreateRGBSurface(SDL_HWSURFACE, screenW, screenH, 8, 0, 0, 0, 0);
#else
screen = SDL_SetVideoMode(screenW, screenH, 8,
SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_HWSURFACE |
SDL_HWPALETTE);
#endif
// The absence of a break statement is intentional createWindow();
break;
case SDL_VIDEOEXPOSE: case SDL_VIDEOEXPOSE:
SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256); SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256); SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256);
#ifdef SCALE
SDL_SetPalette(screen_scaled, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen_scaled, SDL_PHYSPAL, currentPalette, 0, 256);
#endif
break; break;
#endif #endif
...@@ -705,10 +689,6 @@ int loop (int type) { ...@@ -705,10 +689,6 @@ int loop (int type) {
firstPE->apply(shownPalette, false, globalTicks - prevTicks); firstPE->apply(shownPalette, false, globalTicks - prevTicks);
SDL_SetPalette(screen, SDL_PHYSPAL, shownPalette, 0, 256); SDL_SetPalette(screen, SDL_PHYSPAL, shownPalette, 0, 256);
#ifdef SCALE
SDL_SetPalette(screen_scaled, SDL_PHYSPAL, shownPalette, 0, 256);
#endif
} else { } else {
...@@ -732,7 +712,7 @@ int main(int argc, char *argv[]) { ...@@ -732,7 +712,7 @@ int main(int argc, char *argv[]) {
Scene *scene = NULL; Scene *scene = NULL;
int scene_result = E_NONE; int scene_result = E_NONE;
// Initialise SDL // Initialise SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK |
...@@ -771,11 +751,11 @@ int main(int argc, char *argv[]) { ...@@ -771,11 +751,11 @@ int main(int argc, char *argv[]) {
} }
scene_result = scene->play(); scene_result = scene->play();
delete scene; delete scene;
scene = NULL;*/ scene = NULL;*/
if (scene_result != E_QUIT) { if (scene_result != E_QUIT) {
// Load the menu // Load the menu
try { try {
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Part of the OpenJazz project * Part of the OpenJazz project
* *
* *
* Copyright (c) 2005-2009 Alister Thomson * Copyright (c) 2005-2010 Alister Thomson
* *
* OpenJazz is distributed under the terms of * OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0 * the GNU General Public License, version 2.0
...@@ -59,8 +59,8 @@ int Menu::newGameDifficulty (int mode, int levelNum, int worldNum) { ...@@ -59,8 +59,8 @@ int Menu::newGameDifficulty (int mode, int levelNum, int worldNum) {
if (count == difficulty) fontmn2->mapPalette(240, 8, 114, 16); if (count == difficulty) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showString(options[count], screenW >> 2, fontmn2->showString(options[count], canvasW >> 2,
(screenH >> 1) + (count << 4) - 32); (canvasH >> 1) + (count << 4) - 32);
if (count == difficulty) fontmn2->restorePalette(); if (count == difficulty) fontmn2->restorePalette();
...@@ -70,9 +70,9 @@ int Menu::newGameDifficulty (int mode, int levelNum, int worldNum) { ...@@ -70,9 +70,9 @@ int Menu::newGameDifficulty (int mode, int levelNum, int worldNum) {
src.y = (difficulty & 2) * 50; src.y = (difficulty & 2) * 50;
src.w = 160; src.w = 160;
src.h = 100; src.h = 100;
dst.x = (screenW >> 1) - 40; dst.x = (canvasW >> 1) - 40;
dst.y = (screenH >> 1) - 50; dst.y = (canvasH >> 1) - 50;
SDL_BlitSurface(screens[2], &src, screen, &dst); SDL_BlitSurface(screens[2], &src, canvas, &dst);
if (controls.release(C_UP)) difficulty = (difficulty + 3) % 4; if (controls.release(C_UP)) difficulty = (difficulty + 3) % 4;
...@@ -171,14 +171,14 @@ int Menu::newGameLevel (int mode) { ...@@ -171,14 +171,14 @@ int Menu::newGameLevel (int mode) {
clearScreen(15); clearScreen(15);
if (option == 0) fontmn2->mapPalette(240, 8, 114, 16); if (option == 0) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showString("choose world:", 32, screenH / 3); fontmn2->showString("choose world:", 32, canvasH / 3);
fontmn2->showNumber(worldNum, 208, screenH / 3); fontmn2->showNumber(worldNum, 208, canvasH / 3);
if (option == 0) fontmn2->restorePalette(); if (option == 0) fontmn2->restorePalette();
else fontmn2->mapPalette(240, 8, 114, 16); else fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showString("choose level:", 32, (screenH << 1) / 3); fontmn2->showString("choose level:", 32, (canvasH << 1) / 3);
fontmn2->showNumber(levelNum, 208, (screenH << 1) / 3); fontmn2->showNumber(levelNum, 208, (canvasH << 1) / 3);
if (option != 0) fontmn2->restorePalette(); if (option != 0) fontmn2->restorePalette();
...@@ -263,15 +263,15 @@ int Menu::newGameEpisode (int mode) { ...@@ -263,15 +263,15 @@ int Menu::newGameEpisode (int mode) {
if ((episode < episodes - 1) || (episode < 6)) { if ((episode < episodes - 1) || (episode < 6)) {
dst.x = screenW - 150; dst.x = canvasW - 150;
dst.y = (screenH - 110) >> 1; dst.y = (canvasH - 110) >> 1;
SDL_BlitSurface(screens[episode + 3], NULL, screen, &dst); SDL_BlitSurface(screens[episode + 3], NULL, canvas, &dst);
} else if ((episode == 10) && (episodes > 6)) { } else if ((episode == 10) && (episodes > 6)) {
dst.x = screenW - 160; dst.x = canvasW - 160;
dst.y = (screenH - 110) >> 1; dst.y = (canvasH - 110) >> 1;
SDL_BlitSurface(screens[episodes + 2], NULL, screen, &dst); SDL_BlitSurface(screens[episodes + 2], NULL, canvas, &dst);
} }
...@@ -280,14 +280,14 @@ int Menu::newGameEpisode (int mode) { ...@@ -280,14 +280,14 @@ int Menu::newGameEpisode (int mode) {
if (count == episode) { if (count == episode) {
fontmn2->mapPalette(240, 8, 79, -80); fontmn2->mapPalette(240, 8, 79, -80);
drawRect((screenW >> 3) - 4, (screenH >> 1) + (count << 4) - 94, drawRect((canvasW >> 3) - 4, (canvasH >> 1) + (count << 4) - 94,
136, 15, 79); 136, 15, 79);
} else if (!exists[count]) } else if (!exists[count])
fontmn2->mapPalette(240, 8, 94, -16); fontmn2->mapPalette(240, 8, 94, -16);
fontmn2->showString(options[count], screenW >> 3, fontmn2->showString(options[count], canvasW >> 3,
(screenH >> 1) + (count << 4) - 92); (canvasH >> 1) + (count << 4) - 92);
if ((count == episode) || (!exists[count])) if ((count == episode) || (!exists[count]))
fontmn2->mapPalette(240, 8, 9, 80); fontmn2->mapPalette(240, 8, 9, 80);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Part of the OpenJazz project * Part of the OpenJazz project
* *
* *
* Copyright (c) 2005-2009 Alister Thomson * Copyright (c) 2005-2010 Alister Thomson
* *
* OpenJazz is distributed under the terms of * OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0 * the GNU General Public License, version 2.0
...@@ -233,13 +233,13 @@ int Menu::main () { ...@@ -233,13 +233,13 @@ int Menu::main () {
clearScreen(28); clearScreen(28);
dst.x = (screenW >> 2) - 72; dst.x = (canvasW >> 2) - 72;
dst.y = screenH - (screenH >> 2); dst.y = canvasH - (canvasH >> 2);
SDL_BlitSurface(screens[14], NULL, screen, &dst); SDL_BlitSurface(screens[14], NULL, canvas, &dst);
dst.x = (screenW - 320) >> 1; dst.x = (canvasW - 320) >> 1;
dst.y = (screenH - 200) >> 1; dst.y = (canvasH - 200) >> 1;
SDL_BlitSurface(screens[0], NULL, screen, &dst); SDL_BlitSurface(screens[0], NULL, canvas, &dst);
switch (option) { switch (option) {
...@@ -299,9 +299,9 @@ int Menu::main () { ...@@ -299,9 +299,9 @@ int Menu::main () {
} }
dst.x = ((screenW - 320) >> 1) + src.x; dst.x = ((canvasW - 320) >> 1) + src.x;
dst.y = ((screenH - 200) >> 1) + src.y; dst.y = ((canvasH - 200) >> 1) + src.y;
SDL_BlitSurface(screens[1], &src, screen, &dst); SDL_BlitSurface(screens[1], &src, canvas, &dst);
} }
......
...@@ -53,7 +53,7 @@ int Menu::message (const char *text) { ...@@ -53,7 +53,7 @@ int Menu::message (const char *text) {
clearScreen(15); clearScreen(15);
// Draw the message // Draw the message
fontmn2->showString(text, screenW >> 2, (screenH >> 1) - 16); fontmn2->showString(text, canvasW >> 2, (canvasH >> 1) - 16);
} }
...@@ -86,8 +86,8 @@ int Menu::generic (const char **optionNames, int options, int *chosen) { ...@@ -86,8 +86,8 @@ int Menu::generic (const char **optionNames, int options, int *chosen) {
if (count == *chosen) fontmn2->mapPalette(240, 8, 114, 16); if (count == *chosen) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showString(optionNames[count], screenW >> 2, fontmn2->showString(optionNames[count], canvasW >> 2,
(screenH >> 1) + (count << 4) - (options << 3)); (canvasH >> 1) + (count << 4) - (options << 3));
if (count == *chosen) fontmn2->restorePalette(); if (count == *chosen) fontmn2->restorePalette();
...@@ -192,20 +192,20 @@ int Menu::textInput (const char *request, char **text) { ...@@ -192,20 +192,20 @@ int Menu::textInput (const char *request, char **text) {
clearScreen(15); clearScreen(15);
// Draw the prompt // Draw the prompt
fontmn2->showString(request, screenW >> 2, (screenH >> 1) - 16); fontmn2->showString(request, canvasW >> 2, (canvasH >> 1) - 16);
// Draw the section of the text before the cursor // Draw the section of the text before the cursor
fontmn2->mapPalette(240, 8, 114, 16); fontmn2->mapPalette(240, 8, 114, 16);
terminate = input[cursor]; terminate = input[cursor];
input[cursor] = 0; input[cursor] = 0;
x = fontmn2->showString(input, (screenW >> 2) + 8, screenH >> 1); x = fontmn2->showString(input, (canvasW >> 2) + 8, canvasH >> 1);
// Draw the cursor // Draw the cursor
drawRect(x, (screenH >> 1) + 10, 8, 2, 79); drawRect(x, (canvasH >> 1) + 10, 8, 2, 79);
// Draw the section of text after the cursor // Draw the section of text after the cursor
input[cursor] = terminate; input[cursor] = terminate;
fontmn2->showString(input + cursor, x, screenH >> 1); fontmn2->showString(input + cursor, x, canvasH >> 1);
fontmn2->restorePalette(); fontmn2->restorePalette();
......
...@@ -88,18 +88,18 @@ int Menu::setupKeyboard () { ...@@ -88,18 +88,18 @@ int Menu::setupKeyboard () {
for (count = 0; count < PCONTROLS; count++) { for (count = 0; count < PCONTROLS; count++) {
if (count < progress) if (count < progress)
fontmn2->showString("okay", (screenW >> 2) + 176, fontmn2->showString("okay", (canvasW >> 2) + 176,
(screenH >> 1) + (count << 4) - 56); (canvasH >> 1) + (count << 4) - 56);
else if (count == progress) fontmn2->mapPalette(240, 8, 114, 16); else if (count == progress) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showString(options[count], screenW >> 2, fontmn2->showString(options[count], canvasW >> 2,
(screenH >> 1) + (count << 4) - 56); (canvasH >> 1) + (count << 4) - 56);
if (count == progress) { if (count == progress) {
fontmn2->showString("press key", (screenW >> 2) + 112, fontmn2->showString("press key", (canvasW >> 2) + 112,
(screenH >> 1) + (count << 4) - 56); (canvasH >> 1) + (count << 4) - 56);
fontmn2->restorePalette(); fontmn2->restorePalette();
...@@ -230,18 +230,15 @@ int Menu::setupJoystick () { ...@@ -230,18 +230,15 @@ int Menu::setupJoystick () {
for (count = 0; count < 7; count++) { for (count = 0; count < 7; count++) {
if (count < progress) if (count < progress)
fontmn2->showString("okay", (screenW >> 2) + 176, fontmn2->showString("okay", (canvasW >> 2) + 176, (canvasH >> 1) + (count << 4) - 56);
(screenH >> 1) + (count << 4) - 56);
else if (count == progress) fontmn2->mapPalette(240, 8, 114, 16); else if (count == progress) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showString(options[count], screenW >> 2, fontmn2->showString(options[count], canvasW >> 2, (canvasH >> 1) + (count << 4) - 56);
(screenH >> 1) + (count << 4) - 56);
if (count == progress) { if (count == progress) {
fontmn2->showString("press control", (screenW >> 2) + 112, fontmn2->showString("press control", (canvasW >> 2) + 112, (canvasH >> 1) + (count << 4) - 56);
(screenH >> 1) + (count << 4) - 56);
fontmn2->restorePalette(); fontmn2->restorePalette();
...@@ -266,28 +263,24 @@ int Menu::setupResolution () { ...@@ -266,28 +263,24 @@ int Menu::setupResolution () {
int dimension, count, maxW, maxH; int dimension, count, maxW, maxH;
#ifdef SCALE #ifdef SCALE
int minS = 1; #define DIMENSIONS 3
int maxS = 4; #define minS 1
#define minD 0 #define maxS 4
#define maxD 2
if ( scaleFactor < minS || scaleFactor > maxS )
if ( scalar < minS || scalar > maxS ) scaleFactor = 1;
scalar = 1;
#else #else
#define minD 0 #define DIMENSIONS 2
#define maxD 1
#endif #endif
dimension = 0; dimension = 0;
#ifndef FULLSCREEN_ONLY #ifndef FULLSCREEN_ONLY
if (!fullscreen) if (!fullscreen)
resolutions = SDL_ListModes(NULL, resolutions = SDL_ListModes(NULL, V_WINDOWED);
SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE); else
else #endif
#endif resolutions = SDL_ListModes(NULL, V_FULLSCREEN);
resolutions = SDL_ListModes(NULL,
SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE);
#if defined(WIZ) || defined(GP2X) #if defined(WIZ) || defined(GP2X)
...@@ -327,84 +320,67 @@ int Menu::setupResolution () { ...@@ -327,84 +320,67 @@ int Menu::setupResolution () {
// Show screen corners // Show screen corners
drawRect(0, 0, 32, 32, 79); drawRect(0, 0, 32, 32, 79);
drawRect(screenW - 32, 0, 32, 32, 79); drawRect(canvasW - 32, 0, 32, 32, 79);
drawRect(screenW - 32, screenH - 32, 32, 32, 79); drawRect(canvasW - 32, canvasH - 32, 32, 32, 79);
drawRect(0, screenH - 32, 32, 32, 79); drawRect(0, canvasH - 32, 32, 32, 79);
// X 1
fontmn2->showString("x", (screenW >> 2) + 40, screenH >> 1);
// X 2
fontmn2->showString("x", (screenW >> 2) + 112, screenH >> 1);
// Width // Width
if (dimension == 0) fontmn2->mapPalette(240, 8, 114, 16); if (dimension == 0) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showNumber(screenW, (canvasW >> 2) + 32, canvasH >> 1);
fontmn2->showNumber(screenW, (screenW >> 2) + 32, screenH >> 1); if (dimension == 0) fontmn2->restorePalette();
// Height // X
if (dimension == 0 || dimension == 2) fontmn2->restorePalette(); fontmn2->showString("x", (canvasW >> 2) + 40, canvasH >> 1);
else fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showNumber(screenH, (screenW >> 2) + 104, screenH >> 1);
// Scalar
if (dimension == 0 || dimension == 1) fontmn2->restorePalette();
else fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showNumber(scalar, (screenW >> 2) + 150, screenH >> 1);
if (dimension != 0) fontmn2->restorePalette(); // Height
if (dimension == 1) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showNumber(screenH, (canvasW >> 2) + 104, canvasH >> 1);
if (dimension == 1) fontmn2->restorePalette();
#ifdef SCALE
// X 2
fontmn2->showString("x", (canvasW >> 2) + 112, canvasH >> 1);
count = 0; // Scale
if (dimension == 2) fontmn2->mapPalette(240, 8, 114, 16);
fontmn2->showNumber(scaleFactor, (canvasW >> 2) + 150, canvasH >> 1);
if (dimension == 2) fontmn2->restorePalette();
#endif
if (controls.release(C_LEFT)) {
dimension--;
if(dimension<minD) count = 0;
dimension = minD;
}
if (controls.release(C_RIGHT)) { if (controls.release(C_LEFT))
dimension = (dimension + DIMENSIONS - 1) % DIMENSIONS;
dimension++;
if(dimension>maxD) if (controls.release(C_RIGHT))
dimension = maxD; dimension = (dimension + 1) % DIMENSIONS;
}
if (controls.release(C_UP)) { if (controls.release(C_UP)) {
if ((dimension == 0) && (screenW*scalar < maxW)) { if ((dimension == 0) && (screenW < maxW)) {
while (screenW >= widthOptions[count] && (screenW*scalar)<maxW) count++;
if ((widthOptions[count]*scalar) > maxW) while (screenW >= widthOptions[count]) count++;
count--;
screenW = widthOptions[count]; screenW = widthOptions[count];
} }
if ((dimension == 1) && (screenH*scalar < maxH)) { if ((dimension == 1) && (screenH < maxH)) {
while (screenH >= heightOptions[count]) count++; while (screenH >= heightOptions[count]) count++;
if ((heightOptions[count]*scalar) > maxH)
count--;
screenH = heightOptions[count]; screenH = heightOptions[count];
} }
#ifdef SCALE #ifdef SCALE
if ((dimension == 2) && (scalar < maxS)) { if ((dimension == 2) && (scaleFactor < maxS)) {
if ( screenH*(scalar+1) <= maxH && screenW*(scalar+1) <= maxW ) if ( canvasH*(scaleFactor+1) <= maxH && canvasW*(scaleFactor+1) <= maxW )
{ {
scalar++; scaleFactor++;
count = 1; count = 1;
} }
...@@ -437,9 +413,9 @@ int Menu::setupResolution () { ...@@ -437,9 +413,9 @@ int Menu::setupResolution () {
} }
#ifdef SCALE #ifdef SCALE
if ((dimension == 2) && (scalar > minS)) { if ((dimension == 2) && (scaleFactor > minS)) {
scalar--; scaleFactor--;
count = 1; count = 1;
} }
...@@ -453,14 +429,11 @@ int Menu::setupResolution () { ...@@ -453,14 +429,11 @@ int Menu::setupResolution () {
playSound(S_ORB); playSound(S_ORB);
#ifndef FULLSCREEN_ONLY #ifndef FULLSCREEN_ONLY
if (!fullscreen) if (!fullscreen) createWindow();
{
createWindow();
}
else else
#endif #endif
createFullscreen(); createFullscreen();
} }
} }
......
...@@ -632,9 +632,9 @@ void Player::view (unsigned int ticks, int mspf) { ...@@ -632,9 +632,9 @@ void Player::view (unsigned int ticks, int mspf) {
oldViewY = viewY; oldViewY = viewY;
// Can we see below the panel? // Can we see below the panel?
viewW = screenW; viewW = canvasW;
if (viewW > panel->w) viewH = screenH; if (viewW > panel->w) viewH = canvasH;
else viewH = screenH - 33; else viewH = canvasH - 33;
// Find new position // Find new position
......
...@@ -45,16 +45,16 @@ ...@@ -45,16 +45,16 @@
* 0x13, 0x04, Offset to datablock * 0x13, 0x04, Offset to datablock
* 0x17, 0x02, Number of script items * 0x17, 0x02, Number of script items
* 0x19, 0x4* Number of script items, Offset to Scripts * 0x19, 0x4* Number of script items, Offset to Scripts
* *
* ----, 0x02 Number of data items * ----, 0x02 Number of data items
* * 0x19, 0x4* Number of script items, Offset to datablocks * * 0x19, 0x4* Number of script items, Offset to datablocks
* *
*/ */
// These are the known script types // These are the known script types
enum enum
{ {
ESceneMusic = 0x2A, ESceneMusic = 0x2A,
ESceneFadeType = 0x3F, ESceneFadeType = 0x3F,
ESceneTextBlock = 0x40, ESceneTextBlock = 0x40,
ESceneTextColour = 0x41, ESceneTextColour = 0x41,
ESceneFontFun = 0x45, ESceneFontFun = 0x45,
...@@ -96,14 +96,14 @@ ScriptText::ScriptText() { ...@@ -96,14 +96,14 @@ ScriptText::ScriptText() {
extraLineHeight = -1; extraLineHeight = -1;
text = NULL; text = NULL;
} }
ScriptText::~ScriptText() { ScriptText::~ScriptText() {
if (text) delete[] text; if (text) delete[] text;
} }
ScriptPage::ScriptPage() { ScriptPage::ScriptPage() {
pageTime = 0; pageTime = 0;
noScriptTexts = 0; noScriptTexts = 0;
backgrounds = 0; backgrounds = 0;
...@@ -127,8 +127,8 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -127,8 +127,8 @@ void Scene::ParseAni(File* f, int dataIndex) {
while(type != 0x4C50) { while(type != 0x4C50) {
type = f->loadShort(); type = f->loadShort();
if(type == 0x4C53) { // SL if(type == 0x4C53) { // SL
/*unsigned short int offset =*/ f->loadShort(); /*unsigned short int offset =*/ f->loadShort();
unsigned char noSounds = f->loadChar(); unsigned char noSounds = f->loadChar();
for(loop = 0;loop<noSounds;loop++) { for(loop = 0;loop<noSounds;loop++) {
...@@ -137,14 +137,14 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -137,14 +137,14 @@ void Scene::ParseAni(File* f, int dataIndex) {
delete[] soundName; delete[] soundName;
} }
} }
else if(type == 0x4C50) {// PL else if(type == 0x4C50) {// PL
int pos = f->tell(); int pos = f->tell();
int nextPos = f->tell(); int nextPos = f->tell();
LOG("PL Read position", pos); LOG("PL Read position", pos);
unsigned short int len = f->loadShort(); unsigned short int len = f->loadShort();
unsigned char* buffer = f->loadBlock(len); unsigned char* buffer = f->loadBlock(len);
for (int count = 0; count < 256; count++) { for (int count = 0; count < 256; count++) {
// Palette entries are 6-bit // Palette entries are 6-bit
// Shift them upwards to 8-bit, and fill in the lower 2 bits // Shift them upwards to 8-bit, and fill in the lower 2 bits
paletteInfos[paletteIndex].palette[count].r = (buffer[count * 3] << 2) + (buffer[count * 3] >> 4); paletteInfos[paletteIndex].palette[count].r = (buffer[count * 3] << 2) + (buffer[count * 3] >> 4);
...@@ -152,22 +152,22 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -152,22 +152,22 @@ void Scene::ParseAni(File* f, int dataIndex) {
(buffer[(count * 3) + 1] >> 4); (buffer[(count * 3) + 1] >> 4);
paletteInfos[paletteIndex].palette[count].b = (buffer[(count * 3) + 2] << 2) + paletteInfos[paletteIndex].palette[count].b = (buffer[(count * 3) + 2] << 2) +
(buffer[(count * 3) + 2] >> 4); (buffer[(count * 3) + 2] >> 4);
} }
delete[] buffer; delete[] buffer;
paletteInfos[paletteIndex].dataIndex = dataIndex; paletteInfos[paletteIndex].dataIndex = dataIndex;
paletteIndex++; paletteIndex++;
unsigned short int value = 0x4646; unsigned short int value = 0x4646;
int items = 0; int items = 0;
int validValue = true; int validValue = true;
pos = f->tell(); pos = f->tell();
LOG("PL Read position start", pos); LOG("PL Read position start", pos);
while(validValue) while(validValue)
{ {
value = f->loadShort(); value = f->loadShort();
LOG("PL Read block start tag", value); LOG("PL Read block start tag", value);
unsigned short int size= f->loadShort(); unsigned short int size= f->loadShort();
...@@ -176,29 +176,29 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -176,29 +176,29 @@ void Scene::ParseAni(File* f, int dataIndex) {
// next pos is intial position + size and four bytes header // next pos is intial position + size and four bytes header
nextPos+=(size); nextPos+=(size);
switch(value) switch(value)
{ {
case 0x455F: case 0x455F:
validValue = false; validValue = false;
break; break;
case 0x3131: case 0x3131:
{ {
// Skip back size header, this is read by the surface reader // Skip back size header, this is read by the surface reader
f->seek(-2, false); f->seek(-2, false);
SDL_Surface* image = f->loadSurface(320, 200, true); SDL_Surface* image = f->loadSurface(320, 200, true);
SDL_Rect dst; SDL_Rect dst;
dst.x = 0; dst.x = 0;
dst.y = 0; dst.y = 0;
SDL_BlitSurface(image, NULL, screen, &dst); SDL_BlitSurface(image, NULL, canvas, &dst);
SDL_SetPalette(screen, SDL_PHYSPAL, paletteInfos[paletteIndex-1].palette, 0, 256); SDL_SetPalette(screen, SDL_PHYSPAL, paletteInfos[paletteIndex-1].palette, 0, 256);
currentPalette = paletteInfos[paletteIndex-1].palette; currentPalette = paletteInfos[paletteIndex-1].palette;
}break; }break;
case 0x4c31: case 0x4c31:
{ {
int longvalue = f->loadInt(); int longvalue = f->loadInt();
LOG("PL Anim block value", longvalue); LOG("PL Anim block value", longvalue);
// Skip back size header, this is read by the surface reader // Skip back size header, this is read by the surface reader
//f->seek(-2, false); //f->seek(-2, false);
while(size) { while(size) {
size--; size--;
unsigned char header = f->loadChar(); unsigned char header = f->loadChar();
...@@ -216,7 +216,7 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -216,7 +216,7 @@ void Scene::ParseAni(File* f, int dataIndex) {
case 0xff: case 0xff:
{ {
unsigned char x= f->loadChar(); unsigned char x= f->loadChar();
unsigned char y= f->loadChar(); unsigned char y= f->loadChar();
LOG("PL block x", x); LOG("PL block x", x);
LOG("PL block y", y); LOG("PL block y", y);
size-=2; size-=2;
...@@ -227,9 +227,9 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -227,9 +227,9 @@ void Scene::ParseAni(File* f, int dataIndex) {
}break; }break;
} }
} }
}break; }break;
case 0x4646: case 0x4646:
{ {
while(size) { while(size) {
unsigned char header = f->loadChar(); unsigned char header = f->loadChar();
LOG("PL 4646 block header", header); LOG("PL 4646 block header", header);
...@@ -246,7 +246,7 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -246,7 +246,7 @@ void Scene::ParseAni(File* f, int dataIndex) {
case 0xff: case 0xff:
{ {
unsigned char x= f->loadChar(); unsigned char x= f->loadChar();
unsigned char y= f->loadChar(); unsigned char y= f->loadChar();
LOG("PL block x", x); LOG("PL block x", x);
LOG("PL block y", y); LOG("PL block y", y);
size-=2; size-=2;
...@@ -254,7 +254,7 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -254,7 +254,7 @@ void Scene::ParseAni(File* f, int dataIndex) {
default: default:
{ {
LOG("PL Unknown type", header); LOG("PL Unknown type", header);
}break; }break;
} }
size--; size--;
} }
...@@ -263,7 +263,7 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -263,7 +263,7 @@ void Scene::ParseAni(File* f, int dataIndex) {
case 0x4252: case 0x4252:
case 0x4352: case 0x4352:
case 0x4c52: case 0x4c52:
case 0x4e41: case 0x4e41:
case 0x584d: case 0x584d:
case 0x5252: case 0x5252:
break; break;
...@@ -279,13 +279,13 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -279,13 +279,13 @@ void Scene::ParseAni(File* f, int dataIndex) {
{ {
unsigned char soundIndex = f->loadChar(); unsigned char soundIndex = f->loadChar();
unsigned char soundNote = f->loadChar(); unsigned char soundNote = f->loadChar();
unsigned char soundOffset = f->loadChar(); unsigned char soundOffset = f->loadChar();
LOG("PL Audio tag with index", soundIndex); LOG("PL Audio tag with index", soundIndex);
LOG("PL Audio tag play at ", soundNote); LOG("PL Audio tag play at ", soundNote);
LOG("PL Audio tag play offset ", soundOffset); LOG("PL Audio tag play offset ", soundOffset);
} }
break; break;
case 0: case 0:
{ {
int longvalue = f->loadInt(); int longvalue = f->loadInt();
...@@ -303,15 +303,15 @@ void Scene::ParseAni(File* f, int dataIndex) { ...@@ -303,15 +303,15 @@ void Scene::ParseAni(File* f, int dataIndex) {
break; break;
} }
pos = f->tell(); pos = f->tell();
LOG("PL Read position after block should be", nextPos); LOG("PL Read position after block should be", nextPos);
f->seek(nextPos, true); f->seek(nextPos, true);
if(validValue) { if(validValue) {
items++; items++;
} }
} }
LOG("PL Parsed through number of items skipping 0 items", items); LOG("PL Parsed through number of items skipping 0 items", items);
pos = f->tell(); pos = f->tell();
LOG("PL Read position after parsing anim blocks", pos); LOG("PL Read position after parsing anim blocks", pos);
} }
...@@ -327,14 +327,14 @@ void Scene::ParseData(File *f) { ...@@ -327,14 +327,14 @@ void Scene::ParseData(File *f) {
// AN // AN
if(dataLen == 0x4e41) { if(dataLen == 0x4e41) {
LOG("Data Type", "ANI"); LOG("Data Type", "ANI");
ParseAni(f, loop); ParseAni(f, loop);
} }
else { else {
unsigned char type = f->loadChar(); unsigned char type = f->loadChar();
LOG("Data Type", type); LOG("Data Type", type);
switch(type) switch(type)
{ {
case 3: case 3:
case 4: // image case 4: // image
case 5: case 5:
case 6: case 6:
...@@ -354,9 +354,9 @@ void Scene::ParseData(File *f) { ...@@ -354,9 +354,9 @@ void Scene::ParseData(File *f) {
imageIndex++; imageIndex++;
} }
}break; }break;
default: default:
{ {
LOG("Data Type", "Palette"); LOG("Data Type", "Palette");
LOG("Data Type Palette index", loop); LOG("Data Type Palette index", loop);
f->seek(-3, false); f->seek(-3, false);
...@@ -376,28 +376,28 @@ void Scene::ParseScripts(File *f) { ...@@ -376,28 +376,28 @@ void Scene::ParseScripts(File *f) {
char *string; char *string;
/*int bgIndex = 0;*/ /*int bgIndex = 0;*/
int textAlignment = 0; int textAlignment = 0;
int textFont = 0; int textFont = 0;
for(loop = 0;loop < scriptItems; loop++) for(loop = 0;loop < scriptItems; loop++)
{ {
LOG("\nParse Script", loop); LOG("\nParse Script", loop);
int textPosX = -1; int textPosX = -1;
int textPosY = -1; int textPosY = -1;
int extraheight = -1; int extraheight = -1;
SDL_Rect textRect; SDL_Rect textRect;
bool textRectValid = false; bool textRectValid = false;
f->seek(scriptStarts[loop], true); // Seek to data start f->seek(scriptStarts[loop], true); // Seek to data start
if(f->loadChar() == 0x50) { // Script tag if(f->loadChar() == 0x50) { // Script tag
unsigned short int scriptid = f->loadShort(); unsigned short int scriptid = f->loadShort();
LOG("Script id:", scriptid); LOG("Script id:", scriptid);
int palette = f->loadShort(); int palette = f->loadShort();
LOG("Script default palette", palette); LOG("Script default palette", palette);
scriptPages[loop].paletteIndex = palette; scriptPages[loop].paletteIndex = palette;
unsigned char type = 0; unsigned char type = 0;
bool breakloop = false; bool breakloop = false;
int pos = f->tell(); int pos = f->tell();
while(!breakloop && pos< dataOffsets[0]) { while(!breakloop && pos< dataOffsets[0]) {
type = f->loadChar(); type = f->loadChar();
switch(type) switch(type)
{ {
...@@ -411,12 +411,12 @@ void Scene::ParseScripts(File *f) { ...@@ -411,12 +411,12 @@ void Scene::ParseScripts(File *f) {
case ESceneAnimationIndex: case ESceneAnimationIndex:
{ {
unsigned char aniIndex = f->loadChar(); unsigned char aniIndex = f->loadChar();
LOG("ESceneAnimationIndex:", aniIndex); LOG("ESceneAnimationIndex:", aniIndex);
}break; }break;
case ESceneFadeType: case ESceneFadeType:
{ {
unsigned char fadein = f->loadChar(); unsigned char fadein = f->loadChar();
LOG("ESceneFadeType:", fadein); LOG("ESceneFadeType:", fadein);
}break; }break;
case ESceneBackground: case ESceneBackground:
{ {
...@@ -431,13 +431,13 @@ void Scene::ParseScripts(File *f) { ...@@ -431,13 +431,13 @@ void Scene::ParseScripts(File *f) {
scriptPages[loop].backgrounds++; scriptPages[loop].backgrounds++;
}break; }break;
case ESceneMusic: case ESceneMusic:
{ {
// Music file name // Music file name
string = f->loadString(); string = f->loadString();
LOG("ESceneMusic: ", string); LOG("ESceneMusic: ", string);
scriptPages[loop].musicfile = createString(string); scriptPages[loop].musicfile = createString(string);
delete[] string; delete[] string;
}break; }break;
case ESceneSomethingElse: case ESceneSomethingElse:
{ {
unsigned char value = 0;//f->loadChar(); unsigned char value = 0;//f->loadChar();
...@@ -481,7 +481,7 @@ void Scene::ParseScripts(File *f) { ...@@ -481,7 +481,7 @@ void Scene::ParseScripts(File *f) {
{ {
scriptFonts[noScriptFonts].fontType = EFONTMN2Type; scriptFonts[noScriptFonts].fontType = EFONTMN2Type;
} }
scriptFonts[noScriptFonts].fontId = fontid; scriptFonts[noScriptFonts].fontId = fontid;
noScriptFonts++; noScriptFonts++;
delete[] fontname; delete[] fontname;
...@@ -518,14 +518,14 @@ void Scene::ParseScripts(File *f) { ...@@ -518,14 +518,14 @@ void Scene::ParseScripts(File *f) {
LOG("ESceneFontIndex", value); LOG("ESceneFontIndex", value);
textFont = value; textFont = value;
} }
break; break;
case ESceneTextVAdjust: case ESceneTextVAdjust:
{ {
unsigned short value = f->loadShort(); unsigned short value = f->loadShort();
LOG("ESceneTextVAdjust", value); LOG("ESceneTextVAdjust", value);
extraheight = value; extraheight = value;
} }
break; break;
case ESceneTextSetting: case ESceneTextSetting:
{ {
unsigned short value = f->loadShort(); unsigned short value = f->loadShort();
...@@ -558,7 +558,7 @@ void Scene::ParseScripts(File *f) { ...@@ -558,7 +558,7 @@ void Scene::ParseScripts(File *f) {
}break; }break;
case ESceneTextLine: case ESceneTextLine:
case ESceneTextBlock: case ESceneTextBlock:
{ {
unsigned char datalen = f->loadChar(); unsigned char datalen = f->loadChar();
unsigned char* block = f->loadBlock(datalen); unsigned char* block = f->loadBlock(datalen);
unsigned char pos = 0; unsigned char pos = 0;
...@@ -569,14 +569,14 @@ void Scene::ParseScripts(File *f) { ...@@ -569,14 +569,14 @@ void Scene::ParseScripts(File *f) {
while(datalen>0) { while(datalen>0) {
if(block[pos] == 0x8b) { if(block[pos] == 0x8b) {
sprintf(pagebuf, "%2d", loop+1); sprintf(pagebuf, "%2d", loop+1);
memcpy(&block[pos-1], pagebuf,2); memcpy(&block[pos-1], pagebuf,2);
} }
else if(block[pos] == 0x8a) { else if(block[pos] == 0x8a) {
sprintf(pagebuf, "%2d", scriptItems); sprintf(pagebuf, "%2d", scriptItems);
memcpy(&block[pos-1], pagebuf,2); memcpy(&block[pos-1], pagebuf,2);
} }
else if(block[pos] == 'C') { else if(block[pos] == 'C') {
block[pos]=' '; block[pos]=' ';
} }
else if(block[pos]>='a'-70 && block[pos]<='z'-70) { else if(block[pos]>='a'-70 && block[pos]<='z'-70) {
block[pos]+=70; block[pos]+=70;
...@@ -610,7 +610,7 @@ void Scene::ParseScripts(File *f) { ...@@ -610,7 +610,7 @@ void Scene::ParseScripts(File *f) {
} }
else if(block[pos] == 0x67) { else if(block[pos] == 0x67) {
block[pos]='?'; block[pos]='?';
} }
else if(block[pos] == 0x66) { else if(block[pos] == 0x66) {
block[pos]='.'; block[pos]='.';
} }
...@@ -623,21 +623,21 @@ void Scene::ParseScripts(File *f) { ...@@ -623,21 +623,21 @@ void Scene::ParseScripts(File *f) {
else if(block[pos] == 't') { else if(block[pos] == 't') {
block[pos]='\''; block[pos]='\'';
} }
pos++; pos++;
datalen--; datalen--;
} }
if(orgdatalen > 0) { if(orgdatalen > 0) {
scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text = new char[orgdatalen + 1]; scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text = new char[orgdatalen + 1];
memcpy(scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text, block, orgdatalen); memcpy(scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text, block, orgdatalen);
scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text[orgdatalen] = 0; scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text[orgdatalen] = 0;
LOG("Text data",(char*) scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text); LOG("Text data",(char*) scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text);
} }
else { else {
scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text = new char[1]; scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text = new char[1];
scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text[0] = 0; scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].text[0] = 0;
LOG("Text data", "Empty line"); LOG("Text data", "Empty line");
} }
scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].alignment = textAlignment; scriptPages[loop].scriptTexts[scriptPages[loop].noScriptTexts].alignment = textAlignment;
...@@ -668,19 +668,19 @@ void Scene::ParseScripts(File *f) { ...@@ -668,19 +668,19 @@ void Scene::ParseScripts(File *f) {
} }
break; break;
case ESceneBreaker: case ESceneBreaker:
case 0x3e: case 0x3e:
pos = f->tell(); pos = f->tell();
LOG("Parse script end at position", pos); LOG("Parse script end at position", pos);
LOG("Parse script end with", type); LOG("Parse script end with", type);
breakloop = true; breakloop = true;
f->loadChar(); f->loadChar();
break; break;
default: default:
{ {
pos = f->tell(); pos = f->tell();
LOG("Parse script end at position", pos); LOG("Parse script end at position", pos);
LOG("Parse script breaker", type); LOG("Parse script breaker", type);
breakloop = true; breakloop = true;
} }
break; break;
} }
...@@ -693,9 +693,9 @@ void Scene::ParseScripts(File *f) { ...@@ -693,9 +693,9 @@ void Scene::ParseScripts(File *f) {
Scene::Scene (const char * fileName) { Scene::Scene (const char * fileName) {
File *file; File *file;
int loop; int loop;
noScriptFonts = 0; noScriptFonts = 0;
LOG("\nScene", fileName); LOG("\nScene", fileName);
try { try {
...@@ -708,7 +708,7 @@ Scene::Scene (const char * fileName) { ...@@ -708,7 +708,7 @@ Scene::Scene (const char * fileName) {
} }
imageIndex = 0; imageIndex = 0;
paletteIndex = 0; paletteIndex = 0;
file->seek(0x13, true); // Skip Digital Dimensions header file->seek(0x13, true); // Skip Digital Dimensions header
signed long int dataOffset = file->loadInt(); //get offset pointer to first data block signed long int dataOffset = file->loadInt(); //get offset pointer to first data block
scriptItems = file->loadShort(); // Get number of script items scriptItems = file->loadShort(); // Get number of script items
...@@ -733,7 +733,7 @@ Scene::Scene (const char * fileName) { ...@@ -733,7 +733,7 @@ Scene::Scene (const char * fileName) {
ParseData(file); ParseData(file);
ParseScripts(file); ParseScripts(file);
delete []scriptStarts; delete []scriptStarts;
delete []dataOffsets; delete []dataOffsets;
delete file; delete file;
return; return;
...@@ -768,13 +768,13 @@ int Scene::play () { ...@@ -768,13 +768,13 @@ int Scene::play () {
int newpage = true; int newpage = true;
int fadein = false; int fadein = false;
SDL_Rect textRect = {0,0,320,200}; SDL_Rect textRect = {0,0,320,200};
while (true) { while (true) {
if (loop(NORMAL_LOOP) == E_QUIT) return E_QUIT; if (loop(NORMAL_LOOP) == E_QUIT) return E_QUIT;
if (controls.release(C_ESCAPE)) { if (controls.release(C_ESCAPE)) {
return E_NONE; return E_NONE;
} }
...@@ -782,7 +782,7 @@ int Scene::play () { ...@@ -782,7 +782,7 @@ int Scene::play () {
SDL_Delay(T_FRAME); SDL_Delay(T_FRAME);
int upOrLeft = (controls.release(C_UP) || controls.release(C_LEFT)); int upOrLeft = (controls.release(C_UP) || controls.release(C_LEFT));
if((sceneIndex > 0 && upOrLeft) || controls.release(C_RIGHT) || controls.release(C_DOWN) || controls.release(C_ENTER) || if((sceneIndex > 0 && upOrLeft) || controls.release(C_RIGHT) || controls.release(C_DOWN) || controls.release(C_ENTER) ||
((globalTicks-lastTicks)>=pageTime*1000 && pageTime != 256 && pageTime != 0)) { ((globalTicks-lastTicks)>=pageTime*1000 && pageTime != 256 && pageTime != 0)) {
if(upOrLeft) { if(upOrLeft) {
sceneIndex--; sceneIndex--;
...@@ -795,47 +795,47 @@ int Scene::play () { ...@@ -795,47 +795,47 @@ int Scene::play () {
} }
lastTicks = globalTicks; lastTicks = globalTicks;
// Get bg for this page // Get bg for this page
newpage = true; newpage = true;
pageTime = scriptPages[sceneIndex].pageTime; pageTime = scriptPages[sceneIndex].pageTime;
} }
if(newpage) { if(newpage) {
//firstPE = new FadeOutPaletteEffect(250, firstPE); //firstPE = new FadeOutPaletteEffect(250, firstPE);
textRect.x = 0; textRect.x = 0;
textRect.y = 0; textRect.y = 0;
textRect.w = 320; textRect.w = 320;
textRect.h = 200; textRect.h = 200;
PaletteInfo* paletteInfo = NULL; PaletteInfo* paletteInfo = NULL;
for(int palette = 0;palette<paletteIndex;palette++) { for(int palette = 0;palette<paletteIndex;palette++) {
if(paletteInfos[palette].dataIndex == scriptPages[sceneIndex].paletteIndex) { if(paletteInfos[palette].dataIndex == scriptPages[sceneIndex].paletteIndex) {
paletteInfo = &paletteInfos[palette]; paletteInfo = &paletteInfos[palette];
break; break;
} }
} }
if(paletteInfo != NULL) { if(paletteInfo != NULL) {
// usePalette(paletteInfo->palette); // usePalette(paletteInfo->palette);
currentPalette = paletteInfo->palette; currentPalette = paletteInfo->palette;
fadein = true; fadein = true;
} }
else { else {
restorePalette(screen); restorePalette(screen);
} }
newpage = 0; newpage = 0;
} }
// First draw the backgrounds associated with this page // First draw the backgrounds associated with this page
if(scriptPages[sceneIndex].backgrounds > 0) { if(scriptPages[sceneIndex].backgrounds > 0) {
for(int bg = 0;bg<scriptPages[sceneIndex].backgrounds;bg++) { for(int bg = 0;bg<scriptPages[sceneIndex].backgrounds;bg++) {
imageInfo = FindImage(scriptPages[sceneIndex].bgIndex[bg]); imageInfo = FindImage(scriptPages[sceneIndex].bgIndex[bg]);
if(imageInfo != NULL) { if(imageInfo != NULL) {
dst.x = (scriptPages[sceneIndex].bgPos[bg] & 65535)*2+(screenW - 320) >> 1; dst.x = (scriptPages[sceneIndex].bgPos[bg] & 65535)*2+(canvasW - 320) >> 1;
dst.y = ((scriptPages[sceneIndex].bgPos[bg] & (~65535))>>16)*2+(screenH - 200) >> 1; dst.y = ((scriptPages[sceneIndex].bgPos[bg] & (~65535))>>16)*2+(canvasH - 200) >> 1;
SDL_BlitSurface(imageInfo->image, NULL, screen, &dst); SDL_BlitSurface(imageInfo->image, NULL, canvas, &dst);
} }
} }
} else { } else {
clearScreen(0); clearScreen(0);
...@@ -917,8 +917,8 @@ int Scene::play () { ...@@ -917,8 +917,8 @@ int Scene::play () {
} }
xOffset = ((screenW - 320) >> 1) + textRect.x; xOffset = ((canvasW - 320) >> 1) + textRect.x;
yOffset = ((screenH - 200) >> 1) + textRect.y + y; yOffset = ((canvasH - 200) >> 1) + textRect.y + y;
switch (scriptPages[sceneIndex].scriptTexts[text].alignment) { switch (scriptPages[sceneIndex].scriptTexts[text].alignment) {
...@@ -959,7 +959,7 @@ int Scene::play () { ...@@ -959,7 +959,7 @@ int Scene::play () {
if (fadein) { if (fadein) {
fadein = false; fadein = false;
firstPE = new FadeInPaletteEffect(250, firstPE); firstPE = new FadeInPaletteEffect(250, firstPE);
clearScreen(0); clearScreen(0);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment