2023-09-07 02:46:57 +00:00
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-14 19:46:08 +00:00
|
|
|
// global variables and consts
|
2023-09-07 02:46:57 +00:00
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-14 19:46:08 +00:00
|
|
|
const DEBUGMODERAMUSE = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-14 19:46:08 +00:00
|
|
|
let memStart;
|
|
|
|
if (DEBUGMODERAMUSE)
|
|
|
|
memStart = process.memory(true);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 20:42:47 +00:00
|
|
|
const DEBUGMODE = 0;
|
2023-09-11 20:57:39 +00:00
|
|
|
const DEBUGMODEINPUT = 0;
|
|
|
|
const DEBUGMODESPEED = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
|
|
|
|
const TILESIZE = 10;
|
2023-09-14 19:16:49 +00:00
|
|
|
const SCREENWIDTH = g.getWidth();
|
|
|
|
const SCREENHEIGHT = g.getHeight();
|
2023-09-09 22:32:12 +00:00
|
|
|
const SCREENOFFSETX = ((SCREENWIDTH - 16 * TILESIZE) >> 1);
|
2023-09-14 19:16:49 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
const MAXBOARDWIDTH = 10;
|
|
|
|
const MAXBOARDHEIGHT = 8;
|
|
|
|
const MAXBOARDSIZE = MAXBOARDWIDTH * MAXBOARDHEIGHT;
|
|
|
|
|
|
|
|
const GSGAME = 0;
|
|
|
|
const GSTITLE = 1;
|
|
|
|
const GSLEVELSELECT = 2;
|
|
|
|
const GSLEVELSCLEARED = 3;
|
|
|
|
const GSHELPROTATE = 4;
|
|
|
|
const GSHELPROTATE2 = 5;
|
|
|
|
const GSHELPROTATE3 = 6;
|
|
|
|
const GSHELPROTATESLIDE = 7;
|
|
|
|
const GSHELPROTATESLIDE2 = 8;
|
|
|
|
const GSHELPROTATESLIDE3 = 9;
|
|
|
|
const GSHELPROTATESLIDE4 = 10;
|
|
|
|
const GSHELPSLIDE = 11;
|
|
|
|
const GSHELPSLIDE2 = 12;
|
|
|
|
const GSHELPSLIDE3 = 13;
|
|
|
|
const GSINTRO = 14;
|
|
|
|
|
|
|
|
const GSINITDIFF = 50;
|
|
|
|
|
|
|
|
const GSINITGAME = GSINITDIFF + GSGAME;
|
|
|
|
const GSINITTITLE = GSINITDIFF + GSTITLE;
|
|
|
|
const GSINITLEVELSELECT = GSINITDIFF + GSLEVELSELECT;
|
|
|
|
const GSINITLEVELSCLEARED = GSINITDIFF + GSLEVELSCLEARED;
|
|
|
|
const GSINITHELPROTATE = GSINITDIFF + GSHELPROTATE;
|
|
|
|
const GSINITHELPROTATE2 = GSINITDIFF + GSHELPROTATE2;
|
|
|
|
const GSINITHELPROTATE3 = GSINITDIFF + GSHELPROTATE3;
|
|
|
|
const GSINITHELPROTATESLIDE = GSINITDIFF + GSHELPROTATESLIDE;
|
|
|
|
const GSINITHELPROTATESLIDE2 = GSINITDIFF + GSHELPROTATESLIDE2;
|
|
|
|
const GSINITHELPROTATESLIDE3 = GSINITDIFF + GSHELPROTATESLIDE3;
|
|
|
|
const GSINITHELPROTATESLIDE4 = GSINITDIFF + GSHELPROTATESLIDE4;
|
|
|
|
const GSINITHELPSLIDE = GSINITDIFF + GSHELPSLIDE;
|
|
|
|
const GSINITHELPSLIDE2 = GSINITDIFF + GSHELPSLIDE2;
|
|
|
|
const GSINITHELPSLIDE3 = GSINITDIFF + GSHELPSLIDE3;
|
|
|
|
const GSINITINTRO = GSINITDIFF + GSINTRO;
|
|
|
|
|
|
|
|
const DIFFVERYEASY = 0;
|
|
|
|
const DIFFEASY = 1;
|
|
|
|
const DIFFNORMAL = 2;
|
|
|
|
const DIFFHARD = 3;
|
|
|
|
const DIFFVERYHARD = 4;
|
|
|
|
const DIFFRANDOM = 5;
|
|
|
|
const DIFFCOUNT = 6;
|
|
|
|
|
|
|
|
const GMROTATE = 0;
|
|
|
|
const GMSLIDE = 1;
|
|
|
|
const GMROTATESLIDE = 2;
|
|
|
|
const GMCOUNT = 3;
|
|
|
|
|
|
|
|
const MMSTARTGAME = 0;
|
|
|
|
const MMHELP = 1;
|
|
|
|
const MMOPTIONS = 2;
|
|
|
|
const MMCREDITS = 3;
|
|
|
|
const MMCOUNT = 4;
|
|
|
|
|
|
|
|
const OPSOUND = 0;
|
2023-09-11 20:57:39 +00:00
|
|
|
const OPINPUTRECTS = 1;
|
2023-09-13 23:58:46 +00:00
|
|
|
const OPTHEMING = 2;
|
|
|
|
const OPWIDGETS = 3;
|
|
|
|
const OPCOUNT = 4;
|
2023-09-09 22:32:12 +00:00
|
|
|
|
|
|
|
const TSMAINMENU = 0;
|
|
|
|
const TSGAMEMODE = 1;
|
|
|
|
const TSDIFFICULTY = 2;
|
|
|
|
const TSOPTIONS = 3;
|
|
|
|
const TSCREDITS = 4;
|
|
|
|
|
|
|
|
const LEVELCOUNT = 25;
|
|
|
|
|
|
|
|
const ARROWDOWN = 122;
|
|
|
|
const ARROWUP = 120;
|
|
|
|
const ARROWLEFT = 123;
|
|
|
|
const ARROWRIGHT = 121;
|
|
|
|
const LEFTMENU = 118;
|
2023-09-11 20:57:39 +00:00
|
|
|
const EMPTY = 61;
|
2023-09-09 22:32:12 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
let startPos;
|
|
|
|
let menuPos;
|
|
|
|
let maxLevel;
|
|
|
|
let selectedLevel;
|
|
|
|
let boardX;
|
|
|
|
let boardY;
|
|
|
|
let difficulty;
|
|
|
|
let gameState;
|
|
|
|
let boardWidth;
|
|
|
|
let boardHeight;
|
|
|
|
let boardSize;
|
|
|
|
let levelDone;
|
|
|
|
let titleStep;
|
|
|
|
let gameMode;
|
|
|
|
let posAdd;
|
|
|
|
let mainMenu;
|
|
|
|
let option;
|
|
|
|
let needRedraw;
|
|
|
|
let requiresFlip;
|
|
|
|
let selectionX, selectionY;
|
|
|
|
let moves;
|
|
|
|
let randomSeedGame;
|
|
|
|
let level = new Uint8Array(MAXBOARDSIZE);
|
|
|
|
let redrawPartial;
|
|
|
|
let screenOffsetY;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
// Cursor
|
2023-09-11 20:57:39 +00:00
|
|
|
const cursorNumTiles = 16; //for the max 2 cursors shown at once (on help screens)
|
2023-09-14 19:16:49 +00:00
|
|
|
let showCursor;
|
2023-09-13 10:57:28 +00:00
|
|
|
let spritePos = [];
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
//intro
|
2023-09-13 10:57:28 +00:00
|
|
|
let frames;
|
|
|
|
let titlePosY;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
//savestate
|
2023-09-13 10:57:28 +00:00
|
|
|
let levelLocks = new Uint8Array(GMCOUNT * DIFFCOUNT);
|
|
|
|
let options = new Uint8Array(OPCOUNT);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//sound
|
2023-09-13 10:57:28 +00:00
|
|
|
let soundon = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
|
2023-09-07 02:46:57 +00:00
|
|
|
//game
|
2023-09-13 10:57:28 +00:00
|
|
|
let paused;
|
|
|
|
let wasSoundOn;
|
|
|
|
let redrawLevelDoneBit;
|
|
|
|
let currentTiles = {};
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
//general input
|
2023-09-13 10:57:28 +00:00
|
|
|
let dragleft = false;
|
|
|
|
let dragright = false;
|
|
|
|
let dragup = false;
|
|
|
|
let dragdown = false;
|
|
|
|
let btna = false;
|
|
|
|
let btnb = false;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-14 19:46:08 +00:00
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// images
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
const BLOCKTILES = {
|
|
|
|
width: 10,
|
|
|
|
height: 10,
|
|
|
|
bpp: 2,
|
|
|
|
transparent: -1,
|
|
|
|
palette: new Uint16Array([0, 65535, 0, 0]),
|
|
|
|
buffer: require("heatshrink").decompress(atob("gsFgFQqFVgtVAYIOEBIgTEBwoADDBwxGgoiCBIIKBBIgxLFAQYOMZ5UIMZ4JIMZ5UEGJRjIDBBoGGoYXCBwQ/ESo57DDB4EYGIxmBDqaUEJQxUDSpJjKDBBAPKgYxLMZAYIBIg9BABgdJDCYxGPwoEGGJYYRMaaVJDCZjTGJYYRNAw0OcpIYRAjBPLAiZKMSpIYTLzAdTCY0BqtUHoIAMitVoAdDDCwxGooELGJYYRMax+DDC0FqhKOoJKEGJBjPY4wJBqJADAgyVKDBrHKBIJZEAhIxJDCJjSY5QYTMawxIDCYAWqEUgsBoEFoNQEwIEBKoNABwMABIYOCModVDCdQitFgNUBINAqg5BoIJCBwIJEAgRKQIAQABe4UQikBBwMVoNRDAIECBIIOCBIhjDVwLRBDCg7BMap8PoonBIQLgCMaJZCPgYA/AEblEACsQcQIETGIYYUIqsFF4JjVDARFVfYIxEDClAgEEA4IETDQNUDCoEBig7BAiYxDDChFVY4hjTDARFVVwT2SAAreBAQMUiEEagNAqraBglUgsAiIzBiAzCBoQTBDAsQDBpKYgtUZQJLBgojBAhAOBCYJkFHwIERAAMVGISjFBIQIEBwIJBDBzGEDA8AAgMVoEFBwNBSoITGG4gxGdooxNCYhZGGwUUDBBjJRYQlHAgJKHMYYxTDAxjMitVfI4JJAgIxGBwwsBCYYOCJRR0IfJVQDAcVFgoECBIIYCT4LgNGJoYJHYRPHAAUFRYcVBwhPDiqQBE4MFGIbCEawwJFAgYyDNAK1CAiBKDoFVHIJaFfwpoBBYRKCUgwTCXBQYDbZauLGIkVawQEBT4NEcowxELINRSAZFCSpsFLIizGXAwTBfIxAFJQQiCfJIYCqjvBoNQAgyuDYQQxCJRYTBfwwxGPgIHBFIMBegTlDBwRjEqtBfIQTCBQIELVwiQJfwRAEcAgYPPgYxEdQoEFfIKzDqEFPgbWJDYKfJDBhFCbwwECSoY7CAoKpCVwQaBBAIOCCYL6DYQa/CRAYJKAAgiBO4NBopOBqJTBqgEEgoxEIAJSBqsFUIJwCbgRYBotQAwILBcoQxDioxHAgYJBGIoYGCYMQgFBgEEBIVQJQwYGJQIYFXgIYPqgYEaoQYORYIYFJREFqkBqITBitBgNUioEBBITIBqtACYIYFCYVFoNUDAYMBDBI="))
|
|
|
|
};
|
|
|
|
|
|
|
|
const CONGRATSTILES = {
|
|
|
|
width: 10,
|
|
|
|
height: 10,
|
|
|
|
bpp: 2,
|
|
|
|
transparent: -1,
|
|
|
|
palette: new Uint16Array([0, 65535, 0, 0]),
|
|
|
|
buffer: require("heatshrink").decompress(atob("gtUgFQoEFggEFqoJIDAVQDBEQDowTDGIoEBA4IEJGwQTBGJhPHGKAJGGI4YJHYRPIAAQYJihKFgtACYQxCLxK4LAAQfBAwQEQJQkBAgLCBAgzMCDAzbHqJbDAgT5JbZauMgNAqlUgsRoFRigJCqAEIJQlUEQKpBqL+NAATWCCZpSEGIQYLqr5LGKL5GGJxjJDoKpGAQb3DDoRjEWwL5LAg75HAhbgHDCCuHd5b+Cor5KFgy4MGI0AoiNBXoZ8MNAQTBDQI9CGIILBMAR8GADAA=="))
|
|
|
|
};
|
|
|
|
|
|
|
|
const CONGRATSSCREEN = {
|
|
|
|
width: 160,
|
|
|
|
height: 80,
|
|
|
|
bpp: 2,
|
|
|
|
transparent: -1,
|
|
|
|
palette: new Uint16Array([0, 65535, 0, 0]),
|
|
|
|
buffer: require("heatshrink").decompress(atob("AFUECaVUAokVCRcFqoUFB5FAE40FqAn1CgQWCAQIgCDAMUE44KBE4I0EgInIKQVAqtVDINUgNVBIdUiodBBQVAipPCAYIIBqAUBE4wYCqoTBEAMBqkFooVBEAInDBAQnCqEUCYInMIgITDMoI9CE4gIDE4tACIQntSAgTFMQJ3HE5Z3FqAnKiqfHBAYnHOQYABHIIUBbgInCY4RPEBwhPGCYZPGBYIdBRwInCionFAgVRE4VQBAInCioOCE94AHgItBAEhKBE8oAegkBQoIEBggJCUwVAAgawCLQIEECYSbBoC/DE9gJBE4gDCE4IEDBwYJCCYcAFgIOCcwgTCE8htCE5R8DBwZ3BE46BCO4YxFJ5aaEJ6An5T6oJCiqVDAAIECRYifGKgQnGT4oA/AH4A/AH4A/AH4A/AH4A/AH4AOqoCBqgn/E88UE81VoAndgoGGoNQGZcFE6BHGE8YhDisAiAnTNowABgNQqgTEiEEZBQRBipdGWpEBdAMVgoMCE4MEE6RFCCQ8BisQiIUCiEBogNCIo0BqpHGgIdBE4xFBoInnqEQYQQCBO4S9HE5BtBS4InIoEEE46pEXwlVDpAGDHwQJBgIbBE458BE6BPDLwInOqCpDAAcUCIQnJPoIiBE97XBigEBVIh3RTwInJgoEDE47OBgpYFE4tQigNBD4InGoIZCBIjfFLoQnKCwIHBiogBDodVdQQnGgIyCKQInFR4InCgInCqFUE88QC4ZoEE46LCRoSoDCwhIEI4MVHYgnKDoMVE4LIEIoQnHCgMFBYYhEDoy9CaI6NDE44HCE4yIBSownIDoQnGCgIntA4SWBco4nNS4IhCD4QcGCoSpEBQUVIQgVGAgQhCgInKLIrvDQIIKFCokFRwYnCHQhyEDgoSCPIYKHAgNVBIonsDAgcGFwTRFE4rICD4iyFAAYcFC4cUBIonJDYQTGAAQxGJgMFQIp+GHwzUEE5cAqqRDMJInuABKpJABiYFA=="))
|
|
|
|
};
|
|
|
|
|
|
|
|
const SELECTORTILES = {
|
|
|
|
width: 10,
|
|
|
|
height: 10,
|
|
|
|
bpp: 2,
|
|
|
|
transparent: 0,
|
|
|
|
palette: new Uint16Array([63519, 0, 65535, 0]),
|
|
|
|
buffer: require("heatshrink").decompress(atob("ACeAgEogEC0AaUhQdGHCozYFSYWCAggApGd9AgEUgEBqAaUgodGHCozYFSYWCAggApGbYA=="))
|
|
|
|
};
|
|
|
|
|
|
|
|
const TITLE = {
|
|
|
|
width: 160,
|
|
|
|
height: 50,
|
|
|
|
bpp: 2,
|
|
|
|
transparent: 0,
|
|
|
|
palette: new Uint16Array([63519, 65535, 0, 0]),
|
|
|
|
buffer: require("heatshrink").decompress(atob("AAUC1WglQCBhWoE78KqtoktV0GprREXBQ8JE4mVE61VsAnSHoJ9PNgInL0onHqtawAnNlInMyonD1QABxVVqzTCwACBAAOgAQJMBLwJpBtQnP1NVqoCBq2qLYICBrVVytqBQQOBrQNBHIInOCQIADrICBtWlAgOVsoHB1QCBqwZBPBAnftSyGaQNqBoOiNAISCAAVpAQIxDBgaICE4eVE4zkCBoI7BE4YkBqxVDSgQnGAAQRBUA0COQJlBXINqywrCJYVWDwInBHIQGBAIIRBPwKFBUA4nByzhCtWqE4YVBE4mqfwYnDMIL9BE+CDBRQQhBAYQFEE4NWE4yxDE4KfGE4waBE5ahBE5DvHE4pCD0p3EP4J7DBgJ3D1QDCrQnHEgQnDEYQnUrAmGgEJE9CMCE4SfDqtlAQIiBE46fDtQnkBwNWE5TlCE4rSBE5QRDE4THIhVaSIKKCTATzBSAIMBBoNqSwWlBAKfDAoOVE48CE8+aCgOlAQNltQnCEIIuCAoVptWmy2qAgLvC1OlE48AIoOm1InBtJJCrSWCDgOVa4JHB02V1NqNATMCE5BMBzUKdQK7CJANW0x/BOIOW02KAYJjB0QTBq2JqwnJlVVtECEQOKFANW0RHBgQGB1ApBB4NYlNWwShBtUJUgInIgVVsB7BAQISBqwDBrAGCwElAoInBhINBDAQNB0AmHBwOqBYICChSfBAYOoAwWAlQFB1WoA4IYDE4NoE5AAblNVLYIAjkrdBT5Andd5IAagWlE4KsBE8QmBUEgnrrQnmqwn/E/4n/E4elE8sAkonprQnjlNWqtoE8cKJ4NgE8cCyta0AnjgGVrAmkgGq1AFDA="))
|
|
|
|
};
|
|
|
|
|
2023-09-07 02:46:57 +00:00
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-15 02:18:40 +00:00
|
|
|
// C Code
|
|
|
|
//
|
2023-09-07 02:46:57 +00:00
|
|
|
// random stuff
|
2023-09-11 20:57:39 +00:00
|
|
|
// https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript#72732727
|
2023-09-15 02:18:40 +00:00
|
|
|
// https://www.ams.org/journals/mcom/1999-68-225/S0025-5718-99-00996-5/S0025-5718-99-00996-5.pdf
|
|
|
|
//
|
|
|
|
// power2 function
|
|
|
|
// https://www.geeksforgeeks.org/write-a-c-program-to-calculate-powxn/
|
2023-09-07 02:46:57 +00:00
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-15 02:18:40 +00:00
|
|
|
|
|
|
|
//this will give an uncaught exception in emulator
|
|
|
|
//but code will still run fine as i'll run javascript versions then
|
|
|
|
var c = E.compiledC(`
|
|
|
|
//void srand(int)
|
|
|
|
//int random(int)
|
|
|
|
//void generateLevel(int,int,int)
|
|
|
|
|
|
|
|
unsigned int m;
|
|
|
|
unsigned int a;
|
|
|
|
unsigned int s;
|
|
|
|
|
|
|
|
int power2 (int x, unsigned int y)
|
|
|
|
{
|
|
|
|
int temp;
|
|
|
|
if (y == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
temp = power2 (x, y / 2);
|
|
|
|
if ((y % 2) == 0)
|
|
|
|
return temp * temp;
|
|
|
|
else
|
|
|
|
return x * temp * temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void srand(int seed)
|
|
|
|
{
|
|
|
|
m = power2(2, 16) - 15;
|
|
|
|
a = 33285;
|
|
|
|
s = seed % m;
|
|
|
|
}
|
|
|
|
|
|
|
|
int random(int value)
|
|
|
|
{
|
|
|
|
s = s * a % m;
|
|
|
|
return s % value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void generateLevel(unsigned char* level, int boardWidth, int boardHeight ) {
|
|
|
|
int cc = 0;
|
|
|
|
int currentPoint = 0;
|
|
|
|
int visitedRooms = 1;
|
|
|
|
int tmp, tmp2;
|
|
|
|
int selectedNeighbour;
|
|
|
|
int neighboursFound;
|
|
|
|
int lookUpX, lookUpY;
|
|
|
|
int rnd;
|
|
|
|
int neighbours[4];
|
|
|
|
int cellStack[(boardWidth*boardHeight) +1];
|
|
|
|
|
|
|
|
|
|
|
|
//intial all walls value in every room we will remove bits of this value to remove walls
|
|
|
|
for (int i = 0; i < boardWidth*boardHeight; i++)
|
|
|
|
level[i] = 0xf;
|
|
|
|
|
|
|
|
while (visitedRooms != boardWidth * boardHeight) {
|
|
|
|
neighboursFound = 0;
|
|
|
|
lookUpX = currentPoint % boardWidth;
|
|
|
|
lookUpY = (currentPoint / boardWidth) | 0;
|
|
|
|
|
|
|
|
tmp = currentPoint + 1;
|
|
|
|
//tile has neighbour to the right which we did not handle yet
|
|
|
|
if ((lookUpX + 1 < boardWidth) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
tmp = currentPoint - 1;
|
|
|
|
//tile has neighbour to the left which we did not handle yet
|
|
|
|
if ((lookUpX > 0) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
tmp = currentPoint - boardWidth;
|
|
|
|
//tile has neighbour the north which we did not handle yet
|
|
|
|
if ((lookUpY > 0) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
tmp = currentPoint + boardWidth;
|
|
|
|
//tile has neighbour the south which we did not handle yet
|
|
|
|
if ((lookUpY + 1 < boardHeight) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
if (neighboursFound == 0)
|
|
|
|
{
|
|
|
|
currentPoint = cellStack[--cc];
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
rnd = random(neighboursFound);
|
|
|
|
}
|
|
|
|
|
|
|
|
selectedNeighbour = neighbours[rnd];
|
|
|
|
tmp = (selectedNeighbour % boardWidth);
|
|
|
|
//tile has neighbour to the east
|
|
|
|
if (tmp > lookUpX) {
|
|
|
|
//remove west wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(8);
|
|
|
|
//remove east wall tile
|
|
|
|
level[currentPoint] &= ~(2);
|
|
|
|
} else {
|
|
|
|
// tile has neighbour to the west
|
|
|
|
if (tmp < lookUpX) {
|
|
|
|
//remove east wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(2);
|
|
|
|
//remove west wall tile
|
|
|
|
level[currentPoint] &= ~(8);
|
|
|
|
} else {
|
|
|
|
// tile has neighbour to the north
|
|
|
|
tmp2 = selectedNeighbour / boardWidth;
|
|
|
|
if (tmp2 < lookUpY) {
|
|
|
|
//remove south wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(4);
|
|
|
|
//remove north wall tile
|
|
|
|
level[currentPoint] &= ~(1);
|
|
|
|
} else {
|
|
|
|
// tile has neighbour to the south
|
|
|
|
if (tmp2 > lookUpY) {
|
|
|
|
//remove north wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(1);
|
|
|
|
//remove south wall tile
|
|
|
|
level[currentPoint] &= ~(4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//add tile to the cellstack
|
|
|
|
if (neighboursFound > 1) {
|
|
|
|
cellStack[cc++] = currentPoint;
|
|
|
|
}
|
|
|
|
//set tile to the neighbour
|
|
|
|
currentPoint = selectedNeighbour;
|
|
|
|
visitedRooms++;
|
|
|
|
}
|
|
|
|
}`);
|
|
|
|
|
|
|
|
//when using C Code it will generate levels
|
|
|
|
//a lot faster on the device.
|
|
|
|
//levels generated by the C Code are not the same
|
|
|
|
//as levels generated by the JS Code!
|
|
|
|
const USECCODE = c !== undefined;
|
|
|
|
print("Using C Code:" + USECCODE.toString());
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// random stuff
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
let randfunc;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-15 02:18:40 +00:00
|
|
|
function srandjs(seed) {
|
2023-09-14 19:16:49 +00:00
|
|
|
var m = Math.pow(2, 35) - 31;
|
|
|
|
var a = 185852;
|
|
|
|
var s = seed % m;
|
2023-09-11 20:57:39 +00:00
|
|
|
randfunc = function() {
|
|
|
|
return (s = s * a % m);
|
|
|
|
};
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
2023-09-15 02:18:40 +00:00
|
|
|
function randomjs(value) {
|
2023-09-11 20:57:39 +00:00
|
|
|
return Math.floor(randfunc()) % value;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
2023-09-15 02:18:40 +00:00
|
|
|
function srand(seed) {
|
|
|
|
"RAM";
|
|
|
|
if(USECCODE)
|
|
|
|
c.srand(seed);
|
|
|
|
else
|
|
|
|
srandjs(seed);
|
|
|
|
}
|
|
|
|
|
|
|
|
function random(value) {
|
|
|
|
"RAM";
|
|
|
|
if(USECCODE)
|
|
|
|
return c.random(value);
|
|
|
|
else
|
|
|
|
return randomjs(value);
|
|
|
|
}
|
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
srand(Date().getTime());
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// Sound stuff
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
function setSoundOn(val) {
|
|
|
|
soundOn = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
function isSoundOn() {
|
|
|
|
return soundOn;
|
|
|
|
}
|
|
|
|
|
|
|
|
function playErrorSound() {
|
|
|
|
if (soundOn) {
|
|
|
|
Bangle.buzz(150, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function playMenuAcknowlege() {
|
|
|
|
if (soundOn) {
|
|
|
|
Bangle.buzz(100, 0.75);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function playMenuBackSound() {
|
|
|
|
if (soundOn) {
|
|
|
|
Bangle.buzz(50, 0.4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function playMenuSelectSound() {
|
|
|
|
if (soundOn) {
|
|
|
|
Bangle.buzz(50, 0.6);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function playGameMoveSound() {
|
|
|
|
if (soundOn) {
|
|
|
|
Bangle.buzz(50, 0.6);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function playGameAction() {
|
|
|
|
if (soundOn) {
|
|
|
|
Bangle.buzz(100, 0.75);
|
|
|
|
}
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// Cursor stuff
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-09 22:32:12 +00:00
|
|
|
function move_sprite(sprite, x, y) {
|
|
|
|
spritePos[sprite][0] = x;
|
|
|
|
spritePos[sprite][1] = y;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
function drawCursors(clear) {
|
2023-09-14 19:16:49 +00:00
|
|
|
if (showCursor == 0)
|
2023-09-09 22:32:12 +00:00
|
|
|
return;
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let i = 0; i < cursorNumTiles; i++)
|
2023-09-09 22:32:12 +00:00
|
|
|
if (spritePos[i][1] < SCREENHEIGHT)
|
2023-09-11 20:57:39 +00:00
|
|
|
g.drawImage(SELECTORTILES, SCREENOFFSETX + spritePos[i][0], screenOffsetY + spritePos[i][1], {
|
|
|
|
frame: ((clear ? 8 : 0) + (i % 8))
|
2023-09-09 22:32:12 +00:00
|
|
|
});
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function hideCursors() {
|
|
|
|
//HIDE CURSOR SPRITES
|
|
|
|
//cursor 0
|
|
|
|
setCursorPos(0, 0, (SCREENHEIGHT / TILESIZE) + 1);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//cursor 1
|
|
|
|
setCursorPos(1, 0, (SCREENHEIGHT / TILESIZE) + 1);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
showCursor = 0;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function showCursors() {
|
|
|
|
showCursor = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function setCursorPos(cursorNr, xPos, yPos) {
|
|
|
|
if (cursorNr > 1)
|
|
|
|
return;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
move_sprite((cursorNr << 3) + 0, ((xPos) * TILESIZE), ((yPos - 1) * TILESIZE));
|
|
|
|
move_sprite((cursorNr << 3) + 1, ((xPos + 1) * TILESIZE), ((yPos) * TILESIZE));
|
|
|
|
move_sprite((cursorNr << 3) + 2, ((xPos) * TILESIZE), ((yPos + 1) * TILESIZE));
|
|
|
|
move_sprite((cursorNr << 3) + 3, ((xPos - 1) * TILESIZE), ((yPos) * TILESIZE));
|
|
|
|
//corners
|
|
|
|
move_sprite((cursorNr << 3) + 4, ((xPos + 1) * TILESIZE), ((yPos - 1) * TILESIZE));
|
|
|
|
move_sprite((cursorNr << 3) + 5, ((xPos + 1) * TILESIZE), ((yPos + 1) * TILESIZE));
|
|
|
|
move_sprite((cursorNr << 3) + 6, ((xPos - 1) * TILESIZE), ((yPos - 1) * TILESIZE));
|
|
|
|
move_sprite((cursorNr << 3) + 7, ((xPos - 1) * TILESIZE), ((yPos + 1) * TILESIZE));
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function initCursors() {
|
|
|
|
hideCursors();
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// helper funcs
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-09 22:32:12 +00:00
|
|
|
function set_bkg_tile_xy(x, y, tile) {
|
2023-09-15 02:18:40 +00:00
|
|
|
"RAM";
|
2023-09-11 20:57:39 +00:00
|
|
|
g.drawImage(currentTiles, SCREENOFFSETX + x * TILESIZE, screenOffsetY + y * TILESIZE, {
|
2023-09-09 22:32:12 +00:00
|
|
|
frame: tile
|
|
|
|
});
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function set_bkg_data(tiles) {
|
2023-09-07 02:46:57 +00:00
|
|
|
currentTiles = tiles;
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function get_bkg_data() {
|
2023-09-07 02:46:57 +00:00
|
|
|
return currentTiles;
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function set_bkg_tiles(x, y, map) {
|
2023-09-15 02:18:40 +00:00
|
|
|
"RAM";
|
2023-09-11 20:57:39 +00:00
|
|
|
g.drawImage(map, SCREENOFFSETX + x, screenOffsetY + y);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function setBlockTilesAsBackground() {
|
|
|
|
set_bkg_data(BLOCKTILES);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// help screens
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
//LEGEND STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function inithelpLegend() {
|
|
|
|
setBlockTilesAsBackground();
|
|
|
|
needRedraw = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//LEGEND STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpLegend(nextState) {
|
|
|
|
if ((gameState == GSINITHELPSLIDE) ||
|
|
|
|
(gameState == GSINITHELPROTATE) ||
|
|
|
|
(gameState == GSINITHELPROTATESLIDE)) {
|
|
|
|
inithelpLegend();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna) {
|
|
|
|
playMenuAcknowlege();
|
|
|
|
gameState = nextState;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
if (btnb) {
|
|
|
|
playMenuBackSound();
|
|
|
|
gameState = GSINITTITLE;
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (needRedraw) {
|
|
|
|
g.clearRect(Bangle.appRect);
|
|
|
|
switch (gameState) {
|
|
|
|
case GSHELPSLIDE:
|
|
|
|
printMessage(2, 0, "HELP: SLIDE");
|
|
|
|
break;
|
|
|
|
case GSHELPROTATE:
|
|
|
|
printMessage(2, 0, "HELP: ROTATE");
|
|
|
|
break;
|
|
|
|
case GSHELPROTATESLIDE:
|
|
|
|
printMessage(2, 0, "HELP: ROSLID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
set_bkg_tile_xy(0, 2, 33);
|
|
|
|
printMessage(1, 2, ":WATER SOURCE");
|
|
|
|
set_bkg_tile_xy(0, 3, 11);
|
|
|
|
set_bkg_tile_xy(1, 3, 6);
|
|
|
|
set_bkg_tile_xy(2, 3, 12);
|
|
|
|
printMessage(3, 3, ":NOT FILLED");
|
|
|
|
set_bkg_tile_xy(0, 4, 27);
|
|
|
|
set_bkg_tile_xy(1, 4, 22);
|
|
|
|
set_bkg_tile_xy(2, 4, 28);
|
|
|
|
printMessage(3, 4, ":FILLED");
|
2023-09-09 22:32:12 +00:00
|
|
|
|
|
|
|
if ((gameState == GSHELPROTATESLIDE) ||
|
|
|
|
(gameState == GSHELPSLIDE)) {
|
2023-09-14 19:16:49 +00:00
|
|
|
set_bkg_tile_xy(0, 5, 121);
|
|
|
|
printMessage(1, 5, ":SLID ROW RIGHT");
|
|
|
|
set_bkg_tile_xy(0, 6, 123);
|
|
|
|
printMessage(1, 6, ":SLID ROW LEFT");
|
|
|
|
set_bkg_tile_xy(0, 7, 122);
|
|
|
|
printMessage(1, 7, ":SLID COL DOWN");
|
|
|
|
set_bkg_tile_xy(0, 8, 120);
|
|
|
|
printMessage(1, 8, ":SLID COL UP");
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
needRedraw = 0;
|
|
|
|
requiresFlip = 1;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//FINISH LEVEL STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function initHelpFinishLevel() {
|
|
|
|
setBlockTilesAsBackground();
|
|
|
|
needRedraw = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//FINISH LEVEL STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpFinishLevel(nextState) {
|
|
|
|
if ((gameState == GSINITHELPSLIDE2) ||
|
|
|
|
(gameState == GSINITHELPROTATE2) ||
|
|
|
|
(gameState == GSINITHELPROTATESLIDE2)) {
|
|
|
|
initHelpFinishLevel();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna) {
|
|
|
|
playMenuAcknowlege();
|
|
|
|
gameState = nextState;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
if (btnb) {
|
|
|
|
playMenuBackSound();
|
|
|
|
gameState = GSINITTITLE;
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (needRedraw) {
|
|
|
|
g.clearRect(Bangle.appRect);
|
|
|
|
switch (gameState) {
|
|
|
|
case GSHELPSLIDE2:
|
|
|
|
printMessage(2, 0, "HELP: SLIDE");
|
|
|
|
break;
|
|
|
|
case GSHELPROTATE2:
|
|
|
|
printMessage(2, 0, "HELP: ROTATE");
|
|
|
|
break;
|
|
|
|
case GSHELPROTATESLIDE2:
|
|
|
|
printMessage(2, 0, "HELP: ROSLID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
printMessage(0, 2, "LEVEL FINISH:");
|
|
|
|
|
|
|
|
if ((gameState == GSHELPSLIDE2) ||
|
|
|
|
(gameState == GSHELPROTATESLIDE2)) {
|
|
|
|
//arrows top
|
|
|
|
set_bkg_tile_xy(2, 3, 122);
|
|
|
|
set_bkg_tile_xy(3, 3, 122);
|
|
|
|
set_bkg_tile_xy(4, 3, 122);
|
|
|
|
|
|
|
|
//arrows left / right row 1
|
|
|
|
set_bkg_tile_xy(1, 4, 121);
|
|
|
|
set_bkg_tile_xy(5, 4, 123);
|
|
|
|
|
|
|
|
//arrows left / right row 2
|
|
|
|
set_bkg_tile_xy(1, 5, 121);
|
|
|
|
set_bkg_tile_xy(5, 5, 123);
|
|
|
|
|
|
|
|
//arrows left / right row 3
|
|
|
|
set_bkg_tile_xy(1, 6, 121);
|
|
|
|
set_bkg_tile_xy(5, 6, 123);
|
|
|
|
|
|
|
|
//arrows bottom
|
|
|
|
set_bkg_tile_xy(2, 7, 120);
|
|
|
|
set_bkg_tile_xy(3, 7, 120);
|
|
|
|
set_bkg_tile_xy(4, 7, 120);
|
|
|
|
}
|
|
|
|
|
|
|
|
set_bkg_tile_xy(2, 4, 25);
|
|
|
|
set_bkg_tile_xy(3, 4, 23);
|
|
|
|
set_bkg_tile_xy(4, 4, 27);
|
|
|
|
printMessage(7, 4, "ALL WATER");
|
|
|
|
|
|
|
|
set_bkg_tile_xy(2, 5, 28);
|
|
|
|
set_bkg_tile_xy(3, 5, 33);
|
|
|
|
set_bkg_tile_xy(4, 5, 22);
|
|
|
|
printMessage(7, 5, "PIPES ARE");
|
|
|
|
|
|
|
|
set_bkg_tile_xy(2, 6, 29);
|
|
|
|
set_bkg_tile_xy(3, 6, 20);
|
|
|
|
set_bkg_tile_xy(4, 6, 23);
|
|
|
|
printMessage(7, 6, "FILLED");
|
|
|
|
needRedraw = 0;
|
|
|
|
requiresFlip = 1;
|
|
|
|
}
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function initHelpDoSlideRotate() {
|
|
|
|
setBlockTilesAsBackground();
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//DRAW CURSOR SPRITES
|
|
|
|
initCursors();
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if ((gameState == GSINITHELPROTATESLIDE4) ||
|
|
|
|
(gameState == GSINITHELPSLIDE3)) {
|
|
|
|
setCursorPos(0, 0, 5);
|
|
|
|
setCursorPos(1, 11, 5);
|
|
|
|
} else {
|
|
|
|
setCursorPos(0, 1, 4);
|
|
|
|
setCursorPos(1, 12, 4);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
showCursors();
|
|
|
|
needRedraw = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpDoSlideRotate(nextState) {
|
|
|
|
if ((gameState == GSINITHELPSLIDE3) ||
|
|
|
|
(gameState == GSINITHELPROTATE3) ||
|
|
|
|
(gameState == GSINITHELPROTATESLIDE3) ||
|
|
|
|
(gameState == GSINITHELPROTATESLIDE4)) {
|
|
|
|
initHelpDoSlideRotate();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna) {
|
|
|
|
playMenuAcknowlege();
|
|
|
|
gameState = nextState;
|
|
|
|
hideCursors();
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
if (btnb) {
|
|
|
|
playMenuBackSound();
|
|
|
|
gameState = GSINITTITLE;
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (needRedraw) {
|
|
|
|
g.clearRect(Bangle.appRect);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
switch (gameState) {
|
|
|
|
case GSHELPSLIDE3:
|
|
|
|
printMessage(2, 0, "HELP: SLIDE");
|
|
|
|
break;
|
|
|
|
case GSHELPROTATE3:
|
|
|
|
printMessage(2, 0, "HELP: ROTATE");
|
|
|
|
break;
|
|
|
|
case GSHELPROTATESLIDE3:
|
|
|
|
case GSHELPROTATESLIDE4:
|
|
|
|
printMessage(2, 0, "HELP: ROSLID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((gameState == GSHELPROTATESLIDE3) ||
|
|
|
|
(gameState == GSHELPROTATE3))
|
|
|
|
printMessage(5, 2, "ROTATE");
|
|
|
|
else
|
|
|
|
printMessage(6, 2, "SLIDE");
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
// 'A' + '=>'
|
|
|
|
set_bkg_tile_xy(6, 5, 119);
|
|
|
|
printMessage(5, 5, "TOUCH");
|
|
|
|
set_bkg_tile_xy(10, 5, 118);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if ((gameState == GSHELPSLIDE3) ||
|
|
|
|
(gameState == GSHELPROTATESLIDE3) ||
|
|
|
|
(gameState == GSHELPROTATESLIDE4)) {
|
|
|
|
//Top Arrows
|
|
|
|
set_bkg_tile_xy(1, 3, 122);
|
|
|
|
set_bkg_tile_xy(2, 3, 122);
|
|
|
|
set_bkg_tile_xy(3, 3, 122);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//arrows 1st row
|
|
|
|
set_bkg_tile_xy(0, 4, 121);
|
|
|
|
set_bkg_tile_xy(4, 4, 123);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//arrows 2nd row
|
|
|
|
set_bkg_tile_xy(0, 5, 121);
|
|
|
|
set_bkg_tile_xy(4, 5, 123);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//arrows 3rd row
|
|
|
|
set_bkg_tile_xy(0, 6, 121);
|
|
|
|
set_bkg_tile_xy(4, 6, 123);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//arrows bottom
|
|
|
|
set_bkg_tile_xy(1, 7, 120);
|
|
|
|
set_bkg_tile_xy(2, 7, 120);
|
|
|
|
set_bkg_tile_xy(3, 7, 120);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//2nd grid
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//Top Arrows
|
|
|
|
set_bkg_tile_xy(12, 3, 122);
|
|
|
|
set_bkg_tile_xy(13, 3, 122);
|
|
|
|
set_bkg_tile_xy(14, 3, 122);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//arrows 1st row
|
|
|
|
set_bkg_tile_xy(11, 4, 121);
|
|
|
|
set_bkg_tile_xy(15, 4, 123);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//arrows 2nd row
|
|
|
|
set_bkg_tile_xy(11, 5, 121);
|
|
|
|
set_bkg_tile_xy(15, 5, 123);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//arrows 3rd row
|
|
|
|
set_bkg_tile_xy(11, 6, 121);
|
|
|
|
set_bkg_tile_xy(15, 6, 123);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//bottoms arrows
|
|
|
|
set_bkg_tile_xy(12, 7, 120);
|
|
|
|
set_bkg_tile_xy(13, 7, 120);
|
|
|
|
set_bkg_tile_xy(14, 7, 120);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//1st grid
|
|
|
|
if ((gameState == GSHELPROTATE3) ||
|
|
|
|
(gameState == GSHELPROTATESLIDE3)) {
|
|
|
|
set_bkg_tile_xy(1, 4, 12);
|
|
|
|
set_bkg_tile_xy(2, 4, 7);
|
|
|
|
set_bkg_tile_xy(3, 4, 27);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
set_bkg_tile_xy(1, 5, 28);
|
|
|
|
set_bkg_tile_xy(2, 5, 33);
|
|
|
|
set_bkg_tile_xy(3, 5, 22);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
set_bkg_tile_xy(1, 6, 29);
|
|
|
|
set_bkg_tile_xy(2, 6, 20);
|
|
|
|
set_bkg_tile_xy(3, 6, 23);
|
|
|
|
} else {
|
|
|
|
set_bkg_tile_xy(1, 4, 9);
|
|
|
|
set_bkg_tile_xy(2, 4, 7);
|
|
|
|
set_bkg_tile_xy(3, 4, 11);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
set_bkg_tile_xy(1, 5, 17);
|
|
|
|
set_bkg_tile_xy(2, 5, 38);
|
|
|
|
set_bkg_tile_xy(3, 5, 12);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
set_bkg_tile_xy(1, 6, 13);
|
|
|
|
set_bkg_tile_xy(2, 6, 4);
|
|
|
|
set_bkg_tile_xy(3, 6, 7);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//2nd grid
|
|
|
|
|
|
|
|
set_bkg_tile_xy(12, 4, 25);
|
|
|
|
set_bkg_tile_xy(13, 4, 23);
|
|
|
|
set_bkg_tile_xy(14, 4, 27);
|
|
|
|
|
|
|
|
set_bkg_tile_xy(12, 5, 28);
|
|
|
|
set_bkg_tile_xy(13, 5, 33);
|
|
|
|
set_bkg_tile_xy(14, 5, 22);
|
|
|
|
|
|
|
|
set_bkg_tile_xy(12, 6, 29);
|
|
|
|
set_bkg_tile_xy(13, 6, 20);
|
|
|
|
set_bkg_tile_xy(14, 6, 23);
|
|
|
|
|
|
|
|
drawCursors();
|
|
|
|
needRedraw = 0;
|
|
|
|
requiresFlip = 1;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//LEGEND STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpRotateSlide() {
|
|
|
|
helpLegend(GSINITHELPROTATESLIDE2);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//FINISH LEVEL STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpRotateSlide2() {
|
|
|
|
helpFinishLevel(GSINITHELPROTATESLIDE3);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//SLIDE STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpRotateSlide3() {
|
|
|
|
helpDoSlideRotate(GSINITHELPROTATESLIDE4);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//ROTATE STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpRotateSlide4() {
|
|
|
|
helpDoSlideRotate(GSINITTITLE);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpRotate() {
|
|
|
|
helpLegend(GSINITHELPROTATE2);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//FINISH LEVEL STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpRotate2() {
|
|
|
|
helpFinishLevel(GSINITHELPROTATE3);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//ROTATE STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpRotate3() {
|
|
|
|
helpDoSlideRotate(GSINITTITLE);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//LEGEND STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpSlide() {
|
|
|
|
helpLegend(GSINITHELPSLIDE2);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//FINISH LEVEL STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpSlide2() {
|
|
|
|
helpFinishLevel(GSINITHELPSLIDE3);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//SLIDE STATE
|
2023-09-09 22:32:12 +00:00
|
|
|
function helpSlide3() {
|
|
|
|
helpDoSlideRotate(GSINITTITLE);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// Intro
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-09 22:32:12 +00:00
|
|
|
function initIntro() {
|
|
|
|
setBlockTilesAsBackground();
|
|
|
|
titlePosY = g.getHeight();
|
|
|
|
frames = 0;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function intro() {
|
|
|
|
if (gameState == GSINITINTRO) {
|
|
|
|
initIntro();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna || btnb) {
|
|
|
|
gameState = GSINITTITLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
frames++;
|
|
|
|
g.clearRect(Bangle.appRect);
|
2023-09-14 19:16:49 +00:00
|
|
|
if (frames < 16) {
|
2023-09-09 22:32:12 +00:00
|
|
|
//16-12
|
|
|
|
printMessage(4 >> 1, 4, "WILLEMS DAVY");
|
|
|
|
requiresFlip = 1;
|
|
|
|
} else {
|
2023-09-14 19:16:49 +00:00
|
|
|
if (frames < 16 * 2) {
|
2023-09-09 22:32:12 +00:00
|
|
|
//16-8
|
|
|
|
printMessage(8 >> 1, 4, "PRESENTS");
|
|
|
|
requiresFlip = 1;
|
|
|
|
} else {
|
|
|
|
requiresFlip = 1;
|
|
|
|
g.drawImage(TITLE, SCREENOFFSETX, titlePosY);
|
2023-09-11 20:57:39 +00:00
|
|
|
if (titlePosY > screenOffsetY) {
|
2023-09-14 19:16:49 +00:00
|
|
|
titlePosY -= 4;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
gameState = GSINITTITLE;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// Level Stuff
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-15 02:18:40 +00:00
|
|
|
|
|
|
|
function generateLeveljs() {
|
|
|
|
let neighbours = new Uint8Array(4);
|
|
|
|
let cellStack = [];//new Uint8Array(boardSize + 1);
|
|
|
|
let cc = 0;
|
|
|
|
let currentPoint = 0;
|
|
|
|
let visitedRooms = 1;
|
|
|
|
let tmp, tmp2;
|
|
|
|
let selectedNeighbour;
|
|
|
|
let neighboursFound;
|
|
|
|
let lookUpX, lookUpY;
|
|
|
|
let rnd;
|
|
|
|
|
|
|
|
//intial all walls value in every room we will remove bits of this value to remove walls
|
|
|
|
level.fill(0xf, 0, boardSize);
|
|
|
|
|
|
|
|
while (visitedRooms != boardSize) {
|
|
|
|
neighboursFound = 0;
|
|
|
|
lookUpX = currentPoint % boardWidth;
|
|
|
|
lookUpY = (currentPoint / boardWidth) | 0;
|
|
|
|
|
|
|
|
tmp = currentPoint + 1;
|
|
|
|
//tile has neighbour to the right which we did not handle yet
|
|
|
|
if ((lookUpX + 1 < boardWidth) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
tmp = currentPoint - 1;
|
|
|
|
//tile has neighbour to the left which we did not handle yet
|
|
|
|
if ((lookUpX > 0) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
tmp = currentPoint - boardWidth;
|
|
|
|
//tile has neighbour the north which we did not handle yet
|
|
|
|
if ((lookUpY > 0) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
tmp = currentPoint + boardWidth;
|
|
|
|
//tile has neighbour the south which we did not handle yet
|
|
|
|
if ((lookUpY + 1 < boardHeight) && (level[tmp] == 0xf))
|
|
|
|
neighbours[neighboursFound++] = tmp;
|
|
|
|
|
|
|
|
if (neighboursFound == 0)
|
|
|
|
{
|
|
|
|
currentPoint = cellStack[--cc];
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
rnd = random(neighboursFound);
|
|
|
|
}
|
|
|
|
|
|
|
|
selectedNeighbour = neighbours[rnd];
|
|
|
|
tmp = (selectedNeighbour % boardWidth);
|
|
|
|
//tile has neighbour to the east
|
|
|
|
if (tmp > lookUpX) {
|
|
|
|
//remove west wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(8);
|
|
|
|
//remove east wall tile
|
|
|
|
level[currentPoint] &= ~(2);
|
|
|
|
} else {
|
|
|
|
// tile has neighbour to the west
|
|
|
|
if (tmp < lookUpX) {
|
|
|
|
//remove east wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(2);
|
|
|
|
//remove west wall tile
|
|
|
|
level[currentPoint] &= ~(8);
|
|
|
|
} else {
|
|
|
|
// tile has neighbour to the north
|
|
|
|
tmp2 = selectedNeighbour / boardWidth;
|
|
|
|
if (tmp2 < lookUpY) {
|
|
|
|
//remove south wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(4);
|
|
|
|
//remove north wall tile
|
|
|
|
level[currentPoint] &= ~(1);
|
|
|
|
} else {
|
|
|
|
// tile has neighbour to the south
|
|
|
|
if (tmp2 > lookUpY) {
|
|
|
|
//remove north wall neighbour
|
|
|
|
level[selectedNeighbour] &= ~(1);
|
|
|
|
//remove south wall tile
|
|
|
|
level[currentPoint] &= ~(4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//add tile to the cellstack
|
|
|
|
if (neighboursFound > 1) {
|
|
|
|
cellStack[cc++] = currentPoint;
|
|
|
|
}
|
|
|
|
//set tile to the neighbour
|
|
|
|
currentPoint = selectedNeighbour;
|
|
|
|
visitedRooms++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function generateLevel()
|
|
|
|
{
|
|
|
|
"RAM";
|
|
|
|
if(USECCODE)
|
|
|
|
{
|
|
|
|
var cellstack = new Uint8Array(MAXBOARDSIZE + 1);
|
|
|
|
var neighbours = new Uint8Array(4);
|
|
|
|
var addrLevel = E.getAddressOf(level,true);
|
|
|
|
c.generateLevel(addrLevel, boardWidth, boardHeight);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
generateLeveljs();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function moveBlockDown(aTile) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let tmp = level[aTile + boardSize - boardWidth];
|
|
|
|
for (let i = boardSize - boardWidth; i != 0; i -= boardWidth)
|
2023-09-09 22:32:12 +00:00
|
|
|
level[aTile + i] = level[aTile + i - boardWidth];
|
|
|
|
level[aTile] = tmp;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function moveBlockUp(aTile) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let tmp = level[aTile - boardSize + boardWidth];
|
|
|
|
for (let i = boardSize - boardWidth; i != 0; i -= boardWidth)
|
2023-09-09 22:32:12 +00:00
|
|
|
level[aTile - i] = level[aTile - i + boardWidth];
|
|
|
|
level[aTile] = tmp;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function moveBlockRight(aTile) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let tmp = level[aTile + boardWidth - 1];
|
|
|
|
for (let i = 0; i < boardWidth - 1; i++)
|
2023-09-09 22:32:12 +00:00
|
|
|
level[aTile + boardWidth - 1 - i] = level[aTile + boardWidth - 2 - i];
|
|
|
|
level[aTile] = tmp;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function moveBlockLeft(aTile) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let tmp = level[aTile - boardWidth + 1];
|
|
|
|
for (let i = 0; i < boardWidth - 1; i++)
|
2023-09-09 22:32:12 +00:00
|
|
|
level[aTile - boardWidth + 1 + i] = level[aTile - boardWidth + 2 + i];
|
|
|
|
level[aTile] = tmp;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//rotates a tile by change the tilenr in the level
|
|
|
|
//there are 16 tiles per set and there are 3 sets no water, water filled, and special start tiles
|
2023-09-09 22:32:12 +00:00
|
|
|
function rotateBlock(aTile) {
|
|
|
|
switch (level[aTile]) {
|
|
|
|
case 1:
|
|
|
|
case 17:
|
|
|
|
case 33:
|
|
|
|
level[aTile] = 2;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
case 18:
|
|
|
|
case 34:
|
|
|
|
level[aTile] = 4;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
case 19:
|
|
|
|
case 35:
|
|
|
|
level[aTile] = 6;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
case 20:
|
|
|
|
case 36:
|
|
|
|
level[aTile] = 8;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
case 21:
|
|
|
|
case 37:
|
|
|
|
level[aTile] = 10;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
case 22:
|
|
|
|
case 38:
|
|
|
|
level[aTile] = 12;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
case 23:
|
|
|
|
case 39:
|
|
|
|
level[aTile] = 14;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
case 24:
|
|
|
|
case 40:
|
|
|
|
level[aTile] = 1;
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
case 25:
|
|
|
|
case 41:
|
|
|
|
level[aTile] = 3;
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
case 26:
|
|
|
|
case 42:
|
|
|
|
level[aTile] = 5;
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
case 27:
|
|
|
|
case 43:
|
|
|
|
level[aTile] = 7;
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
case 28:
|
|
|
|
case 44:
|
|
|
|
level[aTile] = 9;
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
case 29:
|
|
|
|
case 45:
|
|
|
|
level[aTile] = 11;
|
|
|
|
break;
|
|
|
|
case 14:
|
|
|
|
case 30:
|
|
|
|
case 46:
|
|
|
|
level[aTile] = 13;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function shuffleSlide(aTile) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let rnd = random(3);
|
2023-09-09 22:32:12 +00:00
|
|
|
switch (rnd) {
|
|
|
|
case 0:
|
|
|
|
moveBlockUp((aTile % boardWidth) + boardSize - boardWidth);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
moveBlockDown((aTile % boardWidth));
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
moveBlockLeft(boardWidth - 1 + aTile - (aTile % boardWidth));
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
moveBlockRight(aTile - (aTile % boardWidth));
|
|
|
|
break;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function shuffleRotate(aTile) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let rnd = random(3);
|
|
|
|
for (let i = 0; i < rnd; i++)
|
2023-09-09 22:32:12 +00:00
|
|
|
rotateBlock(aTile);
|
|
|
|
}
|
|
|
|
|
|
|
|
function shuffleLevel() {
|
2023-09-13 10:57:28 +00:00
|
|
|
let rnd;
|
|
|
|
let j = 0;
|
2023-09-09 22:32:12 +00:00
|
|
|
while (j < boardSize) {
|
|
|
|
switch (gameMode) {
|
|
|
|
case GMROTATE:
|
|
|
|
shuffleRotate(j);
|
|
|
|
j++;
|
|
|
|
break;
|
|
|
|
case GMSLIDE:
|
|
|
|
shuffleSlide(j);
|
|
|
|
//for speed up it should be fine as all slide levels are uneven in width / height (except random)
|
|
|
|
j += 2;
|
|
|
|
break;
|
|
|
|
case GMROTATESLIDE:
|
|
|
|
rnd = random(2);
|
|
|
|
if (rnd == 0) {
|
|
|
|
shuffleSlide(j);
|
|
|
|
//for speed up
|
|
|
|
j += 2;
|
|
|
|
} else {
|
|
|
|
shuffleRotate(j);
|
|
|
|
j++;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function handleConnectPoint(currentPoint, cellStack, cc) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let lookUpX = currentPoint % boardWidth;
|
2023-09-14 19:16:49 +00:00
|
|
|
let lookUpY = (currentPoint / boardWidth) | 0;
|
2023-09-13 10:57:28 +00:00
|
|
|
let tmp;
|
|
|
|
let tmp2;
|
2023-09-09 22:32:12 +00:00
|
|
|
if ((lookUpY > 0) && (!(level[currentPoint] & 1))) {
|
|
|
|
tmp = currentPoint - boardWidth;
|
|
|
|
tmp2 = level[tmp];
|
|
|
|
if (((tmp2 < 16) && (!(tmp2 & 4))) ||
|
|
|
|
((tmp2 > 15) && (!((tmp2 - 16) & 4)))) {
|
|
|
|
//adapt tile to filled tile
|
|
|
|
if (level[currentPoint] < 16) {
|
|
|
|
level[currentPoint] += 16;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//add neighbour to cellstack of to handle tiles
|
|
|
|
if (tmp2 < 16) {
|
|
|
|
cellStack[cc++] = tmp;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//if tile has passage to the east and east neigbour passage to the west
|
2023-09-09 22:32:12 +00:00
|
|
|
if ((lookUpX + 1 < boardWidth) && (!(level[currentPoint] & 2))) {
|
|
|
|
tmp = currentPoint + 1;
|
|
|
|
tmp2 = level[tmp];
|
|
|
|
if (((tmp2 < 16) && (!(tmp2 & 8))) ||
|
|
|
|
((tmp2 > 15) && (!((tmp2 - 16) & 8)))) {
|
|
|
|
//adapt tile to filled tile
|
|
|
|
if (level[currentPoint] < 16) {
|
|
|
|
level[currentPoint] += 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
//add neighbour to cellstack of to handle tiles
|
|
|
|
if (tmp2 < 16) {
|
|
|
|
cellStack[cc++] = tmp;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//if tile has passage to the south and south neigbour passage to the north
|
2023-09-09 22:32:12 +00:00
|
|
|
if ((lookUpY + 1 < boardHeight) && (!(level[currentPoint] & 4))) {
|
|
|
|
tmp = currentPoint + boardWidth;
|
|
|
|
tmp2 = level[tmp];
|
|
|
|
if (((tmp2 < 16) && (!(tmp2 & 1))) ||
|
|
|
|
((tmp2 > 15) && (!((tmp2 - 16) & 1)))) {
|
|
|
|
//adapt tile to filled tile
|
|
|
|
if (level[currentPoint] < 16) {
|
|
|
|
level[currentPoint] += 16;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//add neighbour to cellstack of to handle tiles
|
|
|
|
if (tmp2 < 16) {
|
|
|
|
cellStack[cc++] = tmp;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//if tile has passage to the west and west neigbour passage to the east
|
2023-09-09 22:32:12 +00:00
|
|
|
if ((lookUpX > 0) && (!(level[currentPoint] & 8))) {
|
|
|
|
tmp = currentPoint - 1;
|
|
|
|
tmp2 = level[tmp];
|
|
|
|
if (((tmp2 < 16) && (!(tmp2 & 2))) ||
|
|
|
|
((tmp2 > 15) && (!((tmp2 - 16) & 2)))) {
|
|
|
|
//adapt tile to filled tile
|
|
|
|
if (level[currentPoint] < 16) {
|
|
|
|
level[currentPoint] += 16;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//add neighbour to cellstack of to handle tiles
|
|
|
|
if (tmp2 < 16) {
|
|
|
|
cellStack[cc++] = tmp;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
return cc;
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function updateConnected() {
|
2023-09-14 19:16:49 +00:00
|
|
|
let cellStack = [];//new Uint8Array(boardSize + 1);
|
2023-09-09 22:32:12 +00:00
|
|
|
//reset all tiles to default not filled one
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let i = 0; i != boardSize; i++) {
|
2023-09-09 22:32:12 +00:00
|
|
|
if (level[i] > 31) {
|
|
|
|
level[i] -= 32;
|
|
|
|
} else {
|
|
|
|
if (level[i] > 15) {
|
|
|
|
level[i] -= 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//start with start tile
|
2023-09-13 10:57:28 +00:00
|
|
|
let cc = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
cc = handleConnectPoint(startPos, cellStack, cc);
|
|
|
|
while (--cc > 0) {
|
|
|
|
//if tile is bigger then 15 we already handled this one, continue with next one
|
|
|
|
if ((level[cellStack[cc]] < 16)) {
|
|
|
|
cc = handleConnectPoint(cellStack[cc], cellStack, cc);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//add start pos special tile
|
2023-09-14 19:16:49 +00:00
|
|
|
if (level[startPos] > 15) {
|
2023-09-09 22:32:12 +00:00
|
|
|
level[startPos] += 16;
|
2023-09-14 19:16:49 +00:00
|
|
|
} else {
|
|
|
|
if (level[startPos] < 16)
|
|
|
|
level[startPos] += 32;
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
//when all board tiles are not below 16, the level is cleared
|
2023-09-11 20:57:39 +00:00
|
|
|
//as there are 16 tiles per tilegroup (no water, water, special start with water)
|
2023-09-09 22:32:12 +00:00
|
|
|
function isLevelDone() {
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let i = 0; i != boardSize; i++)
|
2023-09-09 22:32:12 +00:00
|
|
|
if (level[i] < 16)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
function initLevel(aRandomSeed, noLoading) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let startTime = Date().getTime();
|
2023-09-11 20:57:39 +00:00
|
|
|
if (!noLoading) {
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(((16 - 10) >> 1), (MAXBOARDHEIGHT >> 1) - 1, "[*********]");
|
|
|
|
printMessage(((16 - 10) >> 1), (MAXBOARDHEIGHT >> 1) - 0, "| LOADING +");
|
|
|
|
printMessage(((16 - 10) >> 1), (MAXBOARDHEIGHT >> 1) + 1, "<#########>");
|
2023-09-11 20:57:39 +00:00
|
|
|
g.flip();
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
levelDone = 0;
|
|
|
|
moves = 0;
|
|
|
|
if (difficulty != DIFFRANDOM)
|
|
|
|
//use level number + fixed value based on difficulty as seed for the random function
|
|
|
|
//this makes sure every level from a difficulty will remain the same
|
|
|
|
srand(selectedLevel + (difficulty * 500) + (gameMode * 50));
|
|
|
|
else
|
|
|
|
srand(aRandomSeed);
|
|
|
|
|
|
|
|
maxLevel = LEVELCOUNT;
|
|
|
|
//set boardsize and max level based on difficulty
|
|
|
|
switch (difficulty) {
|
|
|
|
case DIFFVERYEASY:
|
|
|
|
boardWidth = 5;
|
|
|
|
boardHeight = 5;
|
|
|
|
break;
|
|
|
|
case DIFFEASY:
|
|
|
|
boardWidth = 6;
|
|
|
|
boardHeight = 6;
|
|
|
|
break;
|
|
|
|
case DIFFNORMAL:
|
|
|
|
boardWidth = 7;
|
|
|
|
boardHeight = 7;
|
|
|
|
break;
|
|
|
|
case DIFFHARD:
|
|
|
|
boardWidth = 8;
|
|
|
|
boardHeight = 8;
|
|
|
|
break;
|
|
|
|
case DIFFVERYHARD:
|
|
|
|
boardWidth = 10;
|
|
|
|
boardHeight = 8;
|
|
|
|
break;
|
|
|
|
case DIFFRANDOM:
|
2023-09-13 10:57:28 +00:00
|
|
|
let rnd = random(255);
|
2023-09-09 22:32:12 +00:00
|
|
|
boardWidth = 5 + (rnd % (MAXBOARDWIDTH - 5 + 1)); //5 is smallest level width from very easy
|
|
|
|
rnd = random(255);
|
|
|
|
boardHeight = 5 + (rnd % (MAXBOARDHEIGHT - 5 + 1)); //5 is smallest level height from very easy
|
|
|
|
maxLevel = 0; //special value with random
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//add space for arrows based on same posadd value (1 or 0 depending if sliding is allowed)
|
|
|
|
boardWidth -= posAdd + posAdd;
|
|
|
|
boardHeight -= posAdd + posAdd;
|
|
|
|
boardSize = boardWidth * boardHeight;
|
|
|
|
//generate the level
|
|
|
|
generateLevel();
|
|
|
|
//startpoint of of level in center of screen
|
2023-09-14 19:16:49 +00:00
|
|
|
boardX = (MAXBOARDWIDTH - boardWidth) >> 1;
|
|
|
|
boardY = (MAXBOARDHEIGHT - boardHeight) >> 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
startPos = (boardWidth >> 1) + (boardHeight >> 1) * (boardWidth);
|
|
|
|
//startpoint of tile with water and our cursor
|
|
|
|
selectionX = boardWidth >> 1;
|
|
|
|
selectionY = boardHeight >> 1;
|
|
|
|
|
|
|
|
//level is currently the solution so we still need to shuffle it
|
|
|
|
shuffleLevel();
|
|
|
|
//update possibly connected tiles already starting from startpoint
|
|
|
|
updateConnected();
|
2023-09-11 20:57:39 +00:00
|
|
|
if (DEBUGMODESPEED)
|
|
|
|
debugLog("Level Generated in " + (Date().getTime() - startTime).toString() + " ms");
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// levels cleared
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-09 22:32:12 +00:00
|
|
|
function initLevelsCleared() {
|
|
|
|
set_bkg_data(CONGRATSTILES);
|
|
|
|
g.clearRect(Bangle.appRect);
|
2023-09-11 20:57:39 +00:00
|
|
|
g.drawImage(CONGRATSSCREEN, SCREENOFFSETX, screenOffsetY);
|
2023-09-09 22:32:12 +00:00
|
|
|
switch (difficulty) {
|
|
|
|
case DIFFVERYEASY:
|
|
|
|
printCongratsScreen(0, 3, "VERY EASY LEVELS");
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
case DIFFEASY:
|
|
|
|
printCongratsScreen(3, 3, "EASY LEVELS");
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
case DIFFNORMAL:
|
|
|
|
printCongratsScreen(2, 3, "NORMAL LEVELS");
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
case DIFFHARD:
|
|
|
|
printCongratsScreen(3, 3, "HARD LEVELS");
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
case DIFFVERYHARD:
|
|
|
|
printCongratsScreen(0, 3, "VERY HARD LEVELS");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
requiresFlip = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function levelsCleared() {
|
|
|
|
if (gameState == GSINITLEVELSCLEARED) {
|
|
|
|
initLevelsCleared();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna || btnb) {
|
|
|
|
playMenuAcknowlege();
|
|
|
|
titleStep = TSMAINMENU;
|
|
|
|
gameState = GSINITTITLE;
|
|
|
|
}
|
|
|
|
needRedraw = 0;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// level select
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-13 10:57:28 +00:00
|
|
|
function drawLevelSelect(partial) {
|
2023-09-14 19:16:49 +00:00
|
|
|
if (partial > 2) {
|
2023-09-13 10:57:28 +00:00
|
|
|
g.clearRect(Bangle.appRect);
|
|
|
|
//LEVEL:
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 0, "LEVEL:");
|
2023-09-13 10:57:28 +00:00
|
|
|
}
|
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
if (partial == 2) {
|
2023-09-13 10:57:28 +00:00
|
|
|
//clear parts of loading text
|
2023-09-13 23:58:46 +00:00
|
|
|
g.setColor(g.getBgColor());
|
2023-09-13 10:57:28 +00:00
|
|
|
g.fillRect(SCREENOFFSETX + (boardX + boardWidth) * TILESIZE, screenOffsetY + 3 * TILESIZE, SCREENOFFSETX - 1 + (boardX + MAXBOARDWIDTH + 5) * TILESIZE, screenOffsetY - 1 + 6 * TILESIZE);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//[LEVEL NR] 2 chars
|
2023-09-14 19:16:49 +00:00
|
|
|
if (partial == 2)
|
|
|
|
set_bkg_tile_xy(MAXBOARDWIDTH + 4, 1, EMPTY);
|
2023-09-13 10:57:28 +00:00
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
printNumber(MAXBOARDWIDTH + 4, 1, selectedLevel, 2);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
if (partial > 2) {
|
2023-09-13 10:57:28 +00:00
|
|
|
//B:BACK
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 6, "BTN:");
|
|
|
|
printMessage(MAXBOARDWIDTH, 7, "BACK");
|
2023-09-13 10:57:28 +00:00
|
|
|
}
|
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
if (partial > 1) {
|
2023-09-13 10:57:28 +00:00
|
|
|
//A:PLAY
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 4, "TOUCH:");
|
|
|
|
printMessage(MAXBOARDWIDTH, 5, "PLAY");
|
2023-09-13 10:57:28 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//Locked & Unlocked keywoard
|
2023-09-13 10:57:28 +00:00
|
|
|
let tmpUnlocked = levelUnlocked(gameMode, difficulty, selectedLevel - 1);
|
2023-09-09 22:32:12 +00:00
|
|
|
if (!tmpUnlocked)
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 2, "LOCKED");
|
2023-09-09 22:32:12 +00:00
|
|
|
else
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 2, "OPEN ");
|
2023-09-13 10:57:28 +00:00
|
|
|
|
2023-09-14 19:16:49 +00:00
|
|
|
if (partial > 2) {
|
2023-09-13 10:57:28 +00:00
|
|
|
//Draw arrows for vertical / horizontal movement
|
|
|
|
if (gameMode != GMROTATE) {
|
|
|
|
for (let x = 0; x != boardWidth; x++) {
|
|
|
|
set_bkg_tile_xy(boardX + x, boardY - 1, ARROWDOWN);
|
|
|
|
set_bkg_tile_xy(boardX + x, boardY + boardHeight, ARROWUP);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let y = 0; y != boardHeight; y++) {
|
|
|
|
set_bkg_tile_xy(boardX - 1, boardY + y, ARROWRIGHT);
|
|
|
|
set_bkg_tile_xy(boardX + boardWidth, boardY + y, ARROWLEFT);
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-13 10:57:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//only draw right and bottom arrows
|
2023-09-14 19:16:49 +00:00
|
|
|
if (partial == 2) {
|
2023-09-13 10:57:28 +00:00
|
|
|
//Draw arrows for vertical / horizontal movement
|
|
|
|
if (gameMode != GMROTATE) {
|
|
|
|
for (let x = 0; x != boardWidth; x++) {
|
|
|
|
set_bkg_tile_xy(boardX + x, boardY + boardHeight, ARROWUP);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let y = 0; y != boardHeight; y++) {
|
|
|
|
set_bkg_tile_xy(boardX + boardWidth, boardY + y, ARROWLEFT);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
let i16 = 0;
|
|
|
|
for (let yy = 0; yy < boardHeight; yy++) {
|
|
|
|
for (let xx = 0; xx < boardWidth; xx++) {
|
2023-09-09 22:32:12 +00:00
|
|
|
set_bkg_tile_xy(boardX + xx, boardY + yy, level[i16 + xx]);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
i16 += boardWidth;
|
|
|
|
}
|
2023-09-13 10:57:28 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function initLevelSelect() {
|
|
|
|
setBlockTilesAsBackground();
|
|
|
|
needRedraw = 1;
|
2023-09-13 10:57:28 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function levelSelect() {
|
|
|
|
if (gameState == GSINITLEVELSELECT) {
|
|
|
|
initLevelSelect();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
let tmpUnlocked = levelUnlocked(gameMode, difficulty, selectedLevel - 1);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btnb) {
|
|
|
|
playMenuBackSound();
|
|
|
|
gameState = GSINITTITLE;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna) {
|
|
|
|
if (tmpUnlocked) {
|
|
|
|
gameState = GSINITGAME;
|
|
|
|
playMenuAcknowlege();
|
|
|
|
} else {
|
|
|
|
playErrorSound();
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dragleft) {
|
|
|
|
if (difficulty == DIFFRANDOM) {
|
|
|
|
playMenuSelectSound();
|
|
|
|
randomSeedGame = Date.now();
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
needRedraw = 1;
|
2023-09-13 10:57:28 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
if (selectedLevel > 1) {
|
|
|
|
playMenuSelectSound();
|
|
|
|
selectedLevel--;
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
needRedraw = 1;
|
2023-09-13 10:57:28 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
if (dragright) {
|
|
|
|
if (difficulty == DIFFRANDOM) {
|
|
|
|
playMenuSelectSound();
|
|
|
|
//need new seed based on time
|
|
|
|
randomSeedGame = Date.now();
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
needRedraw = 1;
|
2023-09-13 10:57:28 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
if (selectedLevel < maxLevel) {
|
|
|
|
playMenuSelectSound();
|
|
|
|
selectedLevel++;
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
needRedraw = 1;
|
2023-09-13 10:57:28 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (needRedraw) {
|
2023-09-13 10:57:28 +00:00
|
|
|
drawLevelSelect(redrawPartial);
|
2023-09-09 22:32:12 +00:00
|
|
|
needRedraw = 0;
|
|
|
|
requiresFlip = 1;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// printing functions
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-09 22:32:12 +00:00
|
|
|
function setCharAt(str, index, chr) {
|
2023-09-15 02:18:40 +00:00
|
|
|
"RAM";
|
2023-09-09 22:32:12 +00:00
|
|
|
if (index > str.length - 1) return str;
|
|
|
|
return str.substring(0, index) + chr + str.substring(index + 1);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function formatInteger(valinteger) {
|
2023-09-15 02:18:40 +00:00
|
|
|
"RAM";
|
2023-09-09 22:32:12 +00:00
|
|
|
const maxDigits = 10;
|
2023-09-13 10:57:28 +00:00
|
|
|
let array = " ";
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
const maxCharacters = (maxDigits);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
const lastIndex = (maxCharacters - 1);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (valinteger == 0) {
|
|
|
|
array = setCharAt(array, lastIndex, '0');
|
|
|
|
return {
|
|
|
|
digits: 1,
|
|
|
|
string: array
|
|
|
|
};
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
let digits = 0;
|
|
|
|
let integer = valinteger;
|
2023-09-09 22:32:12 +00:00
|
|
|
do {
|
2023-09-13 10:57:28 +00:00
|
|
|
let digit = integer % 10;
|
2023-09-09 22:32:12 +00:00
|
|
|
integer = Math.floor(integer / 10);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
array = setCharAt(array, lastIndex - digits, digit.toString());
|
|
|
|
++digits;
|
|
|
|
}
|
|
|
|
while (integer > 0);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
return {
|
|
|
|
digits: digits,
|
|
|
|
string: array
|
|
|
|
};
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//print a number on levelselect or game screen
|
2023-09-09 22:32:12 +00:00
|
|
|
function printNumber(ax, ay, aNumber, maxDigits) {
|
2023-09-15 02:18:40 +00:00
|
|
|
"RAM";
|
2023-09-09 22:32:12 +00:00
|
|
|
const buffSize = 10;
|
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
let ret = formatInteger(aNumber);
|
|
|
|
let maxFor = ret.digits;
|
2023-09-09 22:32:12 +00:00
|
|
|
if (ret.digits > maxDigits)
|
|
|
|
maxFor = maxDigits;
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let c = 0; c < maxFor; c++) {
|
2023-09-09 22:32:12 +00:00
|
|
|
if (ret.string.charAt(buffSize - ret.digits + c) == '')
|
|
|
|
return;
|
|
|
|
set_bkg_tile_xy(ax + (maxDigits - ret.digits) + c, ay, ret.string.charCodeAt(buffSize - ret.digits + c) + 32);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//print a message on the title screen on ax,ay, the tileset from titlescreen contains an alphabet
|
2023-09-09 22:32:12 +00:00
|
|
|
function printMessage(ax, ay, amsg) {
|
2023-09-15 02:18:40 +00:00
|
|
|
"RAM";
|
2023-09-13 10:57:28 +00:00
|
|
|
let aCode = 'A'.charCodeAt(0);
|
|
|
|
let zCode = 'Z'.charCodeAt(0);
|
|
|
|
let zeroCode = '0'.charCodeAt(0);
|
|
|
|
let nineCode = '9'.charCodeAt(0);
|
2023-09-14 19:16:49 +00:00
|
|
|
for (let p = 0; p < amsg.length; p++) {
|
|
|
|
let fCharCode = amsg.charCodeAt(p);
|
2023-09-13 10:57:28 +00:00
|
|
|
let tile = 61;
|
2023-09-11 20:57:39 +00:00
|
|
|
switch (fCharCode) {
|
2023-09-13 10:57:28 +00:00
|
|
|
case -1:
|
2023-09-11 20:57:39 +00:00
|
|
|
case 0:
|
2023-09-09 22:32:12 +00:00
|
|
|
return;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
// '['
|
|
|
|
case 91:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 70;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//']'
|
|
|
|
case 93:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 64;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'<'
|
|
|
|
case 60:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 73;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'>'
|
|
|
|
case 62:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 67;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'+'
|
|
|
|
case 43:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 63;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'*'
|
|
|
|
case 42:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 62;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'|'
|
|
|
|
case 124:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 69;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'#'
|
|
|
|
case 35:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 65;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//':'
|
|
|
|
case 58:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 116;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'a'
|
|
|
|
case 97:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 119;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//'b'
|
|
|
|
case 98:
|
2023-09-09 22:32:12 +00:00
|
|
|
tile = 117;
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
default:
|
2023-09-11 20:57:39 +00:00
|
|
|
if ((fCharCode >= aCode) && (fCharCode <= zCode)) {
|
|
|
|
tile = fCharCode + 25;
|
|
|
|
} else {
|
|
|
|
if ((fCharCode >= zeroCode) && (fCharCode <= nineCode))
|
|
|
|
tile = fCharCode + 32;
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-14 19:16:49 +00:00
|
|
|
set_bkg_tile_xy(ax + p, ay, tile);
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//print a message on the CongratsScreen on ax,ay, the tileset from Congrats Screen contains an alphabet in another font
|
2023-09-09 22:32:12 +00:00
|
|
|
function printCongratsScreen(ax, ay, amsg) {
|
2023-09-14 19:16:49 +00:00
|
|
|
// based on input from @Pharap
|
2023-09-13 10:57:28 +00:00
|
|
|
let aCode = 'A'.charCodeAt(0);
|
|
|
|
let zCode = 'Z'.charCodeAt(0);
|
2023-09-14 19:16:49 +00:00
|
|
|
for (let p = 0; p < amsg.length; p++) {
|
|
|
|
let fCharCode = amsg.charCodeAt(p);
|
2023-09-13 10:57:28 +00:00
|
|
|
let tile = 26;
|
|
|
|
if ((fCharCode == 0) || (fCharCode == -1))
|
2023-09-11 20:57:39 +00:00
|
|
|
return;
|
|
|
|
if ((fCharCode >= aCode) && (fCharCode <= zCode))
|
|
|
|
tile = fCharCode - aCode;
|
2023-09-14 19:16:49 +00:00
|
|
|
set_bkg_tile_xy(ax + p, ay, tile);
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// save state
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-09 22:32:12 +00:00
|
|
|
function validateSaveState() {
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let j = 0; j < GMCOUNT; j++) {
|
|
|
|
for (let i = 0; i < DIFFCOUNT; i++) {
|
2023-09-09 22:32:12 +00:00
|
|
|
if ((levelLocks[(j * DIFFCOUNT) + i] == 0) || (levelLocks[(j * DIFFCOUNT) + i] > LEVELCOUNT))
|
2023-09-08 12:34:26 +00:00
|
|
|
return 0;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-11 20:57:39 +00:00
|
|
|
if (options[OPSOUND] > 1)
|
|
|
|
return 0;
|
|
|
|
if (options[OPWIDGETS] > 1)
|
|
|
|
return 0;
|
|
|
|
if (options[OPINPUTRECTS] > 1)
|
2023-09-09 22:32:12 +00:00
|
|
|
return 0;
|
2023-09-13 23:58:46 +00:00
|
|
|
if (options[OPTHEMING] > 1)
|
|
|
|
return 0;
|
2023-09-08 12:34:26 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
return 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function initSaveState() {
|
2023-09-11 20:57:39 +00:00
|
|
|
//read from file
|
2023-09-13 10:57:28 +00:00
|
|
|
let file = require("Storage").open("waternet.data.dat", "r");
|
|
|
|
let index = 0;
|
2023-09-11 20:57:39 +00:00
|
|
|
for (index = 0; index < GMCOUNT * DIFFCOUNT; index++) {
|
|
|
|
tmp = file.readLine();
|
|
|
|
if (tmp !== undefined)
|
|
|
|
levelLocks[index] = Number(tmp);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
for (index = 0; index < OPCOUNT; index++) {
|
|
|
|
tmp = file.readLine();
|
|
|
|
if (tmp !== undefined)
|
|
|
|
options[index] = Number(tmp);
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
//then
|
|
|
|
if (!validateSaveState()) {
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let j = 0; j < GMCOUNT; j++)
|
|
|
|
for (let i = 0; i < DIFFCOUNT; i++)
|
2023-09-09 22:32:12 +00:00
|
|
|
levelLocks[(j * DIFFCOUNT) + i] = 1; //1st level unlocked
|
2023-09-11 20:57:39 +00:00
|
|
|
options[OPSOUND] = 1;
|
2023-09-13 23:58:46 +00:00
|
|
|
options[OPWIDGETS] = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
options[OPINPUTRECTS] = 0;
|
2023-09-13 23:58:46 +00:00
|
|
|
options[OPTHEMING] = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function saveSaveState() {
|
|
|
|
//save to file
|
2023-09-13 10:57:28 +00:00
|
|
|
let file = require("Storage").open("waternet.data.dat", "w");
|
|
|
|
let index;
|
2023-09-11 20:57:39 +00:00
|
|
|
for (index = 0; index < GMCOUNT * DIFFCOUNT; index++)
|
2023-09-09 22:32:12 +00:00
|
|
|
file.write(levelLocks[index].toString() + "\n");
|
2023-09-11 20:57:39 +00:00
|
|
|
for (index = 0; index < OPCOUNT; index++)
|
|
|
|
file.write(options[index].toString() + "\n");
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function setSoundOnSaveState(value) {
|
2023-09-11 20:57:39 +00:00
|
|
|
options[OPSOUND] = value;
|
2023-09-09 22:32:12 +00:00
|
|
|
saveSaveState();
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function isSoundOnSaveState() {
|
2023-09-11 20:57:39 +00:00
|
|
|
return options[OPSOUND] == 1;
|
|
|
|
}
|
|
|
|
|
2023-09-13 23:58:46 +00:00
|
|
|
function setThemingOnSaveState(value) {
|
|
|
|
options[OPTHEMING] = value;
|
|
|
|
saveSaveState();
|
|
|
|
}
|
|
|
|
|
|
|
|
function isThemingOnSaveState() {
|
|
|
|
return options[OPTHEMING] == 1;
|
|
|
|
}
|
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
function setWidgetsOnSaveState(value) {
|
|
|
|
options[OPWIDGETS] = value;
|
|
|
|
saveSaveState();
|
|
|
|
}
|
|
|
|
|
|
|
|
function isWidgetsOnSaveState() {
|
|
|
|
return options[OPWIDGETS] == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
function setInputRectsOnSaveState(value) {
|
|
|
|
options[OPINPUTRECTS] = value;
|
|
|
|
saveSaveState();
|
|
|
|
}
|
|
|
|
|
|
|
|
function isInputRectsOnSaveState() {
|
|
|
|
return options[OPINPUTRECTS] == 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function levelUnlocked(mode, diff, level) {
|
|
|
|
return levelLocks[(mode * DIFFCOUNT) + diff] > level;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function lastUnlockedLevel(mode, diff) {
|
|
|
|
return levelLocks[(mode * DIFFCOUNT) + diff];
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function unlockLevel(mode, diff, level) {
|
|
|
|
if (level + 1 > lastUnlockedLevel(mode, diff)) {
|
|
|
|
levelLocks[(mode * DIFFCOUNT) + diff] = level + 1;
|
|
|
|
saveSaveState();
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// titlescreen
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-11 20:57:39 +00:00
|
|
|
function drawMenuSelector(tile) {
|
2023-09-09 22:32:12 +00:00
|
|
|
//set menu tile
|
|
|
|
switch (titleStep) {
|
|
|
|
case TSMAINMENU:
|
2023-09-11 20:57:39 +00:00
|
|
|
set_bkg_tile_xy(4, 4 + mainMenu, tile);
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
|
|
|
case TSGAMEMODE:
|
2023-09-11 20:57:39 +00:00
|
|
|
set_bkg_tile_xy(4, 4 + gameMode, tile);
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
|
|
|
case TSDIFFICULTY:
|
2023-09-11 20:57:39 +00:00
|
|
|
set_bkg_tile_xy(2, 3 + difficulty, tile);
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
|
|
|
case TSOPTIONS:
|
2023-09-11 20:57:39 +00:00
|
|
|
set_bkg_tile_xy(1, 4 + option, tile);
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
function drawMenuItems(clear) {
|
|
|
|
if (clear) {
|
2023-09-13 23:58:46 +00:00
|
|
|
g.setColor(g.getBgColor());
|
2023-09-11 20:57:39 +00:00
|
|
|
switch (titleStep) {
|
|
|
|
case TSMAINMENU:
|
|
|
|
g.fillRect(SCREENOFFSETX + 5 * TILESIZE, screenOffsetY + 4 * TILESIZE, SCREENOFFSETX + 13 * TILESIZE, screenOffsetY + 8 * TILESIZE);
|
|
|
|
break;
|
|
|
|
case TSDIFFICULTY:
|
|
|
|
g.fillRect(SCREENOFFSETX + 3 * TILESIZE, screenOffsetY + 3 * TILESIZE, SCREENOFFSETX + 12 * TILESIZE, screenOffsetY + 9 * TILESIZE);
|
|
|
|
break;
|
|
|
|
case TSGAMEMODE:
|
|
|
|
g.fillRect(SCREENOFFSETX + 5 * TILESIZE, screenOffsetY + 4 * TILESIZE, SCREENOFFSETX + 12 * TILESIZE, screenOffsetY + 7 * TILESIZE);
|
|
|
|
break;
|
|
|
|
case TSCREDITS:
|
|
|
|
g.fillRect(SCREENOFFSETX + 2 * TILESIZE, screenOffsetY + 5 * TILESIZE, SCREENOFFSETX + 15 * TILESIZE, screenOffsetY + 8 * TILESIZE);
|
|
|
|
break;
|
|
|
|
case TSOPTIONS:
|
|
|
|
g.fillRect(SCREENOFFSETX + 3 * TILESIZE, screenOffsetY + 4 * TILESIZE, SCREENOFFSETX + 11 * TILESIZE, screenOffsetY + 5 * TILESIZE);
|
2023-09-13 23:58:46 +00:00
|
|
|
g.fillRect(SCREENOFFSETX + 1 * TILESIZE, screenOffsetY + 5 * TILESIZE, SCREENOFFSETX + 16 * TILESIZE, screenOffsetY + 11 * TILESIZE);
|
2023-09-11 20:57:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (titleStep) {
|
|
|
|
case TSMAINMENU:
|
|
|
|
printMessage(5, 4, "START");
|
|
|
|
printMessage(5, 5, "HELP");
|
|
|
|
printMessage(5, 6, "OPTIONS");
|
|
|
|
printMessage(5, 7, "CREDITS");
|
|
|
|
break;
|
|
|
|
case TSDIFFICULTY:
|
|
|
|
printMessage(3, 3, "VERY EASY");
|
|
|
|
printMessage(3, 4, "EASY");
|
|
|
|
printMessage(3, 5, "NORMAL");
|
|
|
|
printMessage(3, 6, "HARD");
|
|
|
|
printMessage(3, 7, "VERY HARD");
|
|
|
|
printMessage(3, 8, "RANDOM");
|
|
|
|
break;
|
|
|
|
case TSGAMEMODE:
|
|
|
|
printMessage(5, 4, "ROTATE");
|
|
|
|
printMessage(5, 5, "SLIDE");
|
|
|
|
printMessage(5, 6, "ROSLID");
|
|
|
|
break;
|
|
|
|
case TSCREDITS:
|
|
|
|
printMessage(3, 5, "CREATED BY");
|
|
|
|
printMessage(2, 6, "WILLEMS DAVY");
|
|
|
|
printMessage(2, 7, "JOYRIDER3774");
|
|
|
|
break;
|
|
|
|
case TSOPTIONS:
|
|
|
|
if (isSoundOn())
|
|
|
|
printMessage(3, 4, "BUZZ ON");
|
|
|
|
else
|
|
|
|
printMessage(3, 4, "BUZZ OFF");
|
|
|
|
if (isInputRectsOnSaveState())
|
|
|
|
printMessage(3, 5, "INPUTRECT ON");
|
|
|
|
else
|
|
|
|
printMessage(3, 5, "INPUTRECT OFF");
|
2023-09-13 23:58:46 +00:00
|
|
|
if (isThemingOnSaveState()) {
|
|
|
|
printMessage(3, 6, "THEMING ON");
|
|
|
|
} else {
|
|
|
|
printMessage(3, 6, "THEMING OFF");
|
|
|
|
}
|
2023-09-11 20:57:39 +00:00
|
|
|
if (isWidgetsOnSaveState()) {
|
2023-09-13 23:58:46 +00:00
|
|
|
printMessage(3, 7, "WIDGETS ON");
|
2023-09-14 19:16:49 +00:00
|
|
|
} else {
|
2023-09-13 23:58:46 +00:00
|
|
|
printMessage(3, 7, "WIDGETS OFF");
|
2023-09-14 19:16:49 +00:00
|
|
|
}
|
2023-09-13 23:58:46 +00:00
|
|
|
printMessage(1, 9, "RESTART NEEDED");
|
|
|
|
printMessage(2, 10, "FOR WIDGETS");
|
2023-09-11 20:57:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawTitleScreen(partial) {
|
|
|
|
if (partial > 2) {
|
|
|
|
g.clearRect(Bangle.appRect);
|
|
|
|
g.drawImage(TITLE, SCREENOFFSETX, screenOffsetY);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (partial > 1)
|
|
|
|
drawMenuItems(false);
|
|
|
|
|
|
|
|
drawMenuSelector(LEFTMENU);
|
|
|
|
redrawPartial = 3;
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function initTitleScreen() {
|
|
|
|
setBlockTilesAsBackground();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function titleScreen() {
|
|
|
|
if (gameState == GSINITTITLE) {
|
|
|
|
initTitleScreen();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (dragup) {
|
|
|
|
switch (titleStep) {
|
|
|
|
case TSMAINMENU:
|
|
|
|
if (mainMenu > MMSTARTGAME) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
mainMenu--;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TSGAMEMODE:
|
|
|
|
if (gameMode > GMROTATE) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
gameMode--;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TSDIFFICULTY:
|
|
|
|
if (difficulty > DIFFVERYEASY) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
difficulty--;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TSOPTIONS:
|
|
|
|
if (option > OPSOUND) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
option--;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (dragdown) {
|
|
|
|
switch (titleStep) {
|
|
|
|
case TSMAINMENU:
|
|
|
|
if (mainMenu < MMCOUNT - 1) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
mainMenu++;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
|
|
|
case TSGAMEMODE:
|
|
|
|
if (gameMode < GMCOUNT - 1) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
gameMode++;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TSDIFFICULTY:
|
|
|
|
if (difficulty < DIFFCOUNT - 1) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
difficulty++;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TSOPTIONS:
|
|
|
|
if (option < OPCOUNT - 1) {
|
|
|
|
playMenuSelectSound();
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
2023-09-09 22:32:12 +00:00
|
|
|
option++;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 1;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btnb) {
|
|
|
|
switch (titleStep) {
|
|
|
|
case TSOPTIONS:
|
|
|
|
case TSCREDITS:
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
titleStep = TSMAINMENU;
|
|
|
|
playMenuBackSound();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
|
|
|
case TSGAMEMODE:
|
|
|
|
case TSDIFFICULTY:
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
titleStep--;
|
|
|
|
playMenuBackSound();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna) {
|
|
|
|
playMenuAcknowlege();
|
|
|
|
switch (mainMenu) {
|
|
|
|
case MMOPTIONS:
|
|
|
|
if (titleStep != TSOPTIONS) {
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
titleStep = TSOPTIONS;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
switch (option) {
|
|
|
|
case OPSOUND:
|
|
|
|
setSoundOn(!isSoundOn());
|
|
|
|
setSoundOnSaveState(isSoundOn());
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
|
|
|
break;
|
|
|
|
case OPWIDGETS:
|
|
|
|
setWidgetsOnSaveState(!isWidgetsOnSaveState());
|
|
|
|
needRedraw = 1;
|
|
|
|
//needs 3 because text crosses input rect lines
|
|
|
|
redrawPartial = 3;
|
|
|
|
break;
|
|
|
|
case OPINPUTRECTS:
|
|
|
|
setInputRectsOnSaveState(!isInputRectsOnSaveState());
|
|
|
|
needRedraw = 1;
|
|
|
|
//needs 3 because text crosses input rect lines
|
|
|
|
redrawPartial = 3;
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
2023-09-13 23:58:46 +00:00
|
|
|
case OPTHEMING:
|
|
|
|
setThemingOnSaveState(!isThemingOnSaveState());
|
|
|
|
setThemingOn(isThemingOnSaveState());
|
|
|
|
//needs a clear to set background color
|
2023-09-14 19:16:49 +00:00
|
|
|
if (isThemingOnSaveState()) {
|
2023-09-13 23:58:46 +00:00
|
|
|
g.setBgColor(g.theme.bg);
|
|
|
|
} else {
|
|
|
|
g.setBgColor(0x0000);
|
|
|
|
}
|
|
|
|
g.clearRect(g.appRect);
|
|
|
|
//probably need to call this again as i think
|
|
|
|
//a copy is kept in currenttiles but i'm not sure of that
|
|
|
|
//but it's a small call so should be fine
|
|
|
|
setBlockTilesAsBackground();
|
|
|
|
needRedraw = 1;
|
|
|
|
//needs 3 because we need to redraw everything
|
|
|
|
redrawPartial = 3;
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MMCREDITS:
|
|
|
|
if (titleStep != TSCREDITS) {
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
titleStep = TSCREDITS;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
titleStep = TSMAINMENU;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MMHELP:
|
|
|
|
if (titleStep < TSGAMEMODE) {
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
titleStep++;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
switch (gameMode) {
|
|
|
|
case GMROTATE:
|
|
|
|
gameState = GSINITHELPROTATE;
|
|
|
|
break;
|
|
|
|
case GMSLIDE:
|
|
|
|
gameState = GSINITHELPSLIDE;
|
|
|
|
break;
|
|
|
|
case GMROTATESLIDE:
|
|
|
|
gameState = GSINITHELPROTATESLIDE;
|
|
|
|
break;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MMSTARTGAME:
|
|
|
|
if (titleStep < TSDIFFICULTY) {
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear
|
|
|
|
drawMenuSelector(EMPTY);
|
|
|
|
drawMenuItems(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
titleStep++;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
if (difficulty == DIFFRANDOM)
|
|
|
|
selectedLevel = 1;
|
|
|
|
else
|
|
|
|
selectedLevel = lastUnlockedLevel(gameMode, difficulty);
|
|
|
|
|
|
|
|
if (gameMode == GMROTATE)
|
|
|
|
posAdd = 0;
|
|
|
|
else
|
|
|
|
posAdd = 1;
|
|
|
|
//set randomseet to systime here
|
|
|
|
//it will be reused all the time
|
|
|
|
//with the level generating
|
|
|
|
//but not when going back from
|
|
|
|
//level playing to level selector
|
|
|
|
//when calling init level there
|
|
|
|
randomSeedGame = Date.now();
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
|
|
|
|
gameState = GSINITLEVELSELECT;
|
|
|
|
}
|
|
|
|
break;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (needRedraw) {
|
2023-09-11 20:57:39 +00:00
|
|
|
drawTitleScreen(redrawPartial);
|
2023-09-09 22:32:12 +00:00
|
|
|
needRedraw = 0;
|
|
|
|
requiresFlip = 1;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// game
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-11 20:57:39 +00:00
|
|
|
function drawGame(partial) {
|
2023-09-09 22:32:12 +00:00
|
|
|
//background
|
|
|
|
if (!paused && !redrawLevelDoneBit) {
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 2)
|
|
|
|
g.clearRect(Bangle.appRect);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//LEVEL:
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 2) {
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 0, "LEVEL:");
|
2023-09-11 20:57:39 +00:00
|
|
|
//[LEVEL NR] 2 chars
|
2023-09-14 19:16:49 +00:00
|
|
|
printNumber(MAXBOARDWIDTH + 4, 1, selectedLevel, 2);
|
2023-09-11 20:57:39 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//MOVES:
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 2)
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 2, "MOVES:");
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 1)
|
2023-09-14 19:16:49 +00:00
|
|
|
printNumber(MAXBOARDWIDTH + 1, 3, moves, 5);
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//A:XXXXXX (XXXXXX="ROTATE" or XXXXXX="SLIDE " or XXXXXX="ROSLID")
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 2) {
|
|
|
|
switch (gameMode) {
|
|
|
|
case GMROTATE:
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 4, "TOUCH:");
|
|
|
|
printMessage(MAXBOARDWIDTH, 5, "ROTATE");
|
2023-09-11 20:57:39 +00:00
|
|
|
break;
|
|
|
|
case GMSLIDE:
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 4, "TOUCH:");
|
|
|
|
printMessage(MAXBOARDWIDTH, 5, "SLIDE");
|
2023-09-11 20:57:39 +00:00
|
|
|
break;
|
|
|
|
case GMROTATESLIDE:
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 4, "TOUCH:");
|
|
|
|
printMessage(MAXBOARDWIDTH, 5, "ROSLID");
|
2023-09-11 20:57:39 +00:00
|
|
|
break;
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 2) {
|
|
|
|
//B:BACK
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(MAXBOARDWIDTH, 6, "BTN:");
|
|
|
|
printMessage(MAXBOARDWIDTH, 7, "BACK");
|
2023-09-11 20:57:39 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 2) {
|
|
|
|
//Draw arrows for vertical / horizontal movement
|
|
|
|
if (gameMode != GMROTATE) {
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let x = 0; x != boardWidth; x++) {
|
2023-09-11 20:57:39 +00:00
|
|
|
set_bkg_tile_xy(boardX + x, boardY - 1, ARROWDOWN);
|
|
|
|
set_bkg_tile_xy(boardX + x, boardY + boardHeight, ARROWUP);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let y = 0; y != boardHeight; y++) {
|
2023-09-11 20:57:39 +00:00
|
|
|
set_bkg_tile_xy(boardX - 1, boardY + y, ARROWRIGHT);
|
|
|
|
set_bkg_tile_xy(boardX + boardWidth, boardY + y, ARROWLEFT);
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//complete level
|
2023-09-13 10:57:28 +00:00
|
|
|
let i16 = 0;
|
|
|
|
let yy;
|
|
|
|
let xx;
|
2023-09-11 20:57:39 +00:00
|
|
|
if (partial > 1) {
|
|
|
|
for (yy = 0; yy < boardHeight; yy++) {
|
|
|
|
for (xx = 0; xx < boardWidth; xx++) {
|
|
|
|
set_bkg_tile_xy(boardX + xx, boardY + yy, level[i16 + xx]);
|
|
|
|
}
|
|
|
|
i16 += boardWidth;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-13 10:57:28 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function initGame() {
|
|
|
|
paused = 0;
|
|
|
|
//set background tiles
|
|
|
|
setBlockTilesAsBackground();
|
|
|
|
//set sprite for selector / cursor
|
|
|
|
initCursors();
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
|
|
|
showCursors();
|
|
|
|
redrawLevelDoneBit = 0;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function doPause() {
|
|
|
|
paused = 1;
|
|
|
|
wasSoundOn = isSoundOn();
|
|
|
|
setSoundOn(0);
|
|
|
|
hideCursors();
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(0, (MAXBOARDHEIGHT >> 1) - 3, "[**************]");
|
|
|
|
printMessage(0, (MAXBOARDHEIGHT >> 1) - 2, "|PLEASE CONFIRM+");
|
|
|
|
printMessage(0, (MAXBOARDHEIGHT >> 1) - 1, "| +");
|
|
|
|
printMessage(0, (MAXBOARDHEIGHT >> 1) + 0, "| TOUCH PLAY +");
|
|
|
|
printMessage(0, (MAXBOARDHEIGHT >> 1) + 1, "| BTN TO QUIT +");
|
|
|
|
printMessage(0, (MAXBOARDHEIGHT >> 1) + 2, "<##############>");
|
2023-09-09 22:32:12 +00:00
|
|
|
requiresFlip = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
function doUnPause() {
|
|
|
|
paused = 0;
|
|
|
|
setSoundOn(wasSoundOn);
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
|
|
|
showCursors();
|
|
|
|
}
|
|
|
|
|
|
|
|
function game() {
|
|
|
|
if (gameState == GSINITGAME) {
|
|
|
|
initGame();
|
|
|
|
gameState -= GSINITDIFF;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (dragdown) {
|
|
|
|
if (!levelDone && !paused) {
|
|
|
|
playGameMoveSound();
|
|
|
|
//if not touching border on bottom
|
|
|
|
if (selectionY + 1 < boardHeight + posAdd) {
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
selectionY += 1;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 0;
|
2023-09-14 19:16:49 +00:00
|
|
|
} else {
|
|
|
|
//set to border on top
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
2023-09-09 22:32:12 +00:00
|
|
|
selectionY = -posAdd;
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 0;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-11 20:57:39 +00:00
|
|
|
} else {
|
|
|
|
if (dragup) {
|
|
|
|
if (!levelDone && !paused) {
|
|
|
|
//if not touching border on top
|
|
|
|
playGameMoveSound();
|
|
|
|
if (selectionY - 1 >= -posAdd) {
|
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
|
|
|
selectionY -= 1;
|
|
|
|
needRedraw = 1;
|
|
|
|
redrawPartial = 0;
|
2023-09-14 19:16:49 +00:00
|
|
|
} else {
|
|
|
|
//set to border on bottom
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
|
|
|
selectionY = boardHeight - 1 + posAdd;
|
|
|
|
needRedraw = 1;
|
|
|
|
redrawPartial = 0;
|
|
|
|
}
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-11 20:57:39 +00:00
|
|
|
} else {
|
|
|
|
if (dragright) {
|
|
|
|
if (!levelDone && !paused) {
|
|
|
|
playGameMoveSound();
|
|
|
|
//if not touching border on right
|
|
|
|
if (selectionX + 1 < boardWidth + posAdd) {
|
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
|
|
|
selectionX += 1;
|
|
|
|
needRedraw = 1;
|
|
|
|
redrawPartial = 0;
|
2023-09-14 19:16:49 +00:00
|
|
|
} else {
|
|
|
|
//set to border on left
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
|
|
|
selectionX = -posAdd;
|
|
|
|
needRedraw = 1;
|
|
|
|
redrawPartial = 0;
|
|
|
|
}
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (dragleft) {
|
|
|
|
if (!levelDone && !paused) {
|
|
|
|
playGameMoveSound();
|
|
|
|
//if not touching border on left
|
|
|
|
if (selectionX - 1 >= -posAdd) {
|
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
|
|
|
selectionX -= 1;
|
|
|
|
needRedraw = 1;
|
|
|
|
redrawPartial = 0;
|
2023-09-14 19:16:49 +00:00
|
|
|
} else { //set to border on right
|
2023-09-11 20:57:39 +00:00
|
|
|
//clear cursor
|
|
|
|
drawCursors(true);
|
|
|
|
selectionX = boardWidth - 1 + posAdd;
|
|
|
|
needRedraw = 1;
|
|
|
|
redrawPartial = 0;
|
|
|
|
}
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
|
|
|
}
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btna) {
|
|
|
|
if (paused) {
|
|
|
|
doUnPause();
|
|
|
|
playMenuAcknowlege();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
if (!levelDone) {
|
|
|
|
if ((selectionX > -1) && (selectionX < boardWidth) &&
|
|
|
|
(selectionY > -1) && (selectionY < boardHeight)) {
|
|
|
|
if (gameMode != GMSLIDE) {
|
|
|
|
rotateBlock(selectionX + (selectionY * boardWidth));
|
|
|
|
moves++;
|
|
|
|
playGameAction();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
playErrorSound();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((selectionX > -1) && (selectionX < boardWidth)) {
|
|
|
|
if (selectionY == -1) {
|
|
|
|
moveBlockDown(selectionX + ((selectionY + 1) * boardWidth));
|
|
|
|
moves++;
|
|
|
|
playGameAction();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
if (selectionY == boardHeight) {
|
|
|
|
moveBlockUp(selectionX + ((selectionY - 1) * boardWidth));
|
|
|
|
moves++;
|
|
|
|
playGameAction();
|
2023-09-07 02:46:57 +00:00
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
if ((selectionY > -1) && (selectionY < boardHeight)) {
|
|
|
|
if (selectionX == -1) {
|
|
|
|
moveBlockRight((selectionX + 1) + (selectionY * boardWidth));
|
|
|
|
moves++;
|
|
|
|
playGameAction();
|
2023-09-07 02:46:57 +00:00
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
if (selectionX == boardWidth) {
|
|
|
|
moveBlockLeft((selectionX - 1) + (selectionY * boardWidth));
|
|
|
|
moves++;
|
|
|
|
playGameAction();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 2;
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
playErrorSound();
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
updateConnected();
|
|
|
|
levelDone = isLevelDone();
|
|
|
|
if (levelDone) {
|
|
|
|
//update level one last time so we are at final state
|
|
|
|
//as it won't be updated anymore as long as level done is displayed
|
2023-09-13 10:57:28 +00:00
|
|
|
//2 forces level to be drawn (only) one last time the other call uses levelDone
|
|
|
|
drawGame(2);
|
2023-09-09 22:32:12 +00:00
|
|
|
//hide cursor it's only sprite we use
|
|
|
|
hideCursors();
|
2023-09-14 19:16:49 +00:00
|
|
|
printMessage(((16 - 13) >> 1), (MAXBOARDHEIGHT >> 1) - 2, "[************]");
|
|
|
|
printMessage(((16 - 13) >> 1), (MAXBOARDHEIGHT >> 1) - 1, "| LEVEL DONE +");
|
|
|
|
printMessage(((16 - 13) >> 1), (MAXBOARDHEIGHT >> 1) - 0, "| TOUCH TO +");
|
|
|
|
printMessage(((16 - 13) >> 1), (MAXBOARDHEIGHT >> 1) + 1, "| CONTINUE +");
|
|
|
|
printMessage(((16 - 13) >> 1), (MAXBOARDHEIGHT >> 1) + 2, "<############>");
|
2023-09-09 22:32:12 +00:00
|
|
|
redrawLevelDoneBit = 1;
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
redrawLevelDoneBit = 0;
|
|
|
|
//goto next level
|
|
|
|
if (difficulty == DIFFRANDOM) {
|
|
|
|
//ned new seed based on time
|
|
|
|
randomSeedGame = Date.now();
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
//show cursor again (it's actually to early but i'm not fixing that)
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
|
|
|
showCursors();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-09 22:32:12 +00:00
|
|
|
} else {
|
|
|
|
//goto next level if any
|
|
|
|
if (selectedLevel < maxLevel) {
|
|
|
|
selectedLevel++;
|
|
|
|
unlockLevel(gameMode, difficulty, selectedLevel - 1);
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
//show cursor again (it's actually to early but i'm not fixing that)
|
|
|
|
setCursorPos(0, boardX + selectionX, boardY + selectionY);
|
|
|
|
showCursors();
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 3;
|
2023-09-14 19:16:49 +00:00
|
|
|
} else {
|
2023-09-09 22:32:12 +00:00
|
|
|
gameState = GSINITLEVELSCLEARED;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (btnb) {
|
|
|
|
if (!levelDone) {
|
|
|
|
if (!paused) {
|
|
|
|
playMenuBackSound();
|
|
|
|
doPause();
|
|
|
|
needRedraw = 0;
|
|
|
|
} else {
|
|
|
|
//need to enable early again to play backsound
|
|
|
|
//normally unpause does it but we only unpause
|
|
|
|
//after fade
|
|
|
|
setSoundOn(wasSoundOn);
|
|
|
|
hideCursors();
|
|
|
|
playMenuBackSound();
|
|
|
|
gameState = GSINITLEVELSELECT;
|
|
|
|
doUnPause();
|
|
|
|
//unpause sets cursor visible !
|
|
|
|
hideCursors();
|
|
|
|
//need to reset the level to initial state when going back to level selector
|
|
|
|
//could not find a better way unfortunatly
|
|
|
|
//also we do not want to reset the randomseed used for random level generating
|
|
|
|
//or a new level would have been created when going back we only want the level
|
|
|
|
//with random to change when pressing left and right in the level selector
|
|
|
|
//this way it stays consistent with the normal levels
|
|
|
|
//and the player can replay the level if he wants to
|
|
|
|
initLevel(randomSeedGame);
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (needRedraw) {
|
2023-09-11 20:57:39 +00:00
|
|
|
drawGame(redrawPartial);
|
2023-09-09 22:32:12 +00:00
|
|
|
drawCursors();
|
|
|
|
needRedraw = 0;
|
|
|
|
requiresFlip = 1;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
|
|
|
// main game start
|
|
|
|
// --------------------------------------------------------------------------------------------------
|
2023-09-14 19:16:49 +00:00
|
|
|
function setThemingOn(value) {
|
2023-09-13 23:58:46 +00:00
|
|
|
//change color palette to theming options for the images
|
2023-09-14 19:16:49 +00:00
|
|
|
if (value && (g.theme.bg != g.theme.fg)) {
|
2023-09-13 23:58:46 +00:00
|
|
|
SELECTORTILES.palette[1] = g.theme.bg;
|
|
|
|
SELECTORTILES.palette[2] = g.theme.fg;
|
|
|
|
TITLE.palette[3] = g.theme.bg;
|
|
|
|
TITLE.palette[2] = g.theme.bg;
|
|
|
|
TITLE.palette[1] = g.theme.fg;
|
|
|
|
BLOCKTILES.palette[0] = g.theme.bg;
|
|
|
|
BLOCKTILES.palette[1] = g.theme.fg;
|
|
|
|
CONGRATSSCREEN.palette[0] = g.theme.bg;
|
|
|
|
CONGRATSSCREEN.palette[1] = g.theme.fg;
|
|
|
|
CONGRATSTILES.palette[0] = g.theme.bg;
|
|
|
|
CONGRATSTILES.palette[1] = g.theme.fg;
|
|
|
|
} else {
|
|
|
|
SELECTORTILES.palette[1] = 0x0000;
|
|
|
|
SELECTORTILES.palette[2] = 0xFFFF;
|
|
|
|
TITLE.palette[3] = 0x0000;
|
|
|
|
TITLE.palette[2] = 0x0000;
|
|
|
|
TITLE.palette[1] = 0xFFFF;
|
|
|
|
BLOCKTILES.palette[0] = 0x0000;
|
|
|
|
BLOCKTILES.palette[1] = 0xFFFF;
|
|
|
|
CONGRATSSCREEN.palette[0] = 0x0000;
|
|
|
|
CONGRATSSCREEN.palette[1] = 0xFFFF;
|
|
|
|
CONGRATSTILES.palette[0] = 0x0000;
|
|
|
|
CONGRATSTILES.palette[1] = 0xFFFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function setup() {
|
2023-09-11 20:57:39 +00:00
|
|
|
redrawPartial = 0;
|
2023-09-09 22:32:12 +00:00
|
|
|
option = 0;
|
|
|
|
difficulty = DIFFNORMAL;
|
|
|
|
selectedLevel = 1;
|
|
|
|
mainMenu = MMSTARTGAME;
|
|
|
|
gameState = GSINITINTRO;
|
|
|
|
titleStep = TSMAINMENU;
|
|
|
|
gameMode = GMROTATE;
|
2023-09-11 20:57:39 +00:00
|
|
|
posAdd = 0;
|
2023-09-09 22:32:12 +00:00
|
|
|
//has to be called first because initsound read savestate sound to set intial flags
|
|
|
|
initSaveState();
|
|
|
|
//initSound();
|
|
|
|
setSoundOn(isSoundOnSaveState());
|
2023-09-11 20:57:39 +00:00
|
|
|
if (isWidgetsOnSaveState()) {
|
|
|
|
//need to call this first otherwise
|
|
|
|
Bangle.loadWidgets();
|
|
|
|
//only once they update themselves
|
|
|
|
Bangle.drawWidgets();
|
|
|
|
}
|
2023-09-13 23:58:46 +00:00
|
|
|
setThemingOn(isThemingOnSaveState());
|
|
|
|
//has to be called after applying theming
|
|
|
|
setBlockTilesAsBackground();
|
2023-09-13 20:33:00 +00:00
|
|
|
//calculate screenoffset y position taking apprect into account
|
2023-09-11 20:57:39 +00:00
|
|
|
screenOffsetY = ((SCREENHEIGHT + Bangle.appRect.y - 8 * TILESIZE) >> 1);
|
2023-09-09 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function loop() {
|
|
|
|
//soundTimer();
|
2023-09-13 10:57:28 +00:00
|
|
|
let startTime = Date().getTime();
|
2023-09-09 22:32:12 +00:00
|
|
|
g.reset();
|
2023-09-14 19:16:49 +00:00
|
|
|
if (isThemingOnSaveState()) {
|
2023-09-13 23:58:46 +00:00
|
|
|
g.setColor(g.theme.fg);
|
|
|
|
g.setBgColor(g.theme.bg);
|
|
|
|
} else {
|
|
|
|
g.setColor(0xFFFF);
|
|
|
|
g.setBgColor(0x0000);
|
|
|
|
}
|
2023-09-09 22:32:12 +00:00
|
|
|
|
|
|
|
//gamestate handling
|
2023-09-13 10:57:28 +00:00
|
|
|
let prevGameState = gameState;
|
2023-09-09 22:32:12 +00:00
|
|
|
|
|
|
|
switch (gameState) {
|
|
|
|
case GSINITTITLE:
|
|
|
|
case GSTITLE:
|
|
|
|
clearInterval(intervalTimer);
|
|
|
|
titleScreen();
|
|
|
|
break;
|
|
|
|
case GSINITLEVELSELECT:
|
|
|
|
case GSLEVELSELECT:
|
|
|
|
levelSelect();
|
|
|
|
break;
|
|
|
|
case GSINITGAME:
|
|
|
|
case GSGAME:
|
|
|
|
game();
|
|
|
|
break;
|
|
|
|
case GSINITLEVELSCLEARED:
|
|
|
|
case GSLEVELSCLEARED:
|
|
|
|
levelsCleared();
|
|
|
|
break;
|
|
|
|
case GSINITHELPSLIDE:
|
|
|
|
case GSHELPSLIDE:
|
|
|
|
helpSlide();
|
|
|
|
break;
|
|
|
|
case GSINITHELPSLIDE2:
|
|
|
|
case GSHELPSLIDE2:
|
|
|
|
helpSlide2();
|
|
|
|
break;
|
|
|
|
case GSINITHELPSLIDE3:
|
|
|
|
case GSHELPSLIDE3:
|
|
|
|
helpSlide3();
|
|
|
|
break;
|
|
|
|
case GSHELPROTATESLIDE:
|
|
|
|
case GSINITHELPROTATESLIDE:
|
|
|
|
helpRotateSlide();
|
|
|
|
break;
|
|
|
|
case GSINITHELPROTATESLIDE2:
|
|
|
|
case GSHELPROTATESLIDE2:
|
|
|
|
helpRotateSlide2();
|
|
|
|
break;
|
|
|
|
case GSINITHELPROTATESLIDE3:
|
|
|
|
case GSHELPROTATESLIDE3:
|
|
|
|
helpRotateSlide3();
|
|
|
|
break;
|
|
|
|
case GSINITHELPROTATESLIDE4:
|
|
|
|
case GSHELPROTATESLIDE4:
|
|
|
|
helpRotateSlide4();
|
|
|
|
break;
|
|
|
|
case GSINITHELPROTATE:
|
|
|
|
case GSHELPROTATE:
|
|
|
|
helpRotate();
|
|
|
|
break;
|
|
|
|
case GSINITHELPROTATE2:
|
|
|
|
case GSHELPROTATE2:
|
|
|
|
helpRotate2();
|
|
|
|
break;
|
|
|
|
case GSINITHELPROTATE3:
|
|
|
|
case GSHELPROTATE3:
|
|
|
|
helpRotate3();
|
|
|
|
break;
|
|
|
|
case GSINITINTRO:
|
|
|
|
case GSINTRO:
|
|
|
|
intro();
|
|
|
|
break;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (requiresFlip) {
|
2023-09-11 20:57:39 +00:00
|
|
|
if (isInputRectsOnSaveState()) {
|
2023-09-09 22:32:12 +00:00
|
|
|
const offsetvalue = 0.20;
|
2023-09-13 10:57:28 +00:00
|
|
|
let x1 = SCREENWIDTH * offsetvalue;
|
|
|
|
let x2 = SCREENWIDTH - SCREENWIDTH * offsetvalue;
|
|
|
|
let y1 = Bangle.appRect.y + SCREENHEIGHT * offsetvalue;
|
|
|
|
let y2 = SCREENHEIGHT - SCREENHEIGHT * offsetvalue;
|
2023-09-09 22:32:12 +00:00
|
|
|
g.setColor(1, 0, 1);
|
|
|
|
//up
|
|
|
|
g.drawRect(0, Bangle.appRect.y, SCREENWIDTH - 1, y1);
|
|
|
|
//down
|
|
|
|
g.drawRect(0, y2, SCREENWIDTH - 1, SCREENHEIGHT - 1);
|
|
|
|
//left
|
|
|
|
g.drawRect(0, Bangle.appRect.y, x1, SCREENHEIGHT - 1);
|
|
|
|
//right
|
|
|
|
g.drawRect(x2, Bangle.appRect.y, SCREENWIDTH - 1, SCREENHEIGHT - 1);
|
|
|
|
}
|
|
|
|
g.flip();
|
|
|
|
requiresFlip = 0;
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
//when switching gamestate we need a redraw
|
|
|
|
if ((gameState != prevGameState) && (gameState >= GSINITDIFF))
|
|
|
|
needRedraw = 1;
|
2023-09-11 20:57:39 +00:00
|
|
|
if (DEBUGMODESPEED)
|
|
|
|
debugLog("loop done: " + (Date().getTime() - startTime).toString());
|
|
|
|
else
|
|
|
|
debugLog("loop done");
|
2023-09-07 02:46:57 +00:00
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
if (DEBUGMODERAMUSE) {
|
2023-09-13 10:57:28 +00:00
|
|
|
let memTmp = process.memory(false);
|
|
|
|
let used = memTmp.usage - memStart.usage;
|
2023-09-09 22:32:12 +00:00
|
|
|
debugLog("Udiff:" + used.toString() + " used:" + memTmp.usage.toString() + " free:" + memTmp.free.toString() + " total:" + memTmp.total.toString());
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function debugLog(val) {
|
|
|
|
if (DEBUGMODE)
|
2023-09-07 02:46:57 +00:00
|
|
|
print(val);
|
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function handleTouch(button, data) {
|
2023-09-07 02:46:57 +00:00
|
|
|
const offsetvalue = 0.20;
|
2023-09-13 10:57:28 +00:00
|
|
|
let x1 = SCREENWIDTH * offsetvalue;
|
|
|
|
let x2 = SCREENWIDTH - SCREENWIDTH * offsetvalue;
|
|
|
|
let y1 = Bangle.appRect.y + SCREENHEIGHT * offsetvalue;
|
|
|
|
let y2 = SCREENHEIGHT - SCREENHEIGHT * offsetvalue;
|
2023-09-09 22:32:12 +00:00
|
|
|
dragleft = data.x < x1;
|
2023-09-07 02:46:57 +00:00
|
|
|
dragright = data.x > x2;
|
|
|
|
dragup = data.y < y1;
|
|
|
|
dragdown = data.y > y2;
|
|
|
|
btna = ((data.x <= x2) && (data.x >= x1) && (data.y >= y1) && (data.y <= y2) && (data.type == 0));
|
|
|
|
btnb = ((data.x <= x2) && (data.x >= x1) && (data.y >= y1) && (data.y <= y2) && (data.type == 2));
|
2023-09-11 20:57:39 +00:00
|
|
|
if (DEBUGMODEINPUT) {
|
|
|
|
debugLog("tap button:" + button.toString() + " x:" + data.x.toString() + " y:" + data.y.toString() + " x1:" + x1.toString() + " x2:" + x2.toString() + " y1:" + y1.toString() + " y2:" + y2.toString() + " type:" + data.type.toString());
|
|
|
|
debugLog("l:" + dragleft.toString() + " u:" + dragup.toString() + " r:" + dragright.toString() + " d:" + dragdown.toString() + " a:" + btna.toString() + " b:" + btnb.toString());
|
|
|
|
}
|
2023-09-07 02:46:57 +00:00
|
|
|
loop();
|
|
|
|
dragleft = false;
|
|
|
|
dragright = false;
|
|
|
|
dragdown = false;
|
|
|
|
dragup = false;
|
|
|
|
btna = false;
|
|
|
|
btnb = false;
|
2023-09-09 22:32:12 +00:00
|
|
|
while (needRedraw)
|
|
|
|
loop();
|
2023-09-11 20:57:39 +00:00
|
|
|
if (DEBUGMODEINPUT)
|
|
|
|
debugLog("handleTouch done");
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 22:32:12 +00:00
|
|
|
function btnPressed() {
|
2023-09-07 02:46:57 +00:00
|
|
|
dragleft = false;
|
|
|
|
dragright = false;
|
|
|
|
dragdown = false;
|
|
|
|
dragup = false;
|
|
|
|
btna = false;
|
|
|
|
btnb = true;
|
|
|
|
loop();
|
|
|
|
btnb = false;
|
2023-09-09 22:32:12 +00:00
|
|
|
while (needRedraw)
|
|
|
|
loop();
|
2023-09-11 20:57:39 +00:00
|
|
|
if (DEBUGMODEINPUT)
|
|
|
|
debugLog("btnPressed done");
|
2023-09-07 02:46:57 +00:00
|
|
|
}
|
|
|
|
|
2023-09-11 20:57:39 +00:00
|
|
|
//initialize spritepos arrays
|
2023-09-13 10:57:28 +00:00
|
|
|
for (let i = 0; i < cursorNumTiles; i++)
|
2023-09-11 20:57:39 +00:00
|
|
|
spritePos.push(new Int8Array(2));
|
|
|
|
|
2023-09-07 02:46:57 +00:00
|
|
|
//clear one time entire screen
|
|
|
|
g.clear();
|
|
|
|
//setup game and run loop it will repeat during intro
|
|
|
|
//otherwise only as long as redraw is needed after input was detected
|
|
|
|
setup();
|
|
|
|
//for intro only
|
2023-09-13 10:57:28 +00:00
|
|
|
let intervalTimer = setInterval(loop, 66); // 15 fps
|
2023-09-07 02:46:57 +00:00
|
|
|
//for handling input
|
|
|
|
Bangle.on('touch', handleTouch);
|
2023-09-09 22:32:12 +00:00
|
|
|
setWatch(btnPressed, BTN, {
|
|
|
|
edge: "rising",
|
|
|
|
debounce: 50,
|
|
|
|
repeat: true
|
|
|
|
});
|