scummvm/saga/sysgfx.cpp
Eugene Sandulenko c0772498b6 All graphics and input now is in OSystem.
Only timers left.

svn-id: r13723
2004-05-01 19:41:47 +00:00

304 lines
6.2 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004 The ScummVM project
*
* The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include "saga.h"
#include "reinherit.h"
#include "sysgfx.h"
namespace Saga {
static R_SYSGFX_MODULE SGfxModule;
static OSystem *_system;
static byte cur_pal[R_PAL_ENTRIES * 4];
int SYSGFX_Init(OSystem *system, int width, int height) {
R_SURFACE r_back_buf;
_system = system;
_system->initSize(width, height);
debug(0, "Init screen %dx%d", width, height);
// Convert sdl surface data to R surface data
r_back_buf.buf = (byte *)calloc(1, width * height);
r_back_buf.buf_w = width;
r_back_buf.buf_h = height;
r_back_buf.buf_pitch = width;
r_back_buf.bpp = 8;
r_back_buf.clip_rect.left = 0;
r_back_buf.clip_rect.top = 0;
r_back_buf.clip_rect.right = width - 1;
r_back_buf.clip_rect.bottom = height - 1;
// Set module data
SGfxModule.r_back_buf = r_back_buf;
SGfxModule.init = 1;
return R_SUCCESS;
}
/*
~SysGfx() {
free(SGfxModule.r_back_buf->buf);
}
*/
R_SURFACE *SYSGFX_GetBackBuffer() {
return &SGfxModule.r_back_buf;
}
int SYSGFX_LockSurface(R_SURFACE *surface) {
return 0;
}
int SYSGFX_UnlockSurface(R_SURFACE *surface) {
return 0;
}
int SYSGFX_GetWhite(void) {
return SGfxModule.white_index;
}
int SYSGFX_GetBlack(void) {
return SGfxModule.black_index;
}
int SYSGFX_MatchColor(unsigned long colormask) {
int i;
int red = (colormask & 0x0FF0000UL) >> 16;
int green = (colormask & 0x000FF00UL) >> 8;
int blue = colormask & 0x00000FFUL;
int dr;
int dg;
int db;
long color_delta;
long best_delta = LONG_MAX;
int best_index = 0;
byte *ppal;
for (i = 0, ppal = cur_pal; i < R_PAL_ENTRIES; i++, ppal += 4) {
dr = ppal[0] - red;
dr = ABS(dr);
dg = ppal[1] - green;
dg = ABS(dg);
db = ppal[2] - blue;
db = ABS(db);
ppal[3] = 0;
color_delta = (long)(dr * R_RED_WEIGHT + dg * R_GREEN_WEIGHT + db * R_BLUE_WEIGHT);
if (color_delta == 0) {
return i;
}
if (color_delta < best_delta) {
best_delta = color_delta;
best_index = i;
}
}
return best_index;
}
int SYSGFX_SetPalette(R_SURFACE *surface, PALENTRY *pal) {
byte red;
byte green;
byte blue;
int color_delta;
int best_wdelta = 0;
int best_windex = 0;
int best_bindex = 0;
int best_bdelta = 1000;
int i;
byte *ppal;
for (i = 0, ppal = cur_pal; i < R_PAL_ENTRIES; i++, ppal += 4) {
red = pal[i].red;
ppal[0] = red;
color_delta = red;
green = pal[i].green;
ppal[1] = green;
color_delta += green;
blue = pal[i].blue;
ppal[2] = blue;
color_delta += blue;
ppal[3] = 0;
if (color_delta < best_bdelta) {
best_bindex = i;
best_bdelta = color_delta;
}
if (color_delta > best_wdelta) {
best_windex = i;
best_wdelta = color_delta;
}
}
// Set whitest and blackest color indices
SGfxModule.white_index = best_windex;
SGfxModule.black_index = best_bindex;
_system->setPalette(cur_pal, 0, R_PAL_ENTRIES);
return R_SUCCESS;
}
int SYSGFX_GetCurrentPal(PALENTRY *src_pal) {
int i;
byte *ppal;
for (i = 0, ppal = cur_pal; i < R_PAL_ENTRIES; i++, ppal += 4) {
src_pal[i].red = ppal[0];
src_pal[i].green = ppal[1];
src_pal[i].blue = ppal[2];
}
return R_SUCCESS;
}
int SYSGFX_PalToBlack(R_SURFACE *surface, PALENTRY *src_pal, double percent) {
int i;
//int fade_max = 255;
int new_entry;
byte *ppal;
double fpercent;
if (percent > 1.0) {
percent = 1.0;
}
// Exponential fade
fpercent = percent * percent;
fpercent = 1.0 - fpercent;
// Use the correct percentage change per frame for each palette entry
for (i = 0, ppal = cur_pal; i < R_PAL_ENTRIES; i++, ppal += 4) {
new_entry = (int)(src_pal[i].red * fpercent);
if (new_entry < 0) {
ppal[0] = 0;
} else {
ppal[0] = (byte) new_entry;
}
new_entry = (int)(src_pal[i].green * fpercent);
if (new_entry < 0) {
ppal[1] = 0;
} else {
ppal[1] = (byte) new_entry;
}
new_entry = (int)(src_pal[i].blue * fpercent);
if (new_entry < 0) {
ppal[2] = 0;
} else {
ppal[2] = (byte) new_entry;
}
ppal[3] = 0;
}
_system->setPalette(cur_pal, 0, R_PAL_ENTRIES);
return R_SUCCESS;
}
int SYSGFX_BlackToPal(R_SURFACE *surface, PALENTRY *src_pal, double percent) {
int new_entry;
double fpercent;
int color_delta;
int best_wdelta = 0;
int best_windex = 0;
int best_bindex = 0;
int best_bdelta = 1000;
byte *ppal;
int i;
if (percent > 1.0) {
percent = 1.0;
}
// Exponential fade
fpercent = percent * percent;
fpercent = 1.0 - fpercent;
// Use the correct percentage change per frame for each palette entry
for (i = 0, ppal = cur_pal; i < R_PAL_ENTRIES; i++, ppal += 4) {
new_entry = (int)(src_pal[i].red - src_pal[i].red * fpercent);
if (new_entry < 0) {
ppal[0] = 0;
} else {
ppal[0] = (byte) new_entry;
}
new_entry = (int)(src_pal[i].green - src_pal[i].green * fpercent);
if (new_entry < 0) {
ppal[1] = 0;
} else {
ppal[1] = (byte) new_entry;
}
new_entry = (int)(src_pal[i].blue - src_pal[i].blue * fpercent);
if (new_entry < 0) {
ppal[2] = 0;
} else {
ppal[2] = (byte) new_entry;
}
ppal[3] = 0;
}
// Find the best white and black color indices again
if (percent >= 1.0) {
for (i = 0, ppal = cur_pal; i < R_PAL_ENTRIES; i++, ppal += 4) {
color_delta = ppal[0];
color_delta += ppal[1];
color_delta += ppal[2];
if (color_delta < best_bdelta) {
best_bindex = i;
best_bdelta = color_delta;
}
if (color_delta > best_wdelta) {
best_windex = i;
best_wdelta = color_delta;
}
}
}
_system->setPalette(cur_pal, 0, R_PAL_ENTRIES);
return R_SUCCESS;
}
} // End of namespace Saga