From 003a3072803247e843c6f8d9aa67cbffafa71e35 Mon Sep 17 00:00:00 2001 From: Willems Davy Date: Fri, 15 Sep 2023 04:18:40 +0200 Subject: [PATCH] Add C alternatives for generateLevel and random functions but keep the javascript ones for the emulator + put certain functions always in ram --- apps/waternet/app.js | 377 ++++++++++++++++++++++++++++++++----------- 1 file changed, 284 insertions(+), 93 deletions(-) diff --git a/apps/waternet/app.js b/apps/waternet/app.js index fd929dcde..e3f0e553c 100644 --- a/apps/waternet/app.js +++ b/apps/waternet/app.js @@ -200,12 +200,162 @@ const TITLE = { }; // -------------------------------------------------------------------------------------------------- +// C Code +// // random stuff // https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript#72732727 +// 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/ // -------------------------------------------------------------------------------------------------- + +//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 +// -------------------------------------------------------------------------------------------------- + let randfunc; -function srand(seed) { +function srandjs(seed) { var m = Math.pow(2, 35) - 31; var a = 185852; var s = seed % m; @@ -214,10 +364,26 @@ function srand(seed) { }; } -function random(value) { +function randomjs(value) { return Math.floor(randfunc()) % value; } +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); +} + srand(Date().getTime()); // -------------------------------------------------------------------------------------------------- @@ -323,6 +489,7 @@ function initCursors() { // helper funcs // -------------------------------------------------------------------------------------------------- function set_bkg_tile_xy(x, y, tile) { + "RAM"; g.drawImage(currentTiles, SCREENOFFSETX + x * TILESIZE, screenOffsetY + y * TILESIZE, { frame: tile }); @@ -337,6 +504,7 @@ function get_bkg_data() { } function set_bkg_tiles(x, y, map) { + "RAM"; g.drawImage(map, SCREENOFFSETX + x, screenOffsetY + y); } @@ -755,6 +923,116 @@ function intro() { // -------------------------------------------------------------------------------------------------- // Level Stuff // -------------------------------------------------------------------------------------------------- + +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(); + } +} + function moveBlockDown(aTile) { let tmp = level[aTile + boardSize - boardWidth]; for (let i = boardSize - boardWidth; i != 0; i -= boardWidth) @@ -1027,98 +1305,7 @@ function updateConnected() { } } -function generateLevel() { - 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++; - } -} //when all board tiles are not below 16, the level is cleared //as there are 16 tiles per tilegroup (no water, water, special start with water) @@ -1401,11 +1588,13 @@ function levelSelect() { // printing functions // -------------------------------------------------------------------------------------------------- function setCharAt(str, index, chr) { + "RAM"; if (index > str.length - 1) return str; return str.substring(0, index) + chr + str.substring(index + 1); } function formatInteger(valinteger) { + "RAM"; const maxDigits = 10; let array = " "; @@ -1440,6 +1629,7 @@ function formatInteger(valinteger) { //print a number on levelselect or game screen function printNumber(ax, ay, aNumber, maxDigits) { + "RAM"; const buffSize = 10; let ret = formatInteger(aNumber); @@ -1455,6 +1645,7 @@ function printNumber(ax, ay, aNumber, maxDigits) { //print a message on the title screen on ax,ay, the tileset from titlescreen contains an alphabet function printMessage(ax, ay, amsg) { + "RAM"; let aCode = 'A'.charCodeAt(0); let zCode = 'Z'.charCodeAt(0); let zeroCode = '0'.charCodeAt(0);