Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/nuvie/core/nuvie_defs.h"
#include "ultima/nuvie/files/nuvie_io_file.h"
#include "ultima/nuvie/misc/u6_misc.h"
#include "ultima/nuvie/conf/configuration.h"
#include "ultima/nuvie/screen/dither.h"
namespace Ultima {
namespace Nuvie {
//dither EGA to CGA
static const uint8 dither_cga_tbl[0x10] = {0, 3, 3, 3, 13, 13, 13, 3, 3, 13, 15, 3, 13, 13, 15, 15};
//static const uint8 dither_cga_tbl[0x10] = {0,1,1,1,2 ,2 ,2 ,1,1,2 ,3 ,1,2 ,2 ,3, 3};
Dither::Dither(const Configuration *cfg) : config(cfg), dither(nullptr), mode(DITHER_NONE) {
set_mode();
if (mode != DITHER_NONE)
load_data();
}
Dither::~Dither() {
if (dither)
free(dither);
}
bool Dither::load_data() {
Common::Path path;
NuvieIOFileRead file;
config_get_path(config, "dither", path);
if (file.open(path) == false)
return false;//fixme better error handling
dither = (uint8 *)malloc(0x200);
if (dither == nullptr)
return false;
file.readToBuf(dither, 0x200);
file.close();
return true;
}
void Dither::set_mode() {
Std::string str_dither_mode;
config->value("config/general/dither_mode", str_dither_mode);
if (str_dither_mode == "none")
mode = DITHER_NONE;
else if (str_dither_mode == "cga") {
mode = DITHER_CGA;
} else if (str_dither_mode == "ega") {
mode = DITHER_EGA;
} else
mode = DITHER_NONE;
return;
}
bool Dither::dither_bitmap(unsigned char *src_buf, uint16 src_w, uint16 src_h, bool has_transparency) {
if (!dither || mode == DITHER_NONE)
return false;
for (int y = 0; y < src_h; y++) {
for (int x = 0; x < src_w; x++) {
uint8 pixel = src_buf[y * src_w + x];
if (has_transparency && pixel == 0xff)
continue;
if (pixel >= 0xe0 && pixel != 0xff)
pixel &= 0xf;
if (((x & 1) ^ (y & 1)) == 0)
pixel = dither[0x100 + pixel];
else
pixel = dither[pixel];
if (mode == DITHER_CGA)
pixel = dither_cga_tbl[pixel];
src_buf[y * src_w + x] = pixel;
}
}
return true;
}
} // End of namespace Nuvie
} // End of namespace Ultima

View File

@@ -0,0 +1,65 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef NUVIE_SCREEN_DITHER_H
#define NUVIE_SCREEN_DITHER_H
namespace Ultima {
namespace Nuvie {
class Configuration;
#define DITHER_NO_TRANSPARENCY false
// Dither modes..
enum DitherMode {
DITHER_NONE = 0,
DITHER_CGA = 1,
DITHER_EGA = 2,
DITHER_HRC = 3 //FIXME add this mode.
};
class Dither {
const Configuration *config;
uint8 *dither;
DitherMode mode;
public:
Dither(const Configuration *cfg);
~Dither();
uint8 get_mode() const {
return mode;
}
bool dither_bitmap(unsigned char *src_buf, uint16 src_w, uint16 src_h, bool has_transparency);
protected:
bool load_data();
void set_mode();
};
} // End of namespace Nuvie
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,162 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/nuvie/core/nuvie_defs.h"
#include "ultima/nuvie/misc/u6_misc.h"
#include "ultima/nuvie/files/nuvie_io_file.h"
#include "ultima/nuvie/conf/configuration.h"
#include "ultima/nuvie/screen/screen.h"
#include "ultima/nuvie/screen/dither.h"
#include "ultima/nuvie/screen/game_palette.h"
#include "common/util.h"
namespace Ultima {
namespace Nuvie {
GamePalette::GamePalette(Screen *s, const Configuration *cfg) : screen(s), config(cfg), counter(0) {
palette = (uint8 *)malloc(768);
memset(palette, 0, 768);
loadPalette();
set_palette();
}
GamePalette::~GamePalette() {
free(palette);
}
void GamePalette::set_palette() {
screen->set_palette(palette);
}
bool GamePalette::loadPalette() {
uint16 i, j;
Common::Path filename;
NuvieIOFileRead file;
Std::string game_name, game_id, pal_name;
config->value("config/GameName", game_name);
config->value("config/GameID", game_id);
pal_name.assign(game_id);
pal_name.append("pal");
config_get_path(config, pal_name, filename);
if (file.open(filename) == false) {
DEBUG(0, LEVEL_ERROR, "loading palette.\n");
return false;
}
unsigned char *buf = file.readAll();
uint8 *pal_ptr = palette;
for (i = 0, j = 0; i < MIN<uint32>(256U, file.get_size() / 3); i++, j += 3) {
pal_ptr[0] = buf[j] << 2;
pal_ptr[1] = buf[j + 1] << 2;
pal_ptr[2] = buf[j + 2] << 2;
pal_ptr += 3;
}
free(buf);
/*
printf("GIMP Palette\nName: SE\n#\n");
for (int i = 0; i < 0x100; i++)
{
for (int j = 0; j < 3; j++)
{
printf("% 3d ", palette[i*3+j]);
}
printf(" untitled\n");
}
*/
uint8 dither_mode = Game::get_game()->get_dither()->get_mode();
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
if (dither_mode == DITHER_NONE)
bg_color = 0x31;
else
bg_color = 0xf;
} else if (Game::get_game()->get_game_type() == NUVIE_GAME_MD)
bg_color = 220;
else // SE
bg_color = 72;
return true;
}
bool GamePalette::loadPaletteIntoBuffer(unsigned char *pal) {
uint16 i, j;
Common::Path filename;
NuvieIOFileRead file;
Std::string game_name, game_id, pal_name;
config->value("config/GameName", game_name);
config->value("config/GameID", game_id);
pal_name.assign(game_id);
pal_name.append("pal");
config_get_path(config, pal_name, filename);
if (file.open(filename) == false) {
DEBUG(0, LEVEL_ERROR, "loading palette.\n");
return false;
}
unsigned char *buf = file.readAll();
uint8 *pal_ptr = pal;
for (i = 0, j = 0; i < 256; i++, j += 3) {
pal_ptr[0] = buf[j] << 2;
pal_ptr[1] = buf[j + 1] << 2;
pal_ptr[2] = buf[j + 2] << 2;
pal_ptr[3] = 0;
pal_ptr += 4;
}
free(buf);
return true;
}
void GamePalette::rotatePalette() {
if (Game::get_game()->anims_paused())
return;
screen->rotate_palette(0xe0, 8); // Fires, braziers, candles
screen->rotate_palette(0xe8, 8); // BluGlo[tm] magical items
if (counter == 0) {
screen->rotate_palette(0xf0, 4); //
screen->rotate_palette(0xf4, 4); // Kitchen Cauldrons
screen->rotate_palette(0xf8, 4); // Poison Field
counter = 1;
} else
counter = 0;
}
} // End of namespace Nuvie
} // End of namespace Ultima

View File

@@ -0,0 +1,59 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef NUVIE_SCREEN_GAME_PALETTE_H
#define NUVIE_SCREEN_GAME_PALETTE_H
#include "ultima/nuvie/screen/screen.h"
namespace Ultima {
namespace Nuvie {
class Configuration;
class GamePalette {
uint8 *palette;
Screen *screen;
const Configuration *config;
uint8 counter;
uint8 bg_color;
public:
GamePalette(Screen *s, const Configuration *cfg);
~GamePalette();
void rotatePalette();
uint8 get_bg_color() const {
return bg_color;
}
void set_palette();
bool loadPaletteIntoBuffer(unsigned char *pal);
protected:
bool loadPalette();
};
} // End of namespace Nuvie
} // End of namespace Ultima
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,165 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef NUVIE_SCREEN_SCREEN_H
#define NUVIE_SCREEN_SCREEN_H
#include "ultima/shared/std/string.h"
#include "ultima/nuvie/core/game.h"
#include "ultima/nuvie/screen/surface.h"
#include "graphics/screen.h"
namespace Ultima {
namespace Nuvie {
class Configuration;
enum LightingStyle {
LightingNone,
LightingSmooth,
LightingOriginal
};
class Screen {
private:
const Configuration *config;
Graphics::Screen *_rawSurface;
RenderSurface *_renderSurface;
bool is_no_darkness;
bool non_square_pixels;
uint16 width;
uint16 height;
Common::Rect shading_rect;
uint8 *shading_data;
uint8 *shading_globe[6];
uint8 shading_ambient;
uint8 *shading_tile[4];
public:
Screen(const Configuration *cfg);
~Screen();
bool init();
bool is_fullscreen() const;
bool is_non_square_pixels() const {
return non_square_pixels;
}
bool toggle_darkness_cheat();
bool toggle_fullscreen();
bool set_fullscreen(bool value);
bool set_palette(const uint8 *palette);
bool set_palette_entry(uint8 idx, uint8 r, uint8 g, uint8 b);
bool rotate_palette(uint8 pos, uint8 length);
bool clear(sint16 x, sint16 y, sint16 w, sint16 h, Common::Rect *clip_rect = nullptr);
Graphics::ManagedSurface *create_sdl_surface_from(const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch);
Graphics::ManagedSurface *create_sdl_surface_8(const byte *src_buf, uint16 src_w, uint16 src_h);
Graphics::ManagedSurface *get_sdl_surface();
uint16 get_width() const {
return width;
}
uint16 get_height() const {
return height;
}
bool fill(uint8 colour_num, uint16 x, uint16 y, sint16 w, sint16 h);
void fade(uint16 dest_x, uint16 dest_y, uint16 src_w, uint16 src_h, uint8 opacity, uint8 fade_bg_color = 0);
void stipple_8bit(uint8 color_num);
void stipple_8bit(uint8 color_num, uint16 x, uint16 y, uint16 w, uint16 h);
void put_pixel(uint8 colour_num, uint16 x, uint16 y);
bool blit(int32 dest_x, int32 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans = false, const Common::Rect *clip_rect = nullptr, uint8 opacity = 255);
void blitbitmap(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_w, uint16 src_h, uint8 fg_color, uint8 bg_color);
void buildalphamap8();
void clearalphamap8(uint16 x, uint16 y, uint16 w, uint16 h, uint8 opacity, bool party_light_source);
void drawalphamap8globe(sint16 x, sint16 y, uint16 radius);
void blitalphamap8(sint16 x, sint16 y, Common::Rect *clip_rect);
LightingStyle get_lighting_style() const {
return lighting_style;
}
LightingStyle get_old_lighting_style() const {
return old_lighting_style; // return the lighting_style before cheats applied
}
uint8 get_ambient() const {
return shading_ambient;
}
void set_ambient(uint8 ambient) {
shading_ambient = ambient;
}
void update();
void update(int x, int y, uint16 w, uint16 h);
void performUpdate();
byte *copy_area(const Common::Rect *area = nullptr, byte *buf = nullptr);
byte *copy_area(const Common::Rect *area, uint16 down_scale);
void restore_area(byte *pixels, const Common::Rect *area = nullptr, byte *target = nullptr, const Common::Rect *target_area = nullptr, bool free_src = true);
void draw_line(int sx, int sy, int ex, int ey, uint8 color);
void get_mouse_location(int *x, int *y) const;
void set_non_square_pixels(bool value);
protected:
LightingStyle lighting_style, old_lighting_style;
bool fill16(uint8 colour_num, uint16 x, uint16 y, sint16 w, sint16 h);
bool fill32(uint8 colour_num, uint16 x, uint16 y, sint16 w, sint16 h);
void fade16(uint16 dest_x, uint16 dest_y, uint16 src_w, uint16 src_h, uint8 opacity, uint8 fade_bg_color);
void fade32(uint16 dest_x, uint16 dest_y, uint16 src_w, uint16 src_h, uint8 opacity, uint8 fade_bg_color);
inline uint16 blendpixel16(uint16 p, uint16 p1, uint8 opacity);
inline uint32 blendpixel32(uint32 p, uint32 p1, uint8 opacity);
inline bool blit16(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans);
inline bool blit16WithOpacity(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans, uint8 opacity);
inline bool blit32(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans);
inline bool blit32WithOpacity(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_bpp, uint16 src_w, uint16 src_h, uint16 src_pitch, bool trans, uint8 opacity);
inline void blitbitmap16(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_w, uint16 src_h, uint8 fg_color, uint8 bg_color);
inline void blitbitmap32(uint16 dest_x, uint16 dest_y, const byte *src_buf, uint16 src_w, uint16 src_h, uint8 fg_color, uint8 bg_color);
byte *copy_area16(const Common::Rect *area, uint16 down_scale);
byte *copy_area32(const Common::Rect *area, uint16 down_scale);
byte *copy_area16(const Common::Rect *area, byte *buf);
byte *copy_area32(const Common::Rect *area, byte *buf);
void restore_area16(byte *pixels, const Common::Rect *area, byte *target = nullptr, const Common::Rect *target_area = nullptr, bool free_src = true);
void restore_area32(byte *pixels, const Common::Rect *area, byte *target = nullptr, const Common::Rect *target_area = nullptr, bool free_src = true);
void set_screen_mode();
};
} // End of namespace Nuvie
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,537 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/nuvie/core/nuvie_defs.h"
#include "ultima/nuvie/screen/surface.h"
#include "common/algorithm.h"
namespace Ultima {
namespace Nuvie {
// Colour shifting values
uint8 RenderSurface::Rloss;
uint8 RenderSurface::Gloss;
uint8 RenderSurface::Bloss;
uint8 RenderSurface::Rloss16;
uint8 RenderSurface::Gloss16;
uint8 RenderSurface::Bloss16;
uint8 RenderSurface::Rshift;
uint8 RenderSurface::Gshift;
uint8 RenderSurface::Bshift;
uint32 RenderSurface::Rmask;
uint32 RenderSurface::Gmask;
uint32 RenderSurface::Bmask;
// Default constructor for no created surface
RenderSurface::RenderSurface() : buffer(0), zbuffer_priv(0), _rawSurface(nullptr),
_disposeSurface(DisposeAfterUse::YES), opengl(0), bytes_per_pixel(0),
bits_per_pixel(0), format_type(0), pixels(0), zbuffer(0), w(0), h(0),
pitch(0), gl(0), gr(0), gt(0), gb(0), lock_count(0) {
}
// Constructor for custom buffer
RenderSurface::RenderSurface(uint32 width, uint32 height, uint32 bpp, byte *p) :
buffer(0), zbuffer_priv(0), _rawSurface(nullptr), _disposeSurface(DisposeAfterUse::YES),
opengl(0), bytes_per_pixel(bpp / 8), bits_per_pixel(bpp), pixels(p), zbuffer(0),
w(width), h(height), pitch(width), gl(0), gr(width), gt(0), gb(height), lock_count(0) {
// Set default formats for the buffer
if (bpp == 32) set_format888();
else set_format565();
}
// Constructor for generic surface (with optional guardband)
RenderSurface::RenderSurface(uint32 width, uint32 height, uint32 bpp, sint32 guard) :
buffer(0), zbuffer_priv(0), _rawSurface(nullptr), _disposeSurface(DisposeAfterUse::YES),
opengl(0), bytes_per_pixel(bpp / 8), bits_per_pixel(bpp), pixels(0), zbuffer(0),
w(width), h(height), pitch(width * (bpp / 8) + 2 * guard * (bpp / 8)),
gl(-guard), gr(guard + width), gt(-guard), gb(guard + height), lock_count(0) {
// Set default formats for the buffer
if (bpp == 32) set_format888();
else set_format565();
buffer = new uint8[pitch * (height + 2 * gb)];
pixels = buffer + (pitch * gb) + gb;
}
// Constructor for sdl surface
RenderSurface::RenderSurface(Graphics::ManagedSurface *surf) :
_rawSurface(surf), _disposeSurface(DisposeAfterUse::NO), w(surf->w), h(surf->h),
pitch(surf->pitch), gr(surf->w), pixels((byte*)surf->getPixels()), buffer(0),
zbuffer_priv(0), opengl(0), bytes_per_pixel(0), bits_per_pixel(0), zbuffer(0),
gl(0), gt(0), gb(surf->h), lock_count(0) {
set_format(&surf->format);
}
// Constructor for opengl surface
RenderSurface::RenderSurface(OpenGL *ogl) : buffer(0), zbuffer_priv(0), _rawSurface(nullptr),
_disposeSurface(DisposeAfterUse::NO), opengl(ogl), bytes_per_pixel(0),
bits_per_pixel(0), format_type(0), pixels(0), zbuffer(0), w(0), h(0), pitch(0),
gl(0), gr(0), gt(0), gb(0), lock_count(0) {
}
RenderSurface::~RenderSurface() {
delete[] buffer;
delete[] zbuffer_priv;
if (_rawSurface && _disposeSurface == DisposeAfterUse::YES)
delete _rawSurface;
}
//
// Set the buffer format from Graphics::PixelFormat
//
void RenderSurface::set_format(const Graphics::PixelFormat *fmt) {
bits_per_pixel = fmt->bytesPerPixel * 8;
bytes_per_pixel = fmt->bytesPerPixel;
Rloss = fmt->rLoss;
Gloss = fmt->gLoss;
Bloss = fmt->bLoss;
Rloss16 = Rloss + 8;
Gloss16 = Gloss + 8;
Bloss16 = Bloss + 8;
Rshift = fmt->rShift;
Gshift = fmt->gShift;
Bshift = fmt->bShift;
Rmask = fmt->rMax() << fmt->rShift;
Gmask = fmt->gMax() << fmt->gShift;
Bmask = fmt->bMax() << fmt->bShift;
// RGB 565
if (Rmask == 0xf800 && Gmask == 0x7e0 && Bmask == 0x1f)
format_type = 565;
// RGB 555
else if (Rmask == 0x7c00 && Gmask == 0x3e0 && Bmask == 0x1f)
format_type = 555;
// RGB 888
else if (Rmask == 0xFF0000 && Gmask == 0x00FF00 && Bmask == 0x0000FF)
format_type = 888;
// RGB 16 Bit Generic
else if (bits_per_pixel == 16)
format_type = 16;
// RGB 32 Bit Generic
else
format_type = 32;
}
//
// Set a custom 565 format
//
void RenderSurface::set_format565(int rsft, int gsft, int bsft) {
bits_per_pixel = 16;
bytes_per_pixel = 2;
// Static Colour shifting values
Rloss = 3;
Gloss = 2;
Bloss = 3;
Rloss16 = Rloss + 8;
Gloss16 = Gloss + 8;
Bloss16 = Bloss + 8;
Rshift = rsft;
Gshift = gsft;
Bshift = bsft;
Rmask = 0x1f << rsft;
Gmask = 0x2f << rsft;
Bmask = 0x1f << rsft;
// RGB 565
if (Rmask == 0xf800 && Gmask == 0x7e0 && Bmask == 0x1f)
format_type = 565;
// RGB 16 Bit Generic
else if (bits_per_pixel == 16)
format_type = 16;
}
//
// Set a custom 555 format
//
void RenderSurface::set_format555(int rsft, int gsft, int bsft) {
bits_per_pixel = 16;
bytes_per_pixel = 2;
// Static Colour shifting values
Rloss = 3;
Gloss = 3;
Bloss = 3;
Rloss16 = Rloss + 8;
Gloss16 = Gloss + 8;
Bloss16 = Bloss + 8;
Rshift = rsft;
Gshift = gsft;
Bshift = bsft;
Rmask = 0x1f << rsft;
Gmask = 0x1f << rsft;
Bmask = 0x1f << rsft;
// RGB 555
if (Rmask == 0x7c00 && Gmask == 0x3e0 && Bmask == 0x1f)
format_type = 555;
// RGB 16 Bit Generic
else if (bits_per_pixel == 16)
format_type = 16;
}
//
// Set a custom 888 format
//
void RenderSurface::set_format888(int rsft, int gsft, int bsft) {
bits_per_pixel = 32;
bytes_per_pixel = 4;
Rloss = 0;
Gloss = 0;
Bloss = 0;
Rloss16 = Rloss + 8;
Gloss16 = Gloss + 8;
Bloss16 = Bloss + 8;
Rshift = rsft;
Gshift = gsft;
Bshift = bsft;
Rmask = 0xFF << rsft;
Gmask = 0xFF << rsft;
Bmask = 0xFF << rsft;
// RGB 888
if (Rmask == 0xFF0000 && Gmask == 0x00FF00 && Bmask == 0x0000FF)
format_type = 888;
// RGB 32 Bit Generic
else
format_type = 32;
}
void RenderSurface::draw_line(int sx, int sy, int ex, int ey, unsigned char col) {
if (bytes_per_pixel == 4) draw_line32(sx, sy, ex, ey, col);
else draw_line16(sx, sy, ex, ey, col);
}
#define LINE_FRACTION 65536L
void RenderSurface::draw_line16(int sx, int sy, int ex, int ey, unsigned char col) {
#ifdef WANT_OPENGL
if (opengl) {
opengl->draw_line(sx, sy + 1, 0, ex, ey + 1, 0, col);
return;
}
#endif
int xinc = 1;
int yinc = 1;
if (sx == ex) {
sx --;
if (sy > ey) {
yinc = -1;
sy--;
}
} else {
if (sx > ex) {
sx--;
xinc = -1;
} else {
ex--;
}
if (sy > ey) {
yinc = -1;
sy--;
ey--;
}
}
uint16 *pixptr = (uint16 *)(pixels + pitch * sy + sx * 2);
uint16 *pixend = (uint16 *)(pixels + pitch * ey + ex * 2);
int pitch_ = this->pitch * yinc / 2;
int cury = sy;
int curx = sx;
int width = w;
int height = h;
bool no_clip = true;
if (sx >= width && ex >= width) return;
if (sy >= height && ey >= height) return;
if (sx < 0 && ex < 0) return;
if (sy < 0 && ey < 0) return;
if (sy < 0 || sy >= height || sx < 0 || sx >= width) no_clip = false;
if (ey < 0 || ey >= height || ex < 0 || ex >= width) no_clip = false;
int col32 = colour32[col];
// vertical
if (sx == ex) {
//Std::cout << "Vertical" << Std::endl;
// start is below end
while (pixptr != pixend) {
if (no_clip || (cury >= 0 && cury < height)) *pixptr = col32;
pixptr += pitch_;
cury += yinc;
}
}
// Horizontal
else if (sy == ey) {
//Std::cout << "Horizontal" << Std::endl;
while (pixptr != pixend) {
if (no_clip || (curx >= 0 && curx < width)) *pixptr = col32;
pixptr += xinc;
curx += xinc;
}
}
// Diagonal xdiff >= ydiff
else if (ABS(sx - ex) >= ABS(sy - ey)) {
//Std::cout << "Diagonal 1" << Std::endl;
uint32 fraction = ABS((LINE_FRACTION * (sy - ey)) / (sx - ex));
uint32 ycounter = 0;
for (; ;) {
if ((no_clip || (cury >= 0 && cury < height && curx >= 0 && curx < width)))
*pixptr = col32;
pixptr += xinc;
if (curx == ex) break;
curx += xinc;
ycounter += fraction;
// Need to work out if we need to change line
if (ycounter > LINE_FRACTION) {
ycounter -= LINE_FRACTION;
pixptr += pitch_;
cury += yinc;
}
}
}
// Diagonal ydiff > xdiff
else {
//Std::cout << "Diagonal 2" << Std::endl;
uint32 fraction = ABS((LINE_FRACTION * (sx - ex)) / (sy - ey));
uint32 xcounter = 0;
for (; ;) {
if ((no_clip || (cury >= 0 && cury < height && curx >= 0 && curx < width)))
*pixptr = col32;
pixptr += pitch_;
if (cury == ey) break;
cury += yinc;
xcounter += fraction;
// Need to work out if we need to change line
if (xcounter > LINE_FRACTION) {
xcounter -= LINE_FRACTION;
pixptr += xinc;
curx += xinc;
}
}
}
}
void RenderSurface::draw_line32(int sx, int sy, int ex, int ey, unsigned char col) {
#ifdef WANT_OPENGL
if (opengl) {
opengl->draw_line(sx, sy + 1, 0, ex, ey + 1, 0, col);
return;
}
#endif
int xinc = 1;
int yinc = 1;
if (sx == ex) {
sx --;
if (sy > ey) {
yinc = -1;
sy--;
}
} else {
if (sx > ex) {
sx--;
xinc = -1;
} else {
ex--;
}
if (sy > ey) {
yinc = -1;
sy--;
ey--;
}
}
uint32 *pixptr = (uint32 *)(pixels + pitch * sy + sx * 4);
uint32 *pixend = (uint32 *)(pixels + pitch * ey + ex * 4);
int pitch_ = this->pitch * yinc / 4;
int cury = sy;
int curx = sx;
int width = w;
int height = h;
bool no_clip = true;
if (sx >= width && ex >= width) return;
if (sy >= height && ey >= height) return;
if (sx < 0 && ex < 0) return;
if (sy < 0 && ey < 0) return;
if (sy < 0 || sy >= height || sx < 0 || sx >= width) no_clip = false;
if (ey < 0 || ey >= height || ex < 0 || ex >= width) no_clip = false;
int col32 = colour32[col];
// vertical
if (sx == ex) {
//Std::cout << "Vertical" << Std::endl;
// start is below end
while (pixptr != pixend) {
if (no_clip || (cury >= 0 && cury < height)) *pixptr = col32;
pixptr += pitch_;
cury += yinc;
}
}
// Horizontal
else if (sy == ey) {
//Std::cout << "Horizontal" << Std::endl;
while (pixptr != pixend) {
if (no_clip || (curx >= 0 && curx < width)) *pixptr = col32;
pixptr += xinc;
curx += xinc;
}
}
// Diagonal xdiff >= ydiff
else if (ABS(sx - ex) >= ABS(sy - ey)) {
//Std::cout << "Diagonal 1" << Std::endl;
uint32 fraction = ABS((LINE_FRACTION * (sy - ey)) / (sx - ex));
uint32 ycounter = 0;
for (; ;) {
if ((no_clip || (cury >= 0 && cury < height && curx >= 0 && curx < width)))
*pixptr = col32;
pixptr += xinc;
if (curx == ex) break;
curx += xinc;
ycounter += fraction;
// Need to work out if we need to change line
if (ycounter > LINE_FRACTION) {
ycounter -= LINE_FRACTION;
pixptr += pitch_;
cury += yinc;
}
}
}
// Diagonal ydiff > xdiff
else {
//Std::cout << "Diagonal 2" << Std::endl;
uint32 fraction = ABS((LINE_FRACTION * (sx - ex)) / (sy - ey));
uint32 xcounter = 0;
for (; ;) {
if ((no_clip || (cury >= 0 && cury < height && curx >= 0 && curx < width)))
*pixptr = col32;
pixptr += pitch_;
if (cury == ey) break;
cury += yinc;
xcounter += fraction;
// Need to work out if we need to change line
if (xcounter > LINE_FRACTION) {
xcounter -= LINE_FRACTION;
pixptr += xinc;
curx += xinc;
}
}
}
}
//
//
//
void RenderSurface::draw_3d_line(int x, int y, int sx, int sy, int sz, int ex, int ey, int ez, unsigned char col) {
int dispsx = x + (sx - sy) / 4;
int dispsy = y + (sx + sy) / 8 - sz;
int dispex = x + (ex - ey) / 4;
int dispey = y + (ex + ey) / 8 - ez;
#ifdef WANT_OPENGL
if (opengl) opengl->draw_line(dispsx, dispsy + 1, 0, dispex, dispey + 1, 0, col);
else
#endif
draw_line(dispsx, dispsy + 1, dispex, dispey + 1, col);
//draw_line (0, 0, 800, 600, col);
}
void RenderSurface::create_zbuffer() {
#ifdef ENABLE_SOFTREND_EMU
SoftRend::SetupInitialState();
#endif
// Not in opengl, or if we alraedy have one
if (opengl || zbuffer_priv) return;
zbuffer = zbuffer_priv = new uint16[pitch * h];
}
RenderSurface *CreateRenderSurface(uint32 width, uint32 height, uint32 bpp, byte *p) {
return new RenderSurface(width, height, bpp, p);
}
RenderSurface *CreateRenderSurface(uint32 width, uint32 height, uint32 bpp, sint32 gb) {
return new RenderSurface(width, height, bpp, gb);
}
RenderSurface *CreateRenderSurface(Graphics::ManagedSurface *surf) {
return new RenderSurface(surf);
}
RenderSurface *CreateRenderSurface(OpenGL *ogl) {
return new RenderSurface(ogl);
}
static int getBits(uint mask) {
int count = 0;
for (; mask; mask >>= 1)
++count;
return count;
}
Graphics::ManagedSurface *RenderSurface::createSurface(int w, int h,
const Graphics::PixelFormat &format) {
return new Graphics::ManagedSurface(w, h, format);
}
Graphics::ManagedSurface *RenderSurface::get_sdl_surface() {
if (_rawSurface == nullptr) {
_rawSurface = new Graphics::ManagedSurface(w, h,
Graphics::PixelFormat(bytes_per_pixel, getBits(Rmask), getBits(Gmask),
getBits(Bmask), 0, Rshift, Gshift, Bshift, 0));
byte *dest = (byte *)_rawSurface->getPixels();
Common::copy(pixels, pixels + (_rawSurface->pitch * _rawSurface->h), dest);
}
return _rawSurface;
}
const unsigned char *RenderSurface::get_pixels() {
return ((const unsigned char *)pixels);
}
} // End of namespace Nuvie
} // End of namespace Ultima

View File

@@ -0,0 +1,162 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef NUVIE_SCREEN_SURFACE_H
#define NUVIE_SCREEN_SURFACE_H
#include "graphics/pixelformat.h"
namespace Ultima {
namespace Nuvie {
class OpenGL;
class RenderSurface {
private:
uint8 *buffer; // If the buffer is created, this is it
uint16 *zbuffer_priv;
Graphics::ManagedSurface *_rawSurface;
DisposeAfterUse::Flag _disposeSurface;
public:
OpenGL *opengl; // OpenGL surface
// Pixel Format (also see 'Colour shifting values' later)
int bytes_per_pixel; // 2 or 4
int bits_per_pixel; // 16 or 32
int format_type; // 16, 555, 565, 32 or 888
uint8 *pixels; // What we draw to
uint16 *zbuffer; // Z Buffer
uint32 colour32[256]; // Palette as 16/32 bit colours
// Dimensions
uint32 w, h; // Surface width and height
uint32 pitch; // Surface pitch
// Guardband
uint32 gl, gr; // Guard left and right (left goes negetive)
uint32 gt, gb; // Guard top and bottom (up goes negetive)
uint32 lock_count; // Number of locks on surface
public:
// Default constructor for no created surface
RenderSurface();
// Constructor for custom buffer
RenderSurface(uint32 width, uint32 height, uint32 bpp, uint8 *p);
// Constructor for surface (with optional guardband)
RenderSurface(uint32 width, uint32 height, uint32 bpp, sint32 gb = 0);
// Constructor for sdl surface
RenderSurface(Graphics::ManagedSurface *surf);
// Constructor for opengl surface
RenderSurface(OpenGL *ogl);
// Destructor
virtual ~RenderSurface();
// Create a 16 Bit Z Buffer for this surface
void create_zbuffer();
// Set the buffer format from Graphics::PixelFormat
void set_format(const Graphics::PixelFormat *format);
// Set a custom 565 format
void set_format565(int rsft = 11, int gsft = 5, int bsft = 0);
// Set a custom 555 format
void set_format555(int rsft = 10, int gsft = 5, int bsft = 0);
// Set a custom 888 format
void set_format888(int rsft = 16, int gsft = 8, int bsft = 0);
// Get the pixel format
const Graphics::PixelFormat &getFormat() const {
return _rawSurface->format;
}
// Draw Lines
void draw_line(int sx, int sy, int ex, int ey, unsigned char col);
void draw_3d_line(int x, int y, int sx, int sy, int sz, int ex, int ey, int ez, unsigned char col);
// Colour shifting values
static uint8 Rloss;
static uint8 Gloss;
static uint8 Bloss;
static uint8 Rloss16;
static uint8 Gloss16;
static uint8 Bloss16;
static uint8 Rshift;
static uint8 Gshift;
static uint8 Bshift;
static uint32 Rmask;
static uint32 Gmask;
static uint32 Bmask;
//
// Shape Painting
//
// Display a shape. Non translucent
//virtual void display(Shape* s, int x, int y, FrameID frame) = 0;
// Display a shape. Translucent
// virtual void display_translucent(Shape* s, int x, int y, FrameID frame) = 0;
// Display a shape. Flipped
// virtual void display_flipped(Shape* s, int x, int y, FrameID frame, bool trans = false) = 0;
//FIX virtual void display8(uint8 *buf, int x, int y) = 0;
Graphics::ManagedSurface *get_sdl_surface();
const unsigned char *get_pixels();
static Graphics::ManagedSurface *createSurface(int w, int h,
const Graphics::PixelFormat &format);
private:
// Draw Lines
void draw_line16(int sx, int sy, int ex, int ey, unsigned char col);
// Draw Lines
void draw_line32(int sx, int sy, int ex, int ey, unsigned char col);
};
RenderSurface *CreateRenderSurface(uint32 width, uint32 height, uint32 bpp, uint8 *p);
RenderSurface *CreateRenderSurface(uint32 width, uint32 height, uint32 bpp, sint32 gb = 0);
RenderSurface *CreateRenderSurface(Graphics::ManagedSurface *surf);
RenderSurface *CreateRenderSurface(OpenGL *ogl);
} // End of namespace Nuvie
} // End of namespace Ultima
#endif