213 lines
6.5 KiB
C++
213 lines
6.5 KiB
C++
/* 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 KYRA_SCREEN_EOB_SEGACD_H
|
|
#define KYRA_SCREEN_EOB_SEGACD_H
|
|
|
|
#ifdef ENABLE_EOB
|
|
|
|
#define SEGA_PERFORMANCE true
|
|
#define SEGA_USE_MEMPOOL true
|
|
|
|
#include "kyra/graphics/screen_eob.h"
|
|
|
|
#if SEGA_USE_MEMPOOL
|
|
#include "common/memorypool.h"
|
|
#endif
|
|
|
|
namespace Kyra {
|
|
|
|
class SegaRenderer {
|
|
public:
|
|
enum Plane {
|
|
kPlaneA = 0,
|
|
kPlaneB = 1,
|
|
kWindowPlane = 2
|
|
};
|
|
|
|
enum WindowMode {
|
|
kWinToLeft = 0,
|
|
kWinToTop = 0,
|
|
kWinToRight = 1,
|
|
kWinToBottom = 1
|
|
};
|
|
|
|
enum HScrollMode {
|
|
kHScrollFullScreen = 0,
|
|
kHScroll8PixelRows,
|
|
kHScroll1PixelRows
|
|
};
|
|
|
|
enum VScrollMode {
|
|
kVScrollFullScreen = 0,
|
|
kVScroll16PixelStrips
|
|
};
|
|
|
|
public:
|
|
SegaRenderer(Screen_EoB *screen);
|
|
~SegaRenderer();
|
|
|
|
void setResolution(int w, int h);
|
|
void setPlaneTableLocation(int plane, uint16 addr);
|
|
// The hardware allows/demands separate modification of the vertical and horizontal properties.
|
|
// To allow this without making another function the w/h parameters can be set to -1 which will
|
|
// keep the existing value for that property.
|
|
void setupPlaneAB(int pixelWidth, int pixelHeigth);
|
|
// The hardware allows/demands separate modification of the vertical and horizontal properties.
|
|
// To allow this without making another function the blockX/Y parameters can be set to -1 which
|
|
// will keep the existing value for that property.
|
|
void setupWindowPlane(int blockX, int blockY, int horizontalMode, int verticalMode);
|
|
void setHScrollTableLocation(int addr);
|
|
void setSpriteTableLocation(int addr);
|
|
void setPitch(int pitch);
|
|
void setHScrollMode(int mode);
|
|
void setVScrollMode(int mode);
|
|
|
|
void loadToVRAM(const void *data, uint16 dataSize, uint16 addr);
|
|
void loadStreamToVRAM(Common::SeekableReadStream *in, uint16 addr, bool compressedData = false);
|
|
void memsetVRAM(int addr, uint8 val, int len);
|
|
void fillRectWithTiles(int vramArea, int x, int y, int w, int h, uint16 nameTblEntry, bool incr = false, bool topToBottom = false, const uint16 *patternTable = 0);
|
|
void writeUint16VSRAM(int addr, uint16 value);
|
|
void writeUint8VRAM(int addr, uint8 value);
|
|
void writeUint16VRAM(int addr, uint16 value);
|
|
void clearPlanes();
|
|
|
|
void render(int destPageNum, int renderLeft = -1, int renderTop = -1, int renderWidth = -1, int renderHeight = -1, bool spritesOnly = false);
|
|
private:
|
|
void renderPlanePart(int plane, uint8 *dstBuffer, int x1, int y1, int x2, int y2);
|
|
void renderPlaneTile(uint8 *dst, int destX, const uint16 *nameTable, int vScrollLSBStart, int vScrollLSBEnd, int hScrollTableIndex, uint16 pitch);
|
|
void renderSpriteTile(uint8 *dst, uint8 *mask, int x, int y, uint16 tile, uint8 pal, bool vflip, bool hflip, bool prio);
|
|
#if SEGA_PERFORMANCE
|
|
template<bool hflip, bool oddStart, bool oddEnd> void renderLineFragmentM(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal);
|
|
template<bool hflip, bool oddStart, bool oddEnd> void renderLineFragmentD(uint8 *dst, const uint8 *src, int start, int end, uint8 pal);
|
|
typedef void(SegaRenderer::*renderFuncM)(uint8*, uint8*, const uint8*, int, int, uint8);
|
|
typedef void(SegaRenderer::*renderFuncD)(uint8*, const uint8*, int, int, uint8);
|
|
const renderFuncM *_renderLineFragmentM;
|
|
const renderFuncD *_renderLineFragmentD;
|
|
#else
|
|
template<bool hflip> void renderLineFragment(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal);
|
|
#endif
|
|
|
|
void initPrioRenderTask(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal, bool hflip);
|
|
void clearPrioChain();
|
|
|
|
struct SegaPlane {
|
|
SegaPlane() : blockX(0), blockY(0), w(0), h(0), mod(0), nameTable(0), nameTableSize(0) {}
|
|
int blockX, blockY;
|
|
uint16 w, h, mod;
|
|
uint16 *nameTable;
|
|
uint16 nameTableSize;
|
|
};
|
|
|
|
SegaPlane _planes[3];
|
|
uint8 *_vram;
|
|
uint16 *_vsram;
|
|
uint16 *_hScrollTable;
|
|
uint16 *_spriteTable;
|
|
uint8 *_spriteMask;
|
|
uint8 _hScrollMode;
|
|
uint8 _vScrollMode;
|
|
uint16 _pitch;
|
|
uint16 _numSpritesMax;
|
|
|
|
struct PrioTileRenderObj {
|
|
PrioTileRenderObj(PrioTileRenderObj *chainEnd, uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal, bool hflip) :
|
|
_pred(chainEnd), _next(0), _dst(dst), _mask(mask), _src(src), _start(start), _end(end), _pal(pal), _hflip(hflip) {
|
|
if (_pred)
|
|
_pred->_next = this;
|
|
}
|
|
uint8 *_dst;
|
|
uint8 *_mask;
|
|
const uint8 *_src;
|
|
int _start;
|
|
int _end;
|
|
uint8 _pal;
|
|
bool _hflip;
|
|
PrioTileRenderObj *_pred;
|
|
PrioTileRenderObj *_next;
|
|
};
|
|
|
|
#if SEGA_USE_MEMPOOL
|
|
Common::ObjectPool<PrioTileRenderObj> _prioRenderMemPool;
|
|
#endif
|
|
PrioTileRenderObj *_prioChainStart, *_prioChainEnd;
|
|
uint16 _screenW, _screenH, _blocksW, _blocksH;
|
|
Screen_EoB *_screen;
|
|
};
|
|
|
|
class SegaAnimator {
|
|
public:
|
|
SegaAnimator(SegaRenderer *renderer);
|
|
~SegaAnimator();
|
|
|
|
void initSprite(int id, int16 x, int16 y, uint16 nameTbl, uint16 hw);
|
|
void clearSprites();
|
|
void moveMorphSprite(int id, uint16 nameTbl, int16 addX, int16 addY);
|
|
void moveSprites(int id, uint16 num, int16 addX, int16 addY);
|
|
void moveSprites2(int id, uint16 num, int16 addX, int16 addY);
|
|
|
|
void update();
|
|
|
|
private:
|
|
struct Sprite {
|
|
int16 x;
|
|
int16 y;
|
|
uint16 nameTbl;
|
|
uint16 hw;
|
|
};
|
|
|
|
uint16 *_tempBuffer;
|
|
Sprite *_sprites;
|
|
SegaRenderer *_renderer;
|
|
bool _needUpdate;
|
|
};
|
|
|
|
class ScrollManager {
|
|
public:
|
|
ScrollManager(SegaRenderer *renderer);
|
|
~ScrollManager();
|
|
|
|
void setVScrollTimers(uint16 destA, int incrA, int delayA, uint16 destB, int incrB, int delayB);
|
|
void setHScrollTimers(uint16 destA, int incrA, int delayA, uint16 destB, int incrB, int delayB);
|
|
void updateScrollTimers();
|
|
void fastForward();
|
|
|
|
private:
|
|
struct ScrollTimer {
|
|
ScrollTimer() : _offsCur(0), _offsDest(0), _incr(0), _delay(0), _timer(0) {}
|
|
int16 _offsCur;
|
|
int16 _offsDest;
|
|
int16 _incr;
|
|
int16 _delay;
|
|
int16 _timer;
|
|
};
|
|
|
|
ScrollTimer *_vScrollTimers;
|
|
ScrollTimer *_hScrollTimers;
|
|
SegaRenderer *_renderer;
|
|
};
|
|
|
|
} // End of namespace Kyra
|
|
|
|
#endif // ENABLE_EOB
|
|
|
|
#endif
|