v0.99m.1
(1) Add tools that extract game levels from APPLE-II Lode Runner disk
Add folder : tools
(2) Remove unused data from file: lodeRunner.wData.js
Cette révision appartient à :
+28
-1
@@ -1,6 +1,33 @@
|
|||||||
[Lode Runner (超級運動員)](http://simonsays-tw.com/LodeRunner)
|
[Lode Runner (超級運動員)](http://simonsays-tw.com/LodeRunner)
|
||||||
==========================
|
=========================
|
||||||
|
|
||||||
This program build with Javascript + [CreateJS](http://www.createjs.com).
|
This program build with Javascript + [CreateJS](http://www.createjs.com).
|
||||||
|
|
||||||
|
### GAME Mode
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><b>CLASSIC MODE</b></td>
|
||||||
|
<td>Same as APPLE-II play mode</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><b>TIME MODE</b></td>
|
||||||
|
<td>Player can select levels</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><b>EDIT MODE</b></td>
|
||||||
|
<td>Player can create self-levels</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><b>DEMO MODE</b></td>
|
||||||
|
<td>Replay passed levels</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
### [PLAY](http://goo.gl/KgmXhh)
|
||||||
|
http://simonsays-tw.com/web/lodeRunner/game/lodeRunner.html
|
||||||
|
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var VERSION = "0.99k";
|
var VERSION = "0.99m";
|
||||||
var AI_VERSION = 1;
|
var AI_VERSION = 1;
|
||||||
|
|
||||||
var NO_OF_TILES_X = 28,
|
var NO_OF_TILES_X = 28,
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
* The AI algorithm reference book:
|
* The AI algorithm reference book:
|
||||||
* http://www.kingstone.com.tw/book/book_page.asp?kmcode=2014710650538
|
* http://www.kingstone.com.tw/book/book_page.asp?kmcode=2014710650538
|
||||||
*
|
*
|
||||||
|
* Source Code: https://github.com/SimonHung/LodeRunner
|
||||||
|
*
|
||||||
* by Simon Hung 2014/06/20 (http://simonsays-tw.com)
|
* by Simon Hung 2014/06/20 (http://simonsays-tw.com)
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
* The AI algorithm reference book:
|
* The AI algorithm reference book:
|
||||||
* http://www.kingstone.com.tw/book/book_page.asp?kmcode=2014710650538
|
* http://www.kingstone.com.tw/book/book_page.asp?kmcode=2014710650538
|
||||||
*
|
*
|
||||||
|
* Source Code: https://github.com/SimonHung/LodeRunner
|
||||||
|
*
|
||||||
* by Simon Hung 2014/06/20 (http://simonsays-tw.com)
|
* by Simon Hung 2014/06/20 (http://simonsays-tw.com)
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,31 +1,3 @@
|
|||||||
|
|
||||||
// World HighScores1
|
|
||||||
var wHighScores1 = [
|
|
||||||
{ s: 662025, n: "SIMON", l: 69, c: "Taiwan"} //1 date: 2014-06-07 15:33:26
|
|
||||||
,{ s: 61200, n: "AS", l: 8, c: "United States"} //2 date: 2014-06-14 00:39:07
|
|
||||||
,{ s: 58900, n: "BITCH", l: 8, c: "United States"} //3 date: 2014-06-14 01:13:26
|
|
||||||
,{ s: 41050, n: "SIMON HUNG", l: 9, c: "Taiwan"} //4 date: 2014-06-02 21:08:18
|
|
||||||
,{ s: 38250, n: "DANIEL", l: 6, c: "Taiwan"} //5 date: 2014-06-17 00:49:41
|
|
||||||
,{ s: 38250, n: "DANIEL", l: 6, c: "Taiwan"} //6 date: 2014-06-17 00:49:40
|
|
||||||
,{ s: 33575, n: "DANIEL", l: 6, c: "Taiwan"} //7 date: 2014-06-16 14:09:01
|
|
||||||
,{ s: 32400, n: "DANIEL", l: 6, c: "Taiwan"} //8 date: 2014-06-16 00:44:55
|
|
||||||
,{ s: 31325, n: "DANIEL", l: 5, c: "Taiwan"} //9 date: 2014-06-17 00:38:00
|
|
||||||
,{ s: 31325, n: "DANIEL", l: 5, c: "Taiwan"} //10 date: 2014-06-17 00:37:59
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// World HighScores2
|
|
||||||
var wHighScores2 = [
|
|
||||||
{ s: 35000, n: "Simon", l: 100, c: "Taiwan"} //1 date: 2014-06-03 00:17:48
|
|
||||||
,{ s: 35000, n: "Simon", l: 100, c: "Taiwan"} //2 date: 2014-06-01 19:37:07
|
|
||||||
,{ s: 35000, n: "Simon", l: 100, c: "Taiwan"} //3 date: 2014-06-01 14:58:04
|
|
||||||
,{ s: 6500, n: "PPP", l: 1, c: "Taiwan"} //4 date: 2014-06-01 10:14:11
|
|
||||||
,{ s: 3000, n: "LAD APPLE", l: 1, c: "Taiwan"} //5 date: 2014-06-01 10:15:43
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// World DemoData1
|
// World DemoData1
|
||||||
var wDemoData1 = [
|
var wDemoData1 = [
|
||||||
{ level: 1, ai: 1, time: 757, state: 1, country: "Taiwan", //id=1 2014-06-05 01:11:19
|
{ level: 1, ai: 1, time: 757, state: 1, country: "Taiwan", //id=1 2014-06-05 01:11:19
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
Read Lode Runner APPLE-II DISK IMAGE to extract all levels
|
||||||
|
|
||||||
|
Each level is a 28x16 tiles, Lode Runner has 8 different tile types.
|
||||||
|
Two additional tiles are used to represent the player and guard start positions.
|
||||||
|
(reference : http://baetzler.de/c64/games/loderunner/)
|
||||||
|
|
||||||
|
APPLE-II DISK data format:
|
||||||
|
|
||||||
|
Since there are less than 16 different tiles, it is both convenient and
|
||||||
|
efficient to store tiles as nibbles instead of bytes.
|
||||||
|
Thus the 448 tiles of a Lode Runner level can be represented in 224 (0xE0) bytes
|
||||||
|
|
||||||
|
The tile data for each level use 256 bytes (0x00 ~ 0xFF),
|
||||||
|
level data starts at offset 0x00 to 0xDF, and reserved 0x20 bytes.
|
||||||
|
(0x00 ~ 0xDF + 0x20 = 0x100 (256) bytes)
|
||||||
|
|
||||||
|
The tiles are stored in left-to-right, to-to-bottom order,
|
||||||
|
with a small twist: the low nibble of each byte encodes the left tile
|
||||||
|
and the high nibble encodes the right tile in each byte of data.
|
||||||
|
|
||||||
|
level start from disk offset 0x3000,
|
||||||
|
|
||||||
|
Lode Runner Level value to map (10 different types):
|
||||||
|
|
||||||
|
value | Character | Type
|
||||||
|
------+-----------+-----------
|
||||||
|
0x0 | <space> | Empty space
|
||||||
|
0x1 | # | Normal Brick
|
||||||
|
0x2 | @ | Solid Brick
|
||||||
|
0x3 | H | Ladder
|
||||||
|
0x4 | - | Hand-to-hand bar (Line of rope)
|
||||||
|
0x5 | X | False brick
|
||||||
|
0x6 | S | Ladder appears at end of level
|
||||||
|
0x7 | $ | Gold chest
|
||||||
|
0x8 | 0 | Guard
|
||||||
|
0x9 | & | Player
|
||||||
|
|
||||||
|
|
||||||
|
**********************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define MAX_TILE_TYPE (sizeof(tileType)/sizeof(char))
|
||||||
|
#define MAX_LEVEL_ROW (16)
|
||||||
|
#define MAX_LEVEL_COL (28)
|
||||||
|
|
||||||
|
#define READ_LEVEL_DATA_SIZE (256)
|
||||||
|
#define ONE_LEVEL_DATA_SIZE (224)
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
#define FILE_NAME "Lode_Runner_Apple-II.dsk"
|
||||||
|
#define MAX_LEVEL (150)
|
||||||
|
#define TITLE_NAME "Lode Runner (Apple-II 1983)"
|
||||||
|
#define DATA_VAR_NAME "baseLevelData"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define FILE_NAME "Lode_Runner_Championship _Apple-II.dsk"
|
||||||
|
#define MAX_LEVEL (50)
|
||||||
|
#define TITLE_NAME "Championship Lode Runner (Apple-II 1984)"
|
||||||
|
#define DATA_VAR_NAME "champLevelData"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char tileType[] = {
|
||||||
|
' ', //0x00: Empty space
|
||||||
|
'#', //0x01:Normal Brick
|
||||||
|
'@', //0x02:Solid Brick
|
||||||
|
'H', //0x03:Ladder
|
||||||
|
'-', //0x04:Hand-to-hand bar (Line of rope)
|
||||||
|
'X', //0x05:False brick
|
||||||
|
'S', //0x06:Ladder appears at end of level
|
||||||
|
'$', //0x07:Gold chest
|
||||||
|
'0', //0x08:Guard
|
||||||
|
'&' //0x09:Player
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int goodLevel(unsigned char *levelData)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char leftTile, rightTile;
|
||||||
|
|
||||||
|
for(i = 0; i < ONE_LEVEL_DATA_SIZE; i++) {
|
||||||
|
leftTile = levelData[i] & 0xF;
|
||||||
|
rightTile = levelData[i] >> 0x04;
|
||||||
|
if(leftTile >= MAX_TILE_TYPE || rightTile >= MAX_TILE_TYPE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1; //OK
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpTitle(void)
|
||||||
|
{
|
||||||
|
printf("//************************************************************\n");
|
||||||
|
printf("//* All levels extract from: \n");
|
||||||
|
printf("//* %s DISK IMAGE\n",TITLE_NAME );
|
||||||
|
printf("//* by Simon Hung 2014/02/20\n");
|
||||||
|
printf("//************************************************************\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpLevel(int level, unsigned char *levelData)
|
||||||
|
{
|
||||||
|
int row, col;
|
||||||
|
unsigned char leftTile, rightTile;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
printf("======<<< Level %03d >>>======\n\n", level);
|
||||||
|
for(row = 0; row < MAX_LEVEL_ROW; row++){
|
||||||
|
for(col = 0; col < MAX_LEVEL_COL; col+=2){ //one byte contains 2 tile
|
||||||
|
leftTile = levelData[offset] & 0xF;
|
||||||
|
rightTile = levelData[offset] >> 0x04;
|
||||||
|
printf("%c%c",tileType[leftTile],tileType[rightTile]);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpLevel4JavaScript(int level, unsigned char *levelData)
|
||||||
|
{
|
||||||
|
int row, col;
|
||||||
|
unsigned char leftTile, rightTile;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
printf("//======<<< Level %03d >>>======\n\n", level);
|
||||||
|
for(row = 0; row < MAX_LEVEL_ROW; row++){
|
||||||
|
printf("\"");
|
||||||
|
for(col = 0; col < MAX_LEVEL_COL; col+=2){ //one byte contains 2 tile
|
||||||
|
leftTile = levelData[offset] & 0xF;
|
||||||
|
rightTile = levelData[offset] >> 0x04;
|
||||||
|
printf("%c%c",tileType[leftTile],tileType[rightTile]);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
if(row < MAX_LEVEL_ROW-1)printf("\" +\n");
|
||||||
|
else if (level < MAX_LEVEL)printf("\",\n");
|
||||||
|
else printf("\"\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
unsigned char levelData[READ_LEVEL_DATA_SIZE];
|
||||||
|
int curLevel = 0;
|
||||||
|
|
||||||
|
if((fp = fopen(FILE_NAME, "r")) ==NULL) {
|
||||||
|
printf("Open file %d failed !\n", FILE_NAME);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fseek(fp, 0x3000L, SEEK_SET) != 0) {
|
||||||
|
printf("Fseek error ! @%d\n", __LINE__);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpTitle();
|
||||||
|
|
||||||
|
printf("var %s = [\n", DATA_VAR_NAME);
|
||||||
|
while(curLevel < MAX_LEVEL &&
|
||||||
|
fread(levelData, sizeof(char), READ_LEVEL_DATA_SIZE, fp) == READ_LEVEL_DATA_SIZE &&
|
||||||
|
goodLevel(levelData)
|
||||||
|
){
|
||||||
|
//dumpLevel(++curLevel, levelData);
|
||||||
|
dumpLevel4JavaScript(++curLevel, levelData);
|
||||||
|
}
|
||||||
|
printf("];\n");
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
Fichier binaire non affiché.
Fichier binaire non affiché.
Fichier binaire non affiché.
@@ -0,0 +1,50 @@
|
|||||||
|
/**************************************************
|
||||||
|
compare two files modify date
|
||||||
|
if file1 > file2 return > 0
|
||||||
|
if file1 <= file 2 return < 0
|
||||||
|
if error return = 0
|
||||||
|
***************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
//#include <string.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main ( int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct stat fileAttrib1, fileAttrib2;
|
||||||
|
struct tm *pTm1, *pTm2;
|
||||||
|
time_t time1, time2;
|
||||||
|
double seconds;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
printf("Usage: %s <file1> <file2>\n", argv[0]);
|
||||||
|
printf("compare <file1> <file2> modify date \n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if (stat(argv[1], &fileAttrib1) < 0) {
|
||||||
|
printf("Get File (%s) attribute error, Message = %s\n", argv[1], strerror(errno));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (stat(argv[2], &fileAttrib2) < 0) {
|
||||||
|
printf("Get File (%s) attribute error, Message = %s\n", argv[2], strerror(errno));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTm1 = gmtime(&fileAttrib1.st_mtime);
|
||||||
|
time1 = mktime( pTm1 );
|
||||||
|
|
||||||
|
pTm2 = gmtime(&fileAttrib2.st_mtime);
|
||||||
|
time2 = mktime( pTm2 );
|
||||||
|
|
||||||
|
//printf("time1 = %ld, time2 = %ld\n", time1, time2);
|
||||||
|
seconds = difftime(time1,time2);
|
||||||
|
|
||||||
|
//printf("seconds = %.f\n", seconds);
|
||||||
|
return (seconds>0?1:-1);
|
||||||
|
}
|
||||||
Fichier binaire non affiché.
Référencer dans un nouveau ticket
Bloquer un utilisateur