Skip to content

Commit

Permalink
AGI: Cleanup PictureMgr
Browse files Browse the repository at this point in the history
  • Loading branch information
sluicebox committed Dec 13, 2024
1 parent b3fe3a7 commit c6c2924
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 77 deletions.
2 changes: 1 addition & 1 deletion engines/agi/agi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ void AgiEngine::redrawScreen() {
_gfx->setPalette(true); // set graphics mode palette
_text->charAttrib_Set(_text->_textAttrib.foreground, _text->_textAttrib.background);
_gfx->clearDisplay(0);
_picture->showPic();
_picture->showPicture();
_text->statusDraw();
_text->promptRedraw();
}
Expand Down
4 changes: 3 additions & 1 deletion engines/agi/op_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,7 @@ void cmdShowPic(AgiGame *state, AgiEngine *vm, uint8 *parameter) {

vm->setFlag(VM_FLAG_OUTPUT_MODE, false);
vm->_text->closeWindow();
vm->_picture->showPicWithTransition();
vm->_picture->showPictureWithTransition();
state->pictureShown = true;

debugC(6, kDebugLevelScripts, "--- end of show pic ---");
Expand Down Expand Up @@ -2310,6 +2310,8 @@ void cmdAgi256LoadPic(AgiGame *state, AgiEngine *vm, uint8 *parameter) {
vm->loadResource(RESOURCETYPE_PICTURE, resourceNr);

// Draw the picture. Similar to void cmdDrawPic.
// Must not clear the screen; AGI256 uses the priority
// screen from the previously drawn picture.
vm->_picture->decodePicture(resourceNr, false, true);
spritesMgr->drawAllSpriteLists();
state->pictureShown = false;
Expand Down
73 changes: 19 additions & 54 deletions engines/agi/picture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,13 @@ PictureMgr::PictureMgr(AgiBase *agi, GfxMgr *gfx) {
}

void PictureMgr::putVirtPixel(int x, int y) {
byte drawMask = 0;

if (x < 0 || y < 0 || x >= _width || y >= _height)
return;

x += _xOffset;
y += _yOffset;

byte drawMask;
if (_priOn)
drawMask |= GFX_SCREEN_MASK_PRIORITY;
if (_scrOn)
Expand Down Expand Up @@ -319,6 +318,8 @@ void PictureMgr::plotBrush() {
** Draw AGI picture
**************************************************************************/
void PictureMgr::drawPicture() {
_dataOffset = 0;
_dataOffsetNibble = false;
_patCode = 0;
_patNum = 0;
_priOn = false;
Expand All @@ -345,9 +346,9 @@ void PictureMgr::drawPicture() {
}

void PictureMgr::drawPictureC64() {
debugC(8, kDebugLevelMain, "Drawing C64 picture");
debugC(8, kDebugLevelMain, "Drawing Apple II / C64 / CoCo picture");

_scrColor = 0x0;
_scrColor = 0;

while (_dataOffset < _dataSize) {
byte curByte = getNextByte();
Expand Down Expand Up @@ -476,14 +477,10 @@ void PictureMgr::drawPictureV15() {
}

void PictureMgr::drawPictureV2() {
bool nibbleMode = false;

debugC(8, kDebugLevelMain, "Drawing V2/V3 picture");

if (_vm->_game.dirPic[_resourceNr].flags & RES_PICTURE_V3_NIBBLE_PARM) {
// check, if this resource uses nibble mode (0xF0 + 0xF2 commands take nibbles instead of bytes)
nibbleMode = true;
}
// AGIv3 nibble parameters are indicated by a flag in the picture's directory entry
bool nibbleMode = (_vm->_game.dirPic[_resourceNr].flags & RES_PICTURE_V3_NIBBLE_PARM) != 0;

int step = 0;
while (_dataOffset < _dataSize) {
Expand Down Expand Up @@ -842,7 +839,7 @@ bool PictureMgr::draw_FillCheck(int16 x, int16 y) {
}

/**
* Decode an AGI picture resource.
* Decode an AGI picture resource. Used by regular AGI games.
* This function decodes an AGI picture resource into the correct slot
* and draws it on the AGI screen, optionally clearing the screen before
* drawing.
Expand All @@ -851,27 +848,18 @@ bool PictureMgr::draw_FillCheck(int16 x, int16 y) {
* @param agi256 load an AGI256 picture resource
*/
void PictureMgr::decodePicture(int16 resourceNr, bool clearScreen, bool agi256, int16 width, int16 height) {
_patCode = 0;
_patNum = 0;
_priOn = _scrOn = false;
_scrColor = 0xF;
_priColor = 0x4;

_resourceNr = resourceNr;
_data = _vm->_game.pictures[resourceNr].rdata;
_dataSize = _vm->_game.dirPic[resourceNr].len;
_dataOffset = 0;
_dataOffsetNibble = false;

_width = width;
_height = height;

if (clearScreen && !agi256) { // 256 color pictures should always fill the whole screen, so no clearing for them.
_gfx->clear(15, 4); // Clear 16 color AGI screen (Priority 4, color white).
if (clearScreen) {
_gfx->clear(15, 4); // white, priority 4
}

if (!agi256) {
drawPicture(); // Draw 16 color picture.
drawPicture();
} else {
drawPictureAGI256();
}
Expand All @@ -883,7 +871,7 @@ void PictureMgr::decodePicture(int16 resourceNr, bool clearScreen, bool agi256,
}

/**
* Decode an AGI picture resource.
* Decode an AGI picture resource. Used by preAGI.
* This function decodes an AGI picture resource into the correct slot
* and draws it on the AGI screen, optionally clearing the screen before
* drawing.
Expand All @@ -892,51 +880,29 @@ void PictureMgr::decodePicture(int16 resourceNr, bool clearScreen, bool agi256,
* @param clear clear AGI screen before drawing
*/
void PictureMgr::decodePictureFromBuffer(byte *data, uint32 length, bool clearScreen, int16 width, int16 height) {
_patCode = 0;
_patNum = 0;
_priOn = _scrOn = false;
_scrColor = 0xF;
_priColor = 0x4;

_data = data;
_dataSize = length;
_dataOffset = 0;
_dataOffsetNibble = false;

_width = width;
_height = height;

if (clearScreen) {
_gfx->clear(15, 4); // Clear 16 color AGI screen (Priority 4, color white).
_gfx->clear(15, 4); // white, priority 4
}

drawPicture(); // Draw 16 color picture.
drawPicture();
}

void PictureMgr::showPic() {
debugC(8, kDebugLevelMain, "Show picture!");
void PictureMgr::showPicture(int16 x, int16 y, int16 width, int16 height) {
debugC(8, kDebugLevelMain, "Show picture");

_gfx->render_Block(0, 0, SCRIPT_WIDTH, SCRIPT_HEIGHT);
_gfx->render_Block(x, y, width, height);
}

/**
* Show AGI picture.
* This function copies a ``hidden'' AGI picture to the output device.
*/
void PictureMgr::showPic(int16 x, int16 y, int16 pic_width, int16 pic_height) {
_width = pic_width;
_height = pic_height;

debugC(8, kDebugLevelMain, "Show picture!");

_gfx->render_Block(x, y, pic_width, pic_height);
}

void PictureMgr::showPicWithTransition() {
void PictureMgr::showPictureWithTransition() {
_width = SCRIPT_WIDTH;
_height = SCRIPT_HEIGHT;

debugC(8, kDebugLevelMain, "Show picture!");
debugC(8, kDebugLevelMain, "Show picture");

if (!_vm->_game.automaticRestoreGame) {
// only do transitions when we are not restoring a saved game
Expand All @@ -955,7 +921,6 @@ void PictureMgr::showPicWithTransition() {
_gfx->render_Block(0, 0, SCRIPT_WIDTH, SCRIPT_HEIGHT, false);
_gfx->transition_Amiga();
return;
break;
case Common::kRenderAtariST:
// Platform Atari ST used a different transition, looks "high-res" (full 320x168)
_gfx->render_Block(0, 0, SCRIPT_WIDTH, SCRIPT_HEIGHT, false);
Expand Down
23 changes: 10 additions & 13 deletions engines/agi/picture.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,18 @@ struct AgiPicture {
AgiPicture() { reset(); }
};

// AGI picture version
enum AgiPictureVersion {
AGIPIC_C64,
AGIPIC_V1,
AGIPIC_V15,
AGIPIC_V2
AGIPIC_C64, // Winnie (Apple II, C64, CoCo)
AGIPIC_V1, // Currently unused
AGIPIC_V15, // Troll (DOS)
AGIPIC_V2 // AGIv2, AGIv3, Winnie (DOS, Amiga), Mickey (DOS)
};

enum AgiPictureFlags {
kPicFNone = (1 << 0),
kPicFCircle = (1 << 1),
kPicFf3Stop = (1 << 2),
kPicFTrollMode = (1 << 3)
kPicFCircle = (1 << 1), // Mickey, spaceship lights (not drawn accurately)
kPicFf3Stop = (1 << 2), // Troll, certain pictures
kPicFTrollMode = (1 << 3) // Troll, drawing the Troll
};

class AgiBase;
Expand All @@ -70,6 +69,7 @@ class PictureMgr {
int16 getResourceNr() const { return _resourceNr; };

private:
void putVirtPixel(int x, int y);
void xCorner(bool skipOtherCoords = false);
void yCorner(bool skipOtherCoords = false);
void plotPattern(int x, int y);
Expand All @@ -80,8 +80,6 @@ class PictureMgr {
byte getNextNibble();

public:
void putVirtPixel(int x, int y);

void decodePicture(int16 resourceNr, bool clearScreen, bool agi256 = false, int16 width = _DEFAULT_WIDTH, int16 height = _DEFAULT_HEIGHT);
void decodePictureFromBuffer(byte *data, uint32 length, bool clearScreen, int16 width = _DEFAULT_WIDTH, int16 height = _DEFAULT_HEIGHT);

Expand All @@ -107,9 +105,8 @@ class PictureMgr {
void draw_Fill();

public:
void showPic(); // <-- for regular AGI games
void showPic(int16 x, int16 y, int16 pic_width, int16 pic_height); // <-- for preAGI games
void showPicWithTransition();
void showPicture(int16 x = 0, int16 y = 0, int16 width = _DEFAULT_WIDTH, int16 height = _DEFAULT_HEIGHT);
void showPictureWithTransition();

void setPictureVersion(AgiPictureVersion version);

Expand Down
6 changes: 3 additions & 3 deletions engines/agi/preagi/mickey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ void MickeyEngine::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
_picture->setMaxStep(maxStep);
_picture->setOffset(IDI_MSA_PIC_X0 + x0, IDI_MSA_PIC_Y0 + y0);
_picture->decodePictureFromBuffer(buffer, size, false, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
_picture->showPic(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
_picture->showPicture(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
}

void MickeyEngine::drawPic(int iPic) {
Expand All @@ -750,7 +750,7 @@ void MickeyEngine::drawPic(int iPic) {
_picture->setMaxStep(0);
_picture->setOffset(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0);
_picture->decodePictureFromBuffer(buffer, size, true, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
_picture->showPic(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
_picture->showPicture(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
}

void MickeyEngine::drawRoomAnimation() {
Expand Down Expand Up @@ -795,7 +795,7 @@ void MickeyEngine::drawRoomAnimation() {
_picture->setOffset(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0);
_picture->decodePictureFromBuffer(lightPicture, sizeof(lightPicture), false, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
}
_picture->showPic(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
_picture->showPicture(IDI_MSA_PIC_X0, IDI_MSA_PIC_Y0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);

_gameStateMickey.nFrame--;
if (_gameStateMickey.nFrame < 0)
Expand Down
2 changes: 1 addition & 1 deletion engines/agi/preagi/troll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void TrollEngine::drawPic(int iPic, bool f3IsCont, bool clr, bool troll) {
_picture->setPictureFlags(flags);
_picture->decodePictureFromBuffer(_gameData + _pictureOffsets[iPic], 4096, false, IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);

_picture->showPic(0, 0, IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
_picture->showPicture(0, 0, IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
_system->updateScreen();
}

Expand Down
6 changes: 3 additions & 3 deletions engines/agi/preagi/winnie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ void WinnieEngine::drawPic(const char *szName) {

_picture->setOffset(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0);
_picture->decodePictureFromBuffer(buffer, size, true, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
_picture->showPicture(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);

free(buffer);
}
Expand All @@ -1225,7 +1225,7 @@ void WinnieEngine::drawObjPic(int iObj, int x0, int y0) {

_picture->setOffset(x0, y0);
_picture->decodePictureFromBuffer(buffer + objhdr.ofsPic - _objOffset, objSize, false, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
_picture->showPic(10, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
_picture->showPicture(10, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);

free(buffer);
}
Expand All @@ -1244,7 +1244,7 @@ void WinnieEngine::drawRoomPic() {
// draw room picture
_picture->setOffset(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0);
_picture->decodePictureFromBuffer(buffer + roomhdr.ofsPic - _roomOffset, 4096, true, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
_picture->showPicture(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);

// draw object picture
drawObjPic(iObj, IDI_WTP_PIC_X0 + roomhdr.objX, IDI_WTP_PIC_Y0 + roomhdr.objY);
Expand Down
2 changes: 1 addition & 1 deletion engines/agi/saveload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) {
_sprites->eraseSprites();
_sprites->buildAllSpriteLists();
_sprites->drawAllSpriteLists();
_picture->showPicWithTransition();
_picture->showPictureWithTransition();
_game.pictureShown = true;
_text->statusDraw();
_text->promptRedraw();
Expand Down

0 comments on commit c6c2924

Please sign in to comment.