mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-10 03:40:25 +00:00
GROOVIE: T11H Pente AI puzzle
This commit is contained in:
parent
a0cd941fa5
commit
ffb1dc3610
@ -321,6 +321,7 @@ byte CakeGame::aiGetBestMove(int search_depth) {
|
||||
|
||||
void CakeGame::testCake() {
|
||||
warning("starting CakeGame::testCake()");
|
||||
uint32 oldSeed = _random.getSeed();
|
||||
// test the draw condition, grouped by column
|
||||
runCakeTestNoAi(/*move 1*/ "7777777" /*8*/ "6666666" /*15*/ "5555555" /*22*/ "34444444" /*30*/ "333333" /*36*/ "2222222" /*43*/ "01111111" /*51*/ "000000", false, true);
|
||||
|
||||
@ -328,6 +329,7 @@ void CakeGame::testCake() {
|
||||
runCakeTest(1, "232232432445", false);
|
||||
runCakeTest(123, "4453766355133466", false);
|
||||
|
||||
_random.setSeed(oldSeed);
|
||||
warning("finished CakeGame::testCake()");
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,13 +31,40 @@ namespace Groovie {
|
||||
/*
|
||||
* Pente puzzle at the end of the game.
|
||||
*/
|
||||
|
||||
struct pentePlayerTable;
|
||||
struct penteTable;
|
||||
|
||||
class PenteGame {
|
||||
public:
|
||||
PenteGame();
|
||||
void run(byte *scriptVariables);
|
||||
|
||||
|
||||
private:
|
||||
int *allocs(int param_1, int param_2);
|
||||
void penteSub02Frees(penteTable *param_1);
|
||||
void penteSub05BuildLookupTable(penteTable *table);
|
||||
penteTable *penteSub01Init(byte width, byte height, byte length);
|
||||
void penteSub03Scoring(penteTable *table, byte move_y, byte move_x, bool whose_turn);
|
||||
void penteSub07RevertScore(penteTable *table_1, byte y, byte x);
|
||||
byte penteScoreCaptureSingle(penteTable *table, byte x, byte y, int slopeX, int slopeY);
|
||||
uint penteSub04ScoreCapture(penteTable *table, byte y, byte x);
|
||||
void penteSub08MaybeAnimateCapture(short param_1, byte *param_2, short *param_3, short *param_4);
|
||||
void penteSub11RevertCapture(penteTable *table, byte y, byte x, byte y2);
|
||||
int penteSub10AiRecurse(penteTable *table_1, char depth, int parent_score);
|
||||
uint penteSub09Ai(uint y_1, int param_2, int param_3, penteTable *table_4, byte depth);
|
||||
void penteOp(byte *vars);
|
||||
void test();
|
||||
void testGame(uint32 seed, Common::Array<int> moves, bool playerWin);
|
||||
|
||||
Common::RandomSource _random;
|
||||
|
||||
byte globalY;
|
||||
byte globalX;
|
||||
char global2;
|
||||
short globalPlayerMove;
|
||||
short global1;
|
||||
penteTable *game_state_table;
|
||||
};
|
||||
|
||||
} // End of Groovie namespace
|
||||
|
@ -824,6 +824,7 @@ void TriangleGame::ensureSamanthaWin(uint32 seed) {
|
||||
|
||||
void TriangleGame::test() {
|
||||
warning("starting TriangleGame::test");
|
||||
uint32 oldSeed = _random.getSeed();
|
||||
|
||||
// Samantha appears to not always win, but she usually does, and she wins these seeds
|
||||
// haven't verified if she always wins in the original game
|
||||
@ -837,6 +838,7 @@ void TriangleGame::test() {
|
||||
testGame(3, {24, 32, 17, 42, 23, 53, 16, 39, 11, 29, 10, 44, 6, 33, 7, 63, 12, 28, 18, 31, 13, 204, 8, 204, 4, 38, 3, 43}, false);
|
||||
testGame(3, {6, 32, 10, 42, 11, 53, 7, 23, 3, 15, 12, 22, 18, 43, 13, 33, 8, 35, 4, 31, 1, 204, 17, 204, 16, 204, 19, 63 }, false);
|
||||
|
||||
_random.setSeed(oldSeed);
|
||||
warning("finished TriangleGame::test");
|
||||
}
|
||||
|
||||
|
@ -2181,6 +2181,26 @@ void Script::o2_playsound() {
|
||||
playBackgroundSound(fileref, loops);
|
||||
}
|
||||
|
||||
void Script::o_wipemaskfromstring58() {
|
||||
// used in pente when pieces are captured
|
||||
Common::String vidName;
|
||||
uint16 instStart = _currentInstruction;
|
||||
uint32 fileref = getVideoRefString(vidName);
|
||||
setBitFlag(10, true);
|
||||
|
||||
// Show the debug information just when starting the playback
|
||||
if (fileref != _videoRef) {
|
||||
debugC(0, kDebugScript, "Groovie::Script: WIPEMASKFROMSTRING58 %d ('%s')", fileref, vidName.c_str());
|
||||
debugC(2, kDebugVideo, "\nGroovie::Script: @0x%04X: Playing mask video %d ('%s') via 0x58 (o_wipemaskfromstring58)", instStart - 1, fileref, vidName.c_str());
|
||||
}
|
||||
|
||||
// Play the video
|
||||
if (!playvideofromref(fileref)) {
|
||||
// Move _currentInstruction back
|
||||
_currentInstruction = instStart - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Script::o2_check_sounds_overlays() {
|
||||
uint16 val1 = readScript8or16bits();
|
||||
uint8 val2 = readScript8bits();
|
||||
@ -2394,7 +2414,7 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = {
|
||||
&Script::o2_setscriptend,
|
||||
&Script::o2_playsound,
|
||||
&Script::o_invalid,
|
||||
&Script::o_invalid, // 0x58
|
||||
&Script::o_wipemaskfromstring58, // 0x58
|
||||
&Script::o2_check_sounds_overlays,
|
||||
&Script::o2_preview_loadgame
|
||||
};
|
||||
|
@ -245,6 +245,7 @@ private:
|
||||
void o_musicdelay();
|
||||
void o_hotspot_outrect();
|
||||
void o_stub56();
|
||||
void o_wipemaskfromstring58();
|
||||
void o_stub59();
|
||||
|
||||
void o2_bf0on();
|
||||
|
@ -65,13 +65,20 @@ static inline void copyPixel(byte *dst, const byte *src) {
|
||||
*(uint32 *)dst = *(const uint32 *)src;
|
||||
}
|
||||
|
||||
// Overwrites one pixel of destination regardless of the alpha value
|
||||
// Overwrites one pixel of destination if the src pixel is visible
|
||||
static inline void copyPixelIfAlpha(byte *dst, const byte *src) {
|
||||
if (src[kAIndex] > 0) {
|
||||
copyPixel(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
// Overwrites one pixel if it's part of the mask
|
||||
static inline void copyPixelIfMask(byte *dst, const byte *mask, const byte *src) {
|
||||
if (mask[kAIndex] > 0) {
|
||||
copyPixel(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
// Copies one pixel to destination but respects the alpha value of the source
|
||||
static inline void copyPixelWithA(byte *dst, const byte *src) {
|
||||
if (src[kAIndex] == 255) {
|
||||
@ -142,6 +149,7 @@ uint16 ROQPlayer::loadInternal() {
|
||||
_flagOne = ((_flags & (1 << 1)) != 0);
|
||||
_flagTwo = ((_flags & (1 << 2)) != 0);
|
||||
_altMotionDecoder = ((_flags & (1 << 14)) != 0);
|
||||
_flagMasked = ((_flags & (1 << 10)) != 0);
|
||||
|
||||
// Read the file header
|
||||
ROQBlockHeader blockHeader;
|
||||
@ -249,7 +257,13 @@ void ROQPlayer::buildShowBuf() {
|
||||
|
||||
// Select the destination buffer according to the given flags
|
||||
int destOffset = 0;
|
||||
Graphics::Surface *destBuf;
|
||||
Graphics::Surface *maskBuf = NULL;
|
||||
Graphics::Surface *srcBuf = _currBuf;
|
||||
Graphics::Surface *destBuf = NULL;
|
||||
if (_flagMasked) {
|
||||
srcBuf = _bg;
|
||||
maskBuf = _currBuf;
|
||||
}
|
||||
if (_flagOne) {
|
||||
if (_flagTwo) {
|
||||
destBuf = _overBuf;
|
||||
@ -266,17 +280,24 @@ void ROQPlayer::buildShowBuf() {
|
||||
int startX, startY, stopX, stopY;
|
||||
calcStartStop(startX, stopX, _origX, _screen->w);
|
||||
calcStartStop(startY, stopY, _origY, _screen->h);
|
||||
assert(destBuf->format == _currBuf->format);
|
||||
assert(destBuf->format == srcBuf->format);
|
||||
assert(destBuf->format == _overBuf->format);
|
||||
assert(destBuf->format.bytesPerPixel == 4);
|
||||
|
||||
for (int line = startY; line < stopY; line++) {
|
||||
byte *in = (byte *)_currBuf->getBasePtr(MAX(0, -_origX) / _scaleX, (line - _origY) / _scaleY);
|
||||
byte *in = (byte *)srcBuf->getBasePtr(MAX(0, -_origX) / _scaleX, (line - _origY) / _scaleY);
|
||||
byte *inOvr = (byte *)_overBuf->getBasePtr(startX, line);
|
||||
byte *out = (byte *)destBuf->getBasePtr(startX, line + destOffset);
|
||||
byte *mask = NULL;
|
||||
if (_flagMasked) {
|
||||
mask = (byte *)maskBuf->getBasePtr(MAX(0, -_origX) / _scaleX, (line - _origY) / _scaleY);
|
||||
}
|
||||
|
||||
|
||||
for (int x = startX; x < stopX; x++) {
|
||||
if (destBuf == _overBuf) {
|
||||
if (_flagMasked) {
|
||||
copyPixelIfMask(out, mask, in);
|
||||
} else if (destBuf == _overBuf) {
|
||||
copyPixelIfAlpha(out, in);
|
||||
} else {
|
||||
copyPixelWithA(out, in);
|
||||
@ -296,6 +317,8 @@ void ROQPlayer::buildShowBuf() {
|
||||
inOvr += _screen->format.bytesPerPixel;
|
||||
if (!(x % _scaleX))
|
||||
in += _screen->format.bytesPerPixel;
|
||||
if (mask)
|
||||
mask += _screen->format.bytesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,9 +93,10 @@ private:
|
||||
byte _codebook4[256 * 4];
|
||||
|
||||
// Flags
|
||||
bool _flagOne; // Play only first frame and do not print the image to the screen
|
||||
bool _flagTwo; // If _flagOne is set. Copy frame to the foreground otherwise to the background
|
||||
bool _flagOne; //!< Play only first frame and do not print the image to the screen
|
||||
bool _flagTwo; //!< If _flagOne is set. Copy frame to the foreground otherwise to the background
|
||||
bool _altMotionDecoder; // Some ROQ vids use a variation on the copy codeblock
|
||||
bool _flagMasked; //!< Clear the video instead of play it, used in pente
|
||||
|
||||
// Buffers
|
||||
void buildShowBuf();
|
||||
|
Loading…
Reference in New Issue
Block a user