1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-25 03:34:05 +00:00

working on github integration; added nes chase game and support folders/; removed ga()

This commit is contained in:
Steven Hugg 2019-05-05 21:49:08 -04:00
parent 7ee650bb64
commit d2b19df9c9
24 changed files with 4068 additions and 124 deletions

3
.gitmodules vendored
View File

@ -4,9 +4,6 @@
[submodule "codemirror"] [submodule "codemirror"]
path = codemirror path = codemirror
url = https://github.com/codemirror/CodeMirror url = https://github.com/codemirror/CodeMirror
[submodule "octokat.js"]
path = octokat.js
url = https://github.com/philschatz/octokat.js
[submodule "tss"] [submodule "tss"]
path = tss path = tss
url = https://github.com/sehugg/tss url = https://github.com/sehugg/tss

View File

@ -131,6 +131,7 @@ TODO:
- upload multiple files/zip file to subdirectory - upload multiple files/zip file to subdirectory
- allow "include graphics.asm" instead of "include project/graphics.asm" - allow "include graphics.asm" instead of "include project/graphics.asm"
- chrome looks blurry on vcs - chrome looks blurry on vcs
- don't have to include bootstrap-tourist each time?
WEB WORKER FORMAT WEB WORKER FORMAT
@ -256,3 +257,13 @@ Assets come from:
- structured data (palette, sprites, metasprites, levels, etc) - structured data (palette, sprites, metasprites, levels, etc)
- think about new comment format, platform-specific types - think about new comment format, platform-specific types
Github Support
Import
Export
Login
Pull
Push
Git metadata kept in local storage

View File

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>8bitworkshop IDE</title> <title>8bitworkshop IDE</title>
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
@ -19,16 +20,8 @@ body {
} }
</style> </style>
<link rel="stylesheet" href="css/ui.css"> <link rel="stylesheet" href="css/ui.css">
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
if (window.location.host.endsWith('8bitworkshop.com')) {
ga('create', 'UA-54497476-9', 'auto');
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
</head> </head>
<body> <body>
<!-- for file upload --> <!-- for file upload -->
@ -55,6 +48,16 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<li><a class="dropdown-item" href="#" id="item_addfile_link">Add Linked File...</a></li> <li><a class="dropdown-item" href="#" id="item_addfile_link">Add Linked File...</a></li>
</ul> </ul>
</li> </li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Sync</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" id="item_github_import">Import Project from GitHub...</a></li>
<li><a class="dropdown-item" href="#" id="item_github_connect">Publish Project on GitHub...</a></li>
<hr>
<li><a class="dropdown-item" href="#" id="item_github_connect">Pull Latest from Repository</a></li>
<li><a class="dropdown-item" href="#" id="item_github_connect">Push Changes to Repository...</a></li>
</ul>
</li>
<li class="dropdown dropdown-submenu"> <li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Download</a> <a tabindex="-1" href="#">Download</a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
@ -67,7 +70,6 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<li class="dropdown dropdown-submenu"> <li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Share</a> <a tabindex="-1" href="#">Share</a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" id="item_share_github">Share File on Github...</a></li>
<li><a class="dropdown-item" href="#" id="item_share_file">Share Playable Link...</a></li> <li><a class="dropdown-item" href="#" id="item_share_file">Share Playable Link...</a></li>
<li><a class="dropdown-item" href="#" id="item_record_video">Record Video...</a></li> <li><a class="dropdown-item" href="#" id="item_record_video">Record Video...</a></li>
<li><a class="dropdown-item" href="#" id="item_export_cassette">Make Cassette Audio...</a></li> <li><a class="dropdown-item" href="#" id="item_export_cassette">Make Cassette Audio...</a></li>
@ -142,7 +144,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
</ul> </ul>
</span> </span>
<select id="preset_select" name="" title="Project Select" style="width:16em;visibility:hidden"> <select id="preset_select" name="" title="Project Select" style="width:18em;visibility:hidden">
</select> </select>
<img id="compile_spinner" src="images/spinner.gif" height="20em" style="visibility:hidden;margin-left:8px;margin-right:8px"> <img id="compile_spinner" src="images/spinner.gif" height="20em" style="visibility:hidden;margin-left:8px;margin-right:8px">
@ -267,24 +269,35 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
</div> </div>
</div> </div>
</div> </div>
<div id="embedGistModal" class="modal fade"> <div id="importGithubModal" class="modal fade">
<div class="modal-dialog modal-lg" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h3 class="modal-title">Share Code on Github</h3> <h3 class="modal-title">Import Project from GitHub</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p>If you have a Github account, you can share your code as a Github gist.</p> <p>Enter the GitHub repository URL:</p>
<ul> <p><input id="importGithubURL" size="60" placeholder="https://github.com/user/repo"></input></p>
<li>Make sure the correct platform is selected. <p><button type="button" class="btn btn-primary" id="importGithubButton">Import Project</button></p>
<li>Go to <a href="https://gist.github.com/" target="_8bitgist">gist.github.com</a> </div>
<li>Create a gist with your source code (one file only.) <div class="modal-footer">
<li>Paste the final gist URL below. <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</ul> </div>
<textarea rows="2" cols="100" id="embedGistURL" class="cliptext"></textarea> </div>
<p>The shareable URL will appear here:</p> </div>
<textarea rows="2" cols="100" id="embedGistShareURL" class="cliptext"></textarea><br> </div>
<button type="button" class="btn btn-primary" data-clipboard-target="#embedGistShareURL">Copy Shareable Link</button> <div id="connectGithubModal" class="modal fade">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Publish Project on GitHub</h3>
</div>
<div class="modal-body">
<p>This will migrate your existing files to a GitHub repository.</p>
<p><input id="connectGithubURL" size="40" placeholder="Enter a project name"></input></p>
<p><button type="button" class="btn btn-primary" id="connectGithubButton">Upload Project</button></p>
<p>If the destination repository does not exist, it will be created.</p>
<p>Your existing file will be moved to a new folder in the IDE.</p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
@ -385,5 +398,11 @@ $( ".dropdown-submenu" ).click(function(event) {
*/ */
</script> </script>
<!-- firebase libs -->
<script defer src="https://www.gstatic.com/firebasejs/5.10.1/firebase.js"></script>
<script defer src="config.js"></script>
<script defer src="https://cdn.firebase.com/libs/firebaseui/3.6.0/firebaseui.js"></script>
<link defer type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.6.0/firebaseui.css" />
</body> </body>
</html> </html>

2265
lib/octokat.js Normal file

File diff suppressed because it is too large Load Diff

@ -1 +0,0 @@
Subproject commit 2cba2d91728730ae5d51eb595cf36c7bf9221c5d

865
presets/nes/chase/game.c Normal file
View File

@ -0,0 +1,865 @@
//Chase NES game by Shiru (shiru@mail.ru) 01'12
//Feel free to do anything you want with this code, consider it Public Domain
//This game is an example for my article Programming NES games in C
//include the library
#include "neslib.h"
#include <string.h>
//#link "famitone2.s"
//#link "music.s"
//#link "sounds.s"
// CHR data
//#resource "tileset.chr"
//#link "tileset.s"
//include nametables for all the screens such as title or game over
#include "title_nam.h"
#include "level_nam.h"
#include "gameover_nam.h"
#include "welldone_nam.h"
//include nametables for levels
#include "level1_nam.h"
#include "level2_nam.h"
#include "level3_nam.h"
#include "level4_nam.h"
#include "level5_nam.h"
//game uses 12:4 fixed point calculations for enemy movements
#define FP_BITS 4
//max size of the game map
#define MAP_WDT 16
#define MAP_WDT_BIT 4
#define MAP_HGT 13
//macro for calculating map offset from screen space, as
//the map size is smaller than screen to save some memory
#define MAP_ADR(x,y) ((((y)-2)<<MAP_WDT_BIT)|(x))
//size of a map tile
#define TILE_SIZE 16
#define TILE_SIZE_BIT 4
//movement directions, match to the gamepad buttons bits to
//simplify some things
#define DIR_NONE 0
#define DIR_LEFT PAD_LEFT
#define DIR_RIGHT PAD_RIGHT
#define DIR_UP PAD_UP
#define DIR_DOWN PAD_DOWN
//tile numbers for certain things in the game map
//i.e. which object corresponds to a character in the tileset
#define TILE_PLAYER 0x10
#define TILE_ENEMY1 0x11
#define TILE_ENEMY2 0x12
#define TILE_ENEMY3 0x13
#define TILE_WALL 0x40
#define TILE_EMPTY 0x44
#define TILE_ITEM 0x45
//number of levels in the game
#define LEVELS_ALL 5
//numbers for screens that are displayed by the same function as the
//level number
#define SCREEN_GAMEOVER (LEVELS_ALL+0)
#define SCREEN_WELLDONE (LEVELS_ALL+1)
//total number of moving characters on the screen
#define PLAYER_MAX 4
//sound effect numbers, it is easier to use meaningful defines than
//remember actual numbers of the effects
#define SFX_START 0
#define SFX_ITEM 1
#define SFX_RESPAWN1 2
#define SFX_RESPAWN2 3
//sub songs numbers in the music.ftm
#define MUSIC_LEVEL 0
#define MUSIC_GAME 1
#define MUSIC_CLEAR 2
#define MUSIC_GAME_OVER 3
#define MUSIC_WELL_DONE 4
#define MUSIC_LOSE 5
//palettes data
//all the palettes are designed in NES Screen Tool, then copy/pasted here
//with Palettes/Put C data to clipboard function
const unsigned char palTitle[16]={ 0x0f,0x0f,0x0f,0x0f,0x0f,0x1c,0x2c,0x3c,0x0f,0x12,0x22,0x32,0x0f,0x14,0x24,0x34 };
const unsigned char palGame1[16]={ 0x0f,0x11,0x32,0x30,0x0f,0x1c,0x2c,0x3c,0x0f,0x09,0x27,0x38,0x0f,0x11,0x21,0x31 };
const unsigned char palGame2[16]={ 0x0f,0x11,0x32,0x30,0x0f,0x11,0x21,0x31,0x0f,0x07,0x27,0x38,0x0f,0x13,0x23,0x33 };
const unsigned char palGame3[16]={ 0x0f,0x11,0x32,0x30,0x0f,0x15,0x25,0x35,0x0f,0x05,0x27,0x38,0x0f,0x13,0x23,0x33 };
const unsigned char palGame4[16]={ 0x0f,0x11,0x32,0x30,0x0f,0x19,0x29,0x39,0x0f,0x0b,0x27,0x38,0x0f,0x17,0x27,0x37 };
const unsigned char palGame5[16]={ 0x0f,0x11,0x32,0x30,0x0f,0x16,0x26,0x36,0x0f,0x07,0x27,0x38,0x0f,0x18,0x28,0x38 };
const unsigned char palGameSpr[16]={ 0x0f,0x0f,0x29,0x30,0x0f,0x0f,0x26,0x30,0x0f,0x0f,0x24,0x30,0x0f,0x0f,0x21,0x30 };
//metasprites
const unsigned char sprPlayer[]={
0,-1,0x49,0,
8,-1,0x4a,0,
0, 7,0x4b,0,
8, 7,0x4c,0,
128
};
const unsigned char sprEnemy1[]={
0,-1,0x4d,1,
8,-1,0x4e,1,
0, 7,0x4f,1,
8, 7,0x50,1,
128
};
const unsigned char sprEnemy2[]={
0,-1,0x4d,2,
8,-1,0x4e,2,
0, 7,0x4f,2,
8, 7,0x50,2,
128
};
const unsigned char sprEnemy3[]={
0,-1,0x4d,3,
8,-1,0x4e,3,
0, 7,0x4f,3,
8, 7,0x50,3,
128
};
//list of metasprites
const unsigned char* const sprListPlayer[]={ sprPlayer,sprEnemy1,sprEnemy2,sprEnemy3 };
//list of the levels, include pointer to the packed nametable of the level,
//and pointer to the associated palette
const unsigned char* const levelList[LEVELS_ALL*2]={
level1_nam,palGame1,
level2_nam,palGame2,
level3_nam,palGame3,
level4_nam,palGame3,
level5_nam,palGame3
};
//preinitialized update list used during the gameplay
const unsigned char updateListData[]={
0x28,0x00,TILE_EMPTY, //these four entries are used to clear
0x28,0x00,TILE_EMPTY, //the level tile after an item is collected
0x28,0x00,TILE_EMPTY,
0x28,0x00,TILE_EMPTY,
0x20,0x4f,0x10, //these three entires are used to display
0x20,0x50,0x10, //number of the collected items
0x20,0x51,0x10,
NT_UPD_EOF
};
//a nametable string with the game stats, created in NES Screen Tool
//and copy/pasted here with Shift+C
const unsigned char statsStr[27]={
0x2c,0x25,0x36,0x25,0x2c,0x1a,0x00,0x00,0x27,
0x25,0x2d,0x33,0x1a,0x00,0x00,0x00,0x0f,0x00,
0x00,0x00,0x00,0x2c,0x29,0x36,0x25,0x33,0x1a
};
//list of screens such as level number, game over, and well done
//contains pointers to the packed nametables
const unsigned char* screenList[3]={ level_nam,gameover_nam,welldone_nam };
//list of sub songs for corresponding screens
const unsigned char screenMusicList[3]={MUSIC_LEVEL,MUSIC_GAME_OVER,MUSIC_WELL_DONE};
//large 1-5 numbers nametable definitons, 2x3 tiles each
//numbers were drawn one next to the other in NES Screen Tool,
//then that part of nametable was copy/pasted here with Shift+C
//here they are orderded as
// top row of 11 22 33 44 55
//middle row of 11 22 33 44 55
//bottom row of 11 22 33 44 55
const unsigned char largeNums[10*3]={
0x7a,0x7b,0x7c,0x7d,0x7c,0x7d,0x7e,0x7f,0x80,0x81,
0x86,0x7b,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x7d,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x7f,0x94,0x95
};
//array for game map, contains walls, empty spaces, and items
static unsigned char map[MAP_WDT*MAP_HGT];
//put all the subsequent global vars into zeropage, to make code faster and shorter
#pragma bss-name(push,"ZEROPAGE")
#pragma data-name(push,"ZEROPAGE")
//set of general purpose global vars that are used everywhere in the program
//this makes code faster and shorter, although not very convinent and readable
static unsigned char i,j;
static unsigned char ptr,spr;
static unsigned char px,py;
static unsigned char wait;
static unsigned int i16;
static int iy,dy;
//this array is used to determine movement directions for enemies
static unsigned char dir[4];
//this array is used to convert nametable into game map, row by row
static unsigned char nameRow[32];
//number of moving characters on current level
static unsigned char player_all;
//character variables
static unsigned int player_x [PLAYER_MAX];
static unsigned int player_y [PLAYER_MAX];
static unsigned char player_dir [PLAYER_MAX];
static int player_cnt [PLAYER_MAX];
static unsigned int player_speed[PLAYER_MAX];
static unsigned char player_wait [PLAYER_MAX];
//number of items on current level, total and collected
static unsigned char items_count;
static unsigned char items_collected;
//game state variables
static unsigned char game_level;
static unsigned char game_lives;
//game state flags, they are 0 or 1
static unsigned char game_done;
static unsigned char game_paused;
static unsigned char game_clear;
//system vars used everywhere as well
static unsigned char frame_cnt;
static unsigned char bright;
//update list
static unsigned char update_list[7*3+1];
//smoothly fade current bright to the given value
//in case when to=0 it also stops the music,
//turns the display off, reset vram update and scroll
void pal_fade_to(unsigned to)
{
if(!to) music_stop();
while(bright!=to)
{
delay(4);
if(bright<to) ++bright; else --bright;
pal_bright(bright);
}
if(!bright)
{
ppu_off();
set_vram_update(NULL);
scroll(0,0);
}
}
//show title screen
void title_screen(void)
{
scroll(-8,240);//title is aligned to the color attributes, so shift it a bit to the right
vram_adr(NAMETABLE_A);
vram_unrle(title_nam);
vram_adr(NAMETABLE_C);//clear second nametable, as it is visible in the jumping effect
vram_fill(0,1024);
pal_bg(palTitle);
pal_bright(4);
ppu_on_bg();
delay(20);//delay just to make it look better
iy=240<<FP_BITS;
dy=-8<<FP_BITS;
frame_cnt=0;
wait=160;
bright=4;
while(1)
{
ppu_wait_frame();
scroll(-8,iy>>FP_BITS);
if(pad_trigger(0)&PAD_START) break;
iy+=dy;
if(iy<0)
{
iy=0;
dy=-dy>>1;
}
if(dy>(-8<<FP_BITS)) dy-=2;
if(wait)
{
--wait;
}
else
{
pal_col(2,(frame_cnt&32)?0x0f:0x20);//blinking press start text
++frame_cnt;
}
}
scroll(-8,0);//if start is pressed, show the title at whole
sfx_play(SFX_START,0);
for(i=0;i<16;++i)//and blink the text faster
{
pal_col(2,i&1?0x0f:0x20);
delay(4);
}
pal_fade_to(0);
}
//show level intro, game over, or well done screen
void show_screen(unsigned char num)
{
scroll(-4,0); //all the screens are misaligneg horizontally by half of a tile
if(num<LEVELS_ALL) spr=0; else spr=num-LEVELS_ALL+1;//get offset in the screens list
vram_adr(NAMETABLE_A);
vram_unrle(screenList[spr]);
if(!spr)//if it is the level screen, print large number
{
j=num<<1;
i16=0x2194;//position of the number in the nametable
for(i=0;i<3;++i)
{
vram_adr(i16);
vram_put(largeNums[j]);
vram_put(largeNums[j+1]);
j+=10;
i16+=32;
}
}
i16=(num==SCREEN_GAMEOVER)?0x1525:0x1121;//two colors for flashing text in LSB and MSB
frame_cnt=0;
pal_col(2,i16&0xff);//this palette entry is used for flashing text
pal_col(3,0x30);
pal_col(6,0x30);
ppu_on_bg();
pal_fade_to(4);
music_play(screenMusicList[spr]);
if(!spr)//if it is the level screen, just wait one second
{
delay(50);
}
else//otherwise wait for Start button and display flashing text
{
while(1)
{
ppu_wait_frame();
pal_col(2,frame_cnt&2?i16&0xff:i16>>8);
if(pad_trigger(0)&PAD_START) break;
++frame_cnt;
}
}
pal_fade_to(0);
}
//set up a move in the specified direction if there is no wall
void player_move(unsigned char id,unsigned char dir)
{
px=player_x[id]>>(TILE_SIZE_BIT+FP_BITS);
py=player_y[id]>>(TILE_SIZE_BIT+FP_BITS);
switch(dir)
{
case DIR_LEFT: --px; break;
case DIR_RIGHT: ++px; break;
case DIR_UP: --py; break;
case DIR_DOWN: ++py; break;
}
if(map[MAP_ADR(px,py)]==TILE_WALL) return;
player_cnt[id]=TILE_SIZE<<FP_BITS;
player_dir[id]=dir;
}
//print a 1-3 digit decimal number into VRAM
void put_num(unsigned int adr,unsigned int num,unsigned char len)
{
vram_adr(adr);
if(len>2) vram_put(0x10+num/100);
if(len>1) vram_put(0x10+num/10%10);
vram_put(0x10+num%10);
}
//the main gameplay code
void game_loop(void)
{
oam_clear();
i=game_level<<1;
vram_adr(NAMETABLE_A);
vram_unrle(levelList[i]); //unpack level nametable
vram_adr(NAMETABLE_A+0x0042);
vram_write((unsigned char*)statsStr,27); //add game stats string
pal_bg(levelList[i+1]); //set up background palette
pal_spr(palGameSpr); //set up sprites palette
player_all=0;
items_count=0;
items_collected=0;
//this loop reads the level nametable back from VRAM, row by row,
//constructs game map, removes spawn points from the nametable,
//and writes back to the VRAM
i16=NAMETABLE_A+0x0080;
ptr=0;
wait=0;
for(i=2;i<MAP_HGT+2;++i)
{
vram_adr(i16);
vram_read(nameRow,32);
vram_adr(i16);
for(j=0;j<MAP_WDT<<1;j+=2)
{
spr=nameRow[j];
switch(spr)
{
case TILE_PLAYER://player
case TILE_ENEMY1://enemies
case TILE_ENEMY2:
case TILE_ENEMY3:
player_dir [player_all]=DIR_NONE;
player_x [player_all]=(j<<3)<<FP_BITS;
player_y [player_all]=(i<<4)<<FP_BITS;
player_cnt [player_all]=0;
player_wait [player_all]=16+((spr-TILE_PLAYER)<<4);
player_speed[player_all]=(spr==TILE_PLAYER)?2<<FP_BITS:10+((spr-TILE_ENEMY1)<<1);
++player_all;
wait+=16;
spr=TILE_EMPTY;
break;
case TILE_ITEM:
++items_count;
break;
}
map[ptr++]=spr;
vram_put(spr);
vram_put(nameRow[j+1]);
}
i16+=64;
}
//setup update list
memcpy(update_list,updateListData,sizeof(updateListData));
set_vram_update(update_list);
//put constant game stats numbers, that aren't updated during level
put_num(NAMETABLE_A+0x0048,game_level+1,1);
put_num(NAMETABLE_A+0x0053,items_count,3);
put_num(NAMETABLE_A+0x005d,game_lives-1,1);
//enable display
ppu_on_all();
game_done=FALSE;
game_paused=FALSE;
game_clear=FALSE;
bright=0;
frame_cnt=0;
while(!game_done)
{
//construct OAM from object parameters
spr=(player_all-1)<<4;
for(i=0;i<player_all;++i)
{
py=player_y[i]>>FP_BITS;
if(player_wait[i])
{
if(player_wait[i]>=16||player_wait[i]&2) py=240;
}
oam_meta_spr(player_x[i]>>FP_BITS,py,spr,sprListPlayer[i]);
spr-=16;
}
//wait for next frame
//it is here and not at beginning of the loop because you need
//to update OAM for the very first frame, and you also need to do that
//right after object parameters were changed, so either OAM update should
//be in a function that called before the loop and at the end of the loop,
//or wait for NMI should be placed there
//otherwise you would have situation update-wait-display, i.e.
//one frame delay between action and display of its result
ppu_wait_frame();
++frame_cnt;
//slowly fade virtual brightness to needed value,
//which is max for gameplay or half for pause
if(!(frame_cnt&3))
{
if(!game_paused&&bright<4) ++bright;
if( game_paused&&bright>2) --bright;
pal_bright(bright);
}
//poll the gamepad in the trigger mode
i=pad_trigger(0);
//it start was released and then pressed, toggle pause mode
if(i&PAD_START)
{
game_paused^=TRUE;
music_pause(game_paused);
}
//don't process anything in pause mode, just display latest game state
if(game_paused) continue;
//CHR bank switching animation with different speed for background and sprites
bank_bg((frame_cnt>>4)&1);
bank_spr((frame_cnt>>3)&1);
//a counter that does not allow objects to move while spawn animation plays
if(wait)
{
--wait;
if(!wait) music_play(MUSIC_GAME);//start the music when all the objects spawned
}
//check for level completion condition
if(items_collected==items_count)
{
music_play(MUSIC_CLEAR);
game_done=TRUE;
game_clear=TRUE;
}
//process all the objects
//player and enemies are the same type of object in this game,
//to make code simpler and shorter, but generally they need to be
//different kind of objects
for(i=0;i<player_all;++i)
{
//per-object spawn animation counter, it counts fron N to 16 to 0
//needed because objects spawn in sequence, not all at once
if(player_wait[i])
{
if(player_wait[i]==16) sfx_play(i?SFX_RESPAWN2:SFX_RESPAWN1,i);
--player_wait[i];
continue;
}
if(wait) continue; //don't process object movements if spawn animation is running
//check collision of an enemy object with player object
//NOT logic is used here, check http://gendev.spritesmind.net/page-collide.html
if(i)
{
if(!((player_x[i]+(4 <<FP_BITS))>=(player_x[0]+(12<<FP_BITS))||
(player_x[i]+(12<<FP_BITS))< (player_x[0]+(4 <<FP_BITS))||
(player_y[i]+(4 <<FP_BITS))>=(player_y[0]+(12<<FP_BITS))||
(player_y[i]+(12<<FP_BITS))< (player_y[0]+(4 <<FP_BITS))))
{
//if an enemy touch the player, quit the game loop
if(!game_clear)
{
music_play(MUSIC_LOSE);
game_done=TRUE;
break;
}
}
}
//if movement counter is not zero, process the movement
if(player_cnt[i])
{
switch(player_dir[i])
{
case DIR_RIGHT: player_x[i]+=player_speed[i]; break;
case DIR_LEFT: player_x[i]-=player_speed[i]; break;
case DIR_DOWN: player_y[i]+=player_speed[i]; break;
case DIR_UP: player_y[i]-=player_speed[i]; break;
}
player_cnt[i]-=player_speed[i];
//if move from one tile to another is over, realign the object to tile grid
//it is needed because when it moves with non-integer speed, it could
//overrun the destination tile a little bit, and thus can't take a turn properly
if(player_cnt[i]<=0)
{
if(player_cnt[i]<0) //overrun
{
player_cnt[i]=0;
//0xff is a coordinate mask that leaves only integer tile offeset
//it is 8:4:4 here, where 8 is integer tile coordinate,
//first 4 is offset in the tile, which is 16 pixels wide,
//and second 4 is fixed point resolution
player_x[i]=(player_x[i]&0xff00)+(player_dir[i]==DIR_LEFT?0x100:0);
player_y[i]=(player_y[i]&0xff00)+(player_dir[i]==DIR_UP ?0x100:0);
}
//it is is the player object, check if there is an item in the new tile
if(!i)
{
i16=MAP_ADR((player_x[i]>>(TILE_SIZE_BIT+FP_BITS)),
(player_y[i]>>(TILE_SIZE_BIT+FP_BITS)));
if(map[i16]==TILE_ITEM)
{
map[i16]=TILE_EMPTY; //mark as collected in the game map
sfx_play(SFX_ITEM,2);
++items_collected;
//get address of the tile in the nametable
i16=NAMETABLE_A+0x0080+(((player_y[i]>>(TILE_SIZE_BIT+FP_BITS))-2)<<6)|
((player_x[i]>>(TILE_SIZE_BIT+FP_BITS))<<1);
//replace it with empty tile through the update list
update_list[0]=i16>>8;
update_list[1]=i16&255;
update_list[3]=update_list[0];
update_list[4]=update_list[1]+1;
i16+=32;
update_list[6]=i16>>8;
update_list[7]=i16&255;
update_list[9]=update_list[6];
update_list[10]=update_list[7]+1;
//update number of collected items in the game stats
update_list[14]=0x10+items_collected/100;
update_list[17]=0x10+items_collected/10%10;
update_list[20]=0x10+items_collected%10;
}
}
}
}
if(!player_cnt[i]) //movement to the next tile is done, set up new movement
{
if(!i) //this is the player, process controls
{
//get gamepad state, it was previously polled with pad_trigger
j=pad_state(0);
//this is a tricky part to make controls more predictable
//when you press two directions at once, sliding by a wall
//to take turn into a passage on the side
//this piece of code gives current direction lower priority
//through testing it first
//bits in player_dir var are matching to the buttons bits
if(j&player_dir[0])
{
j&=~player_dir[0]; //remove the direction from further check
player_move(i,player_dir[0]); //change the direction
}
//now continue control processing as usual
if(j&PAD_LEFT) player_move(i,DIR_LEFT);
if(j&PAD_RIGHT) player_move(i,DIR_RIGHT);
if(j&PAD_UP) player_move(i,DIR_UP);
if(j&PAD_DOWN) player_move(i,DIR_DOWN);
}
else //this is an enemy, run AI
{
//the AI is very simple
//first we create list of all directions that are possible to take
//excluding the direction that is opposite to previous one
i16=MAP_ADR((player_x[i]>>8),(player_y[i]>>8));
ptr=player_dir[i];
j=0;
if(ptr!=DIR_RIGHT&&map[i16-1]!=TILE_WALL) dir[j++]=DIR_LEFT;
if(ptr!=DIR_LEFT &&map[i16+1]!=TILE_WALL) dir[j++]=DIR_RIGHT;
if(ptr!=DIR_DOWN &&map[i16-MAP_WDT]!=TILE_WALL) dir[j++]=DIR_UP;
if(ptr!=DIR_UP &&map[i16+MAP_WDT]!=TILE_WALL) dir[j++]=DIR_DOWN;
//randomly select a possible direction
player_move(i,dir[rand8()%j]);
//if there was more than one possible direction,
//i.e. it is a branch and not a corridor,
//attempt to move towards the player
if(j>1)
{
if(ptr!=DIR_DOWN &&player_y[0]<player_y[i]) player_move(i,DIR_UP);
if(ptr!=DIR_UP &&player_y[0]>player_y[i]) player_move(i,DIR_DOWN);
if(ptr!=DIR_RIGHT&&player_x[0]<player_x[i]) player_move(i,DIR_LEFT);
if(ptr!=DIR_LEFT &&player_x[0]>player_x[i]) player_move(i,DIR_RIGHT);
}
}
}
}
}
delay(100);
pal_fade_to(0);
}
//this is where the program starts
extern const void sound_data[];
extern const void music_data[];
void main(void)
{
famitone_init(&music_data);
sfx_init(&sound_data);
nmi_set_callback(famitone_update);
while(1)//infinite loop, title-gameplay
{
title_screen();
game_level=0;
game_lives=4;
while(game_lives&&game_level<LEVELS_ALL)//loop for gameplay
{
show_screen(game_level);
game_loop();
if(game_clear) ++game_level; else --game_lives;
}
show_screen(!game_lives?SCREEN_GAMEOVER:SCREEN_WELLDONE);//show game results
}
}

View File

@ -0,0 +1,8 @@
const unsigned char gameover_nam[81]={
0x01,0x00,0x01,0xfe,0x00,0x01,0x86,0x60,0x61,0x60,0x62,0x63,0x64,0x65,0x66,0x00,
0x60,0x62,0x67,0x68,0x65,0x66,0x65,0x62,0x00,0x97,0x00,0x01,0x0c,0x67,0x6a,0x67,
0x68,0x6b,0x6c,0x65,0x6d,0x00,0x67,0x68,0x67,0x68,0x65,0x6d,0x67,0x6e,0x00,0x98,
0x00,0x01,0x0c,0x6f,0x70,0x65,0x71,0x67,0x68,0x72,0x73,0x00,0x6f,0x74,0x75,0x76,
0x72,0x73,0x65,0x77,0x00,0x99,0x00,0x01,0xfe,0x00,0x01,0xfe,0x00,0x01,0x28,0x01,
0x00
};

View File

@ -0,0 +1,22 @@
const unsigned char level1_nam[305]={
0x01,0x00,0x01,0xfe,0x00,0x01,0x08,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,
0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x0f,0x42,0x43,0x42,0x43,0x42,0x43,
0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,0x01,0x0f,0x40,0x41,0x10,
0x44,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x00,0x01,0x0f,
0x42,0x43,0x44,0x44,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,
0x00,0x01,0x0f,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x45,
0x46,0x40,0x41,0x00,0x01,0x0f,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,
0x42,0x43,0x47,0x48,0x42,0x43,0x00,0x01,0x0f,0x40,0x41,0x45,0x46,0x45,0x46,0x45,
0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x00,0x01,0x0f,0x42,0x43,0x47,0x48,
0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,0x00,0x01,0x0f,0x40,
0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x00,
0x01,0x0f,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x47,0x48,
0x42,0x43,0x00,0x01,0x0f,0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,
0x46,0x11,0x44,0x40,0x41,0x00,0x01,0x0f,0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,
0x47,0x48,0x47,0x48,0x44,0x44,0x42,0x43,0x00,0x01,0x0f,0x40,0x41,0x40,0x41,0x40,
0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x0f,0x42,0x43,
0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,0x01,
0xfe,0x00,0x01,0x1a,0xbd,0xad,0xad,0x6d,0x00,0x01,0x03,0xb9,0xad,0xad,0x6e,0x00,
0x01,0x03,0xb9,0xad,0xad,0x6e,0x00,0x01,0x03,0x0d,0x01,0x03,0x00,0x01,0x11,0x01,
0x00
};

View File

@ -0,0 +1,31 @@
const unsigned char level2_nam[459]={
0x01,0x00,0x01,0xc5,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x42,0x43,0x42,
0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,
0x01,0x0b,0x40,0x41,0x10,0x44,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x45,0x46,
0x45,0x46,0x11,0x44,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x44,0x44,0x47,0x48,0x47,
0x48,0x47,0x48,0x42,0x43,0x47,0x48,0x47,0x48,0x44,0x44,0x42,0x43,0x00,0x01,0x0b,
0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,
0x45,0x46,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,
0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x00,0x01,0x0b,0x40,0x41,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,
0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,0x00,0x01,0x0b,0x40,0x41,0x40,0x41,
0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,
0x00,0x01,0x0b,0x42,0x43,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,
0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x00,0x01,0x0b,0x40,0x41,0x45,0x46,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x00,0x01,
0x0b,0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,
0x48,0x47,0x48,0x42,0x43,0x00,0x01,0x0b,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,
0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x00,0x01,0x0b,0x42,
0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,
0x48,0x42,0x43,0x00,0x01,0x0b,0x40,0x41,0x12,0x44,0x45,0x46,0x45,0x46,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x44,
0x44,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,
0x43,0x00,0x01,0x0b,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x42,0x43,0x42,
0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,
0x01,0xce,0x40,0x70,0x01,0x03,0x30,0x00,0x00,0x4c,0x6a,0xba,0xb9,0xba,0x31,0x00,
0x00,0x4c,0x7a,0x6a,0x01,0x02,0x31,0x00,0x00,0x4c,0x6a,0x01,0x02,0xba,0x31,0x00,
0x00,0x4c,0x7a,0x01,0x03,0x31,0x00,0x01,0x10,0x01,0x00
};

View File

@ -0,0 +1,36 @@
const unsigned char level3_nam[540]={
0x01,0x00,0x01,0xc5,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x42,0x43,0x42,
0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,
0x01,0x0b,0x40,0x41,0x10,0x44,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x45,0x46,
0x45,0x46,0x11,0x44,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x44,0x44,0x47,0x48,0x47,
0x48,0x47,0x48,0x42,0x43,0x47,0x48,0x47,0x48,0x44,0x44,0x42,0x43,0x00,0x01,0x07,
0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,
0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x03,0x42,
0x43,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,
0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,0x00,0x01,0x03,0x40,0x41,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x47,
0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,
0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,0x00,0x01,0x03,0x40,0x41,0x45,0x46,
0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,
0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x47,0x48,0x42,
0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,
0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x00,0x01,0x03,0x40,0x41,0x45,0x46,0x45,0x46,
0x45,0x46,0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x45,0x46,0x45,0x46,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x47,0x48,0x47,0x48,0x47,
0x48,0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,
0x48,0x47,0x48,0x42,0x43,0x00,0x01,0x03,0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,
0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,
0x40,0x41,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x42,0x43,0x42,0x43,0x47,0x48,0x42,
0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,
0x43,0x42,0x43,0x00,0x01,0x07,0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,
0x45,0x46,0x45,0x46,0x45,0x46,0x12,0x44,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x47,
0x48,0x47,0x48,0x47,0x48,0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x44,0x44,0x42,
0x43,0x00,0x01,0x0b,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x0b,0x42,0x43,0x42,0x43,0x42,
0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,
0x01,0xce,0x40,0x70,0x01,0x03,0x30,0x00,0x40,0x7c,0x6a,0xba,0xb9,0xba,0x71,0x30,
0x4c,0x6a,0x01,0x02,0xba,0xb9,0xba,0x31,0x4c,0x7a,0x6e,0x6a,0x6a,0xba,0x7a,0x31,
0x00,0x4c,0x7a,0x7e,0x7a,0x7a,0x31,0x00,0x01,0x10,0x01,0x00
};

View File

@ -0,0 +1,42 @@
const unsigned char level4_nam[640]={
0x02,0x00,0x02,0x85,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,
0x00,0x02,0x13,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,
0x02,0x13,0x40,0x41,0x10,0x44,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x40,0x41,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x02,0x07,0x42,0x43,0x44,
0x44,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,
0x43,0x42,0x43,0x42,0x43,0x00,0x02,0x07,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,
0x45,0x46,0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x11,0x44,0x40,0x41,
0x00,0x02,0x07,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,
0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x44,0x44,0x42,0x43,0x00,0x02,0x03,0x40,0x41,
0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,
0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x00,0x02,0x03,0x42,0x43,0x42,
0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,
0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x00,0x02,0x03,0x40,0x41,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x00,0x02,0x03,0x42,0x43,0x47,0x48,0x47,
0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,
0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x00,0x02,0x03,0x40,0x41,0x45,0x46,0x40,0x41,
0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,
0x40,0x41,0x45,0x46,0x40,0x41,0x00,0x02,0x03,0x42,0x43,0x47,0x48,0x42,0x43,0x47,
0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,
0x43,0x47,0x48,0x42,0x43,0x00,0x02,0x03,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x45,0x46,0x40,0x41,0x00,0x02,0x03,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x47,
0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,
0x48,0x42,0x43,0x00,0x02,0x03,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,
0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,
0x40,0x41,0x00,0x02,0x03,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x47,
0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,
0x43,0x00,0x02,0x03,0x40,0x41,0x12,0x44,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x00,0x02,0x07,0x42,
0x43,0x44,0x44,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,0x47,0x48,0x42,
0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x00,0x02,0x07,0x40,0x41,0x40,0x41,0x40,0x41,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x13,0x44,
0x40,0x41,0x00,0x02,0x07,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,
0x43,0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x44,0x44,0x42,0x43,0x00,0x02,0x13,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x02,0x13,0x42,
0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,0x02,0x8e,0x4c,0xad,
0xad,0x71,0x70,0x70,0x30,0x40,0x7c,0x6e,0xb9,0xb9,0xba,0xba,0x31,0x4c,0x6a,0x02,
0x02,0xba,0xba,0xb9,0x31,0x4c,0x6e,0x6a,0x02,0x02,0xba,0x7a,0x31,0x4c,0x7a,0x7a,
0x7e,0xae,0xa9,0x31,0x00,0x02,0x03,0x0c,0x0d,0x0d,0x01,0x00,0x02,0x08,0x02,0x00
};

View File

@ -0,0 +1,56 @@
const unsigned char level5_nam[851]={
0x01,0x00,0x01,0x83,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,
0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x07,0x42,
0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,
0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,0x01,0x07,0x40,0x41,0x10,0x44,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x11,0x44,
0x40,0x41,0x00,0x01,0x07,0x42,0x43,0x44,0x44,0x47,0x48,0x47,0x48,0x47,0x48,0x47,
0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x44,0x44,0x42,0x43,0x00,0x01,0x03,
0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,
0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,
0x42,0x43,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,
0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,
0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,
0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,
0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,
0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,
0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,
0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,
0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,
0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,
0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,0x47,0x48,
0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,
0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,
0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,
0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,
0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,
0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,
0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,
0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,
0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,
0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,0x45,0x46,0x40,0x41,
0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,
0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,0x47,0x48,0x42,0x43,
0x40,0x41,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,
0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x40,0x41,
0x42,0x43,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,
0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x42,0x43,
0x40,0x41,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,
0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x45,0x46,0x40,0x41,0x40,0x41,0x40,0x41,
0x42,0x43,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,
0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x47,0x48,0x42,0x43,0x42,0x43,0x42,0x43,
0x00,0x01,0x03,0x40,0x41,0x12,0x44,0x45,0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x45,
0x46,0x45,0x46,0x45,0x46,0x45,0x46,0x13,0x44,0x40,0x41,0x00,0x01,0x07,0x42,0x43,
0x44,0x44,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,0x47,0x48,
0x47,0x48,0x44,0x44,0x42,0x43,0x00,0x01,0x07,0x40,0x41,0x40,0x41,0x40,0x41,0x40,
0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,0x41,0x40,
0x41,0x00,0x01,0x07,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,
0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x42,0x43,0x00,0x01,0x0b,0xbd,
0xbd,0xad,0x01,0x03,0x6d,0x6d,0xbd,0xa9,0xad,0xae,0xa9,0xad,0xae,0x6d,0xbd,0xae,
0xae,0xbd,0xae,0x01,0x02,0x6e,0xb9,0xad,0xa9,0xa9,0xb9,0xad,0xa9,0x6d,0xbd,0xae,
0x01,0x02,0xad,0xae,0xae,0x6e,0xbd,0xb9,0xad,0xae,0xa9,0xad,0x6e,0x6d,0x0d,0x01,
0x07,0x01,0x00
};

View File

@ -0,0 +1,6 @@
const unsigned char level_nam[52]={
0x01,0x00,0x01,0xfe,0x00,0x01,0x89,0x67,0x00,0x65,0x66,0x67,0x68,0x65,0x66,0x67,
0x00,0x01,0x16,0x67,0x00,0x65,0x6d,0x67,0x68,0x65,0x6d,0x67,0x00,0x01,0x16,0x72,
0x78,0x72,0x73,0x75,0x76,0x72,0x73,0x72,0x78,0x00,0x01,0xfe,0x00,0x01,0xfe,0x00,
0x01,0x2e,0x01,0x00
};

439
presets/nes/chase/music.s Normal file
View File

@ -0,0 +1,439 @@
;this file for FamiTone2 library generated by text2data tool
.export _music_data
_music_data:
.byte 6
.word @instruments
.word @samples-3
.word @song0ch0,@song0ch1,@song0ch2,@song0ch3,@song0ch4,307,256
.word @song1ch0,@song1ch1,@song1ch2,@song1ch3,@song1ch4,307,256
.word @song2ch0,@song2ch1,@song2ch2,@song2ch3,@song2ch4,307,256
.word @song3ch0,@song3ch1,@song3ch2,@song3ch3,@song3ch4,307,256
.word @song4ch0,@song4ch1,@song4ch2,@song4ch3,@song4ch4,307,256
.word @song5ch0,@song5ch1,@song5ch2,@song5ch3,@song5ch4,307,256
@instruments:
.byte $30 ;instrument $00
.word @env1,@env0,@env11
.byte $00
.byte $30 ;instrument $01
.word @env2,@env0,@env0
.byte $00
.byte $70 ;instrument $02
.word @env3,@env6,@env0
.byte $00
.byte $70 ;instrument $03
.word @env3,@env6,@env10
.byte $00
.byte $30 ;instrument $04
.word @env1,@env7,@env0
.byte $00
.byte $30 ;instrument $05
.word @env4,@env0,@env0
.byte $00
.byte $30 ;instrument $06
.word @env3,@env8,@env0
.byte $00
.byte $30 ;instrument $07
.word @env3,@env8,@env10
.byte $00
.byte $30 ;instrument $08
.word @env5,@env9,@env0
.byte $00
@samples:
@env0:
.byte $c0,$00,$00
@env1:
.byte $cf,$00,$00
@env2:
.byte $c7,$c5,$c4,$c3,$c3,$c2,$06,$c1,$0a,$c0,$00,$09
@env3:
.byte $c6,$c6,$c5,$c4,$c3,$09,$c2,$08,$c1,$0f,$c0,$00,$0a
@env4:
.byte $c8,$c3,$c2,$c1,$02,$c0,$00,$05
@env5:
.byte $c5,$c5,$c4,$c4,$c3,$c0,$00,$05
@env6:
.byte $c0,$c0,$c5,$c5,$c7,$c7,$00,$00
@env7:
.byte $c6,$c3,$c0,$00,$02
@env8:
.byte $c0,$02,$c4,$02,$c7,$c7,$c7,$00,$00
@env9:
.byte $c6,$c6,$c0,$00,$02
@env10:
.byte $c4,$00,$00
@env11:
.byte $c0,$0b,$c1,$c2,$c3,$c4,$c3,$c2,$c1,$c0,$00,$02
@song0ch0:
.byte $fb,$03
@ref0:
.byte $8c,$33,$33,$36,$95
@song0ch0loop:
@ref1:
.byte $9f
.byte $fd
.word @song0ch0loop
@song0ch1:
@ref2:
.byte $8e,$33,$33,$36,$95
@song0ch1loop:
@ref3:
.byte $9f
.byte $fd
.word @song0ch1loop
@song0ch2:
@ref4:
.byte $80,$33,$33,$90,$32,$80,$36,$83,$00,$8d
@song0ch2loop:
@ref5:
.byte $9f
.byte $fd
.word @song0ch2loop
@song0ch3:
@ref6:
.byte $8a,$1f,$1f,$90,$17,$82,$1e,$91
@song0ch3loop:
@ref7:
.byte $9f
.byte $fd
.word @song0ch3loop
@song0ch4:
@ref8:
.byte $9f
@song0ch4loop:
@ref9:
.byte $9f
.byte $fd
.word @song0ch4loop
@song1ch0:
.byte $fb,$04
@song1ch0loop:
@ref10:
.byte $9f
@ref11:
.byte $9f
@ref12:
.byte $9f
@ref13:
.byte $9f
@ref14:
.byte $9f
@ref15:
.byte $9f
@ref16:
.byte $9f
@ref17:
.byte $9f
.byte $fd
.word @song1ch0loop
@song1ch1:
@song1ch1loop:
@ref18:
.byte $9f
@ref19:
.byte $9f
@ref20:
.byte $9f
@ref21:
.byte $9f
@ref22:
.byte $9f
@ref23:
.byte $9f
@ref24:
.byte $9f
@ref25:
.byte $9f
.byte $fd
.word @song1ch1loop
@song1ch2:
@song1ch2loop:
@ref26:
.byte $80,$28,$00,$83,$28,$00,$27,$90,$32,$00,$8b
@ref27:
.byte $80,$24,$00,$83,$25,$23,$90,$32,$00,$8b
@ref28:
.byte $80,$28,$00,$83,$82,$28,$00,$27,$90,$32,$00,$83,$80,$26,$00,$83
@ref29:
.byte $24,$00,$83,$25,$90,$32,$80,$22,$83,$00,$89
@ref30:
.byte $28,$00,$83,$28,$00,$27,$90,$32,$00,$83,$80,$26,$00,$83
@ref31:
.byte $24,$00,$83,$25,$23,$90,$32,$00,$8b
@ref32:
.byte $80,$1e,$00,$83,$1e,$00,$23,$90,$32,$00,$83,$80,$25,$90,$32,$80
.byte $28
@ref33:
.byte $87,$00,$95
.byte $fd
.word @song1ch2loop
@song1ch3:
@song1ch3loop:
@ref34:
.byte $8a,$1f,$1f,$82,$1f,$8a,$1f,$90,$16,$85,$82,$1f,$8a,$1e,$81
@ref35:
.byte $83,$1f,$82,$1f,$8a,$1f,$90,$16,$85,$8a,$1e,$85
@ref36:
.byte $1f,$1f,$82,$1f,$8a,$1f,$90,$16,$85,$82,$1f,$8a,$1e,$81
@ref37:
.byte $83,$1f,$82,$1f,$90,$16,$89,$8a,$1f,$1e,$81
.byte $ff,$09
.word @ref36
.byte $ff,$08
.word @ref35
@ref40:
.byte $1f,$1f,$82,$1f,$8a,$1f,$90,$16,$85,$17,$16,$81
@ref41:
.byte $87,$8a,$1f,$1f,$82,$1e,$85,$8a,$1f,$1e,$81
.byte $fd
.word @song1ch3loop
@song1ch4:
@song1ch4loop:
@ref42:
.byte $9f
@ref43:
.byte $9f
@ref44:
.byte $9f
@ref45:
.byte $9f
@ref46:
.byte $9f
@ref47:
.byte $9f
@ref48:
.byte $9f
@ref49:
.byte $9f
.byte $fd
.word @song1ch4loop
@song2ch0:
.byte $fb,$03
@ref50:
.byte $84,$3d,$3d,$3c,$85,$3d,$3d,$40,$a5
@song2ch0loop:
@ref51:
.byte $bf
.byte $fd
.word @song2ch0loop
@song2ch1:
@ref52:
.byte $86,$3d,$3d,$3c,$85,$3d,$3d,$40,$a5
@song2ch1loop:
@ref53:
.byte $bf
.byte $fd
.word @song2ch1loop
@song2ch2:
@ref54:
.byte $80,$3c,$00,$3c,$00,$3c,$00,$83,$3c,$00,$3c,$00,$88,$40,$8f,$00
.byte $93
@song2ch2loop:
@ref55:
.byte $bf
.byte $fd
.word @song2ch2loop
@song2ch3:
@ref56:
.byte $8a,$1f,$1f,$82,$1e,$85,$8a,$1f,$1f,$90,$17,$82,$1e,$a1
@song2ch3loop:
@ref57:
.byte $bf
.byte $fd
.word @song2ch3loop
@song2ch4:
@ref58:
.byte $bf
@song2ch4loop:
@ref59:
.byte $bf
.byte $fd
.word @song2ch4loop
@song3ch0:
.byte $fb,$06
@ref60:
.byte $84,$24,$24,$83,$22,$22,$83,$20,$20,$83,$1f,$1a,$89,$32,$95
@song3ch0loop:
@ref61:
.byte $bf
.byte $fd
.word @song3ch0loop
@song3ch1:
@ref62:
.byte $86,$24,$24,$83,$22,$22,$83,$20,$20,$83,$1f,$1a,$89,$32,$85,$32
.byte $8d
@song3ch1loop:
@ref63:
.byte $bf
.byte $fd
.word @song3ch1loop
@song3ch2:
@ref64:
.byte $80,$25,$01,$23,$01,$21,$01,$1f,$1a,$85,$01,$88,$32,$89,$00,$89
@song3ch2loop:
@ref65:
.byte $bf
.byte $fd
.word @song3ch2loop
@song3ch3:
@ref66:
.byte $82,$1f,$8a,$1f,$82,$1d,$8a,$1f,$82,$1b,$8a,$1f,$82,$1b,$18,$89
.byte $90,$17,$82,$1e,$91
@song3ch3loop:
@ref67:
.byte $bf
.byte $fd
.word @song3ch3loop
@song3ch4:
@ref68:
.byte $bf
@song3ch4loop:
@ref69:
.byte $bf
.byte $fd
.word @song3ch4loop
@song4ch0:
.byte $fb,$04
@song4ch0loop:
@ref70:
.byte $84,$28,$8d,$8c,$40,$89,$40,$89,$40,$8d,$84,$28,$85
@ref71:
.byte $24,$8d,$8c,$3c,$89,$3c,$89,$3c,$8d,$84,$24,$85
@ref72:
.byte $28,$8d,$8c,$40,$89,$40,$89,$40,$8d,$84,$28,$85
@ref73:
.byte $1a,$8d,$8c,$32,$89,$36,$89,$36,$95
.byte $fd
.word @song4ch0loop
@song4ch1:
@song4ch1loop:
@ref74:
.byte $86,$28,$8d,$8e,$40,$89,$40,$89,$40,$8d,$86,$28,$85
@ref75:
.byte $24,$8d,$8e,$3c,$89,$3c,$89,$3c,$8d,$86,$24,$85
@ref76:
.byte $28,$8d,$8e,$40,$89,$40,$89,$40,$8d,$86,$28,$85
@ref77:
.byte $1a,$8d,$8e,$32,$89,$36,$89,$36,$95
.byte $fd
.word @song4ch1loop
@song4ch2:
@song4ch2loop:
@ref78:
.byte $80,$28,$87,$00,$26,$00,$88,$29,$00,$85,$80,$29,$01,$29,$01,$26
.byte $00,$88,$29,$01,$80,$29,$22,$81
@ref79:
.byte $24,$87,$00,$22,$00,$88,$25,$00,$85,$80,$25,$01,$25,$01,$22,$00
.byte $25,$01,$25,$22,$81
@ref80:
.byte $28,$87,$00,$26,$00,$88,$29,$00,$85,$80,$29,$01,$29,$01,$26,$00
.byte $88,$29,$01,$80,$29,$00,$81
@ref81:
.byte $32,$87,$00,$30,$00,$33,$00,$85,$37,$01,$37,$01,$34,$00,$88,$37
.byte $01,$1f,$1e,$81
.byte $fd
.word @song4ch2loop
@song4ch3:
@song4ch3loop:
@ref82:
.byte $8a,$1f,$1f,$82,$1f,$8a,$1f,$90,$17,$8a,$1f,$1f,$1f,$82,$1f,$8a
.byte $1f,$1f,$1f,$90,$17,$8a,$1f,$82,$1e,$85
.byte $ff,$10
.word @ref82
.byte $ff,$10
.word @ref82
@ref85:
.byte $8a,$1f,$1f,$82,$1f,$8a,$1f,$90,$17,$8a,$1f,$1f,$1f,$82,$1f,$8a
.byte $1f,$1f,$1f,$90,$16,$85,$17,$16,$81
.byte $fd
.word @song4ch3loop
@song4ch4:
@song4ch4loop:
@ref86:
.byte $bf
@ref87:
.byte $bf
@ref88:
.byte $bf
@ref89:
.byte $bf
.byte $fd
.word @song4ch4loop
@song5ch0:
.byte $fb,$03
@ref90:
.byte $84,$32,$8d,$2c,$85,$28,$a5
@song5ch0loop:
@ref91:
.byte $bf
.byte $fd
.word @song5ch0loop
@song5ch1:
@ref92:
.byte $86,$32,$8d,$2c,$85,$28,$a5
@song5ch1loop:
@ref93:
.byte $bf
.byte $fd
.word @song5ch1loop
@song5ch2:
@ref94:
.byte $88,$32,$85,$00,$85,$80,$2c,$85,$88,$2a,$95,$00,$8d
@song5ch2loop:
@ref95:
.byte $bf
.byte $fd
.word @song5ch2loop
@song5ch3:
@ref96:
.byte $90,$16,$85,$8a,$1f,$1f,$1e,$85,$90,$16,$a5
@song5ch3loop:
@ref97:
.byte $bf
.byte $fd
.word @song5ch3loop
@song5ch4:
@ref98:
.byte $bf
@song5ch4loop:
@ref99:
.byte $bf
.byte $fd
.word @song5ch4loop

View File

@ -0,0 +1,58 @@
;this file for FamiTone2 libary generated by nsf2data tool
.export _sound_data
_sound_data:
.word @ntsc
.word @pal
@ntsc:
.word @sfx_ntsc_0
.word @sfx_ntsc_1
.word @sfx_ntsc_2
.word @sfx_ntsc_3
@pal:
.word @sfx_pal_0
.word @sfx_pal_1
.word @sfx_pal_2
.word @sfx_pal_3
@sfx_ntsc_0:
.byte $80,$7f,$81,$ab,$82,$01,$04,$81,$3f,$04,$81,$1c,$04,$81,$d5,$82
.byte $00,$04,$81,$9f,$04,$81,$8e,$04,$80,$74,$81,$ab,$82,$01,$04,$81
.byte $3f,$04,$81,$1c,$04,$81,$d5,$82,$00,$04,$81,$9f,$04,$81,$8e,$04
.byte $80,$71,$81,$ab,$82,$01,$04,$81,$3f,$04,$81,$1c,$04,$81,$d5,$82
.byte $00,$04,$81,$9f,$04,$81,$8e,$04,$00
@sfx_pal_0:
.byte $80,$7f,$81,$8c,$82,$01,$04,$81,$29,$03,$81,$08,$03,$81,$c6,$82
.byte $00,$04,$81,$94,$03,$81,$84,$03,$80,$74,$81,$8c,$82,$01,$04,$81
.byte $29,$03,$81,$08,$03,$81,$c6,$82,$00,$04,$81,$94,$03,$81,$84,$03
.byte $80,$71,$81,$8c,$82,$01,$04,$81,$29,$03,$81,$08,$03,$81,$c6,$82
.byte $00,$04,$81,$94,$03,$81,$84,$03,$00
@sfx_ntsc_1:
.byte $80,$3f,$81,$ab,$82,$01,$01,$81,$3f,$01,$81,$2d,$01,$81,$1c,$01
.byte $80,$32,$81,$ab,$01,$81,$3f,$01,$81,$2d,$01,$81,$1c,$01,$00
@sfx_pal_1:
.byte $80,$3f,$81,$8c,$82,$01,$01,$81,$29,$01,$81,$18,$01,$81,$08,$01
.byte $80,$32,$81,$8c,$01,$81,$29,$01,$81,$18,$01,$81,$08,$01,$00
@sfx_ntsc_2:
.byte $80,$38,$81,$34,$82,$00,$01,$80,$3a,$81,$27,$01,$80,$3c,$81,$23
.byte $01,$80,$3e,$81,$34,$01,$80,$3f,$81,$27,$01,$81,$23,$01,$81,$34
.byte $01,$81,$27,$01,$80,$32,$81,$23,$01,$81,$34,$01,$81,$27,$01,$81
.byte $23,$01,$81,$34,$01,$81,$27,$01,$81,$23,$01,$81,$34,$01,$81,$27
.byte $01,$81,$23,$01,$81,$34,$01,$81,$27,$01,$81,$23,$01,$00
@sfx_pal_2:
.byte $80,$38,$81,$31,$82,$00,$01,$80,$3a,$81,$24,$01,$80,$3c,$81,$20
.byte $01,$80,$3e,$81,$31,$01,$80,$3f,$81,$24,$01,$81,$20,$01,$81,$31
.byte $01,$81,$24,$01,$80,$32,$81,$20,$01,$81,$31,$01,$81,$24,$01,$81
.byte $20,$01,$81,$31,$01,$81,$24,$01,$81,$20,$01,$81,$31,$01,$81,$24
.byte $01,$81,$20,$01,$81,$31,$01,$81,$24,$01,$81,$20,$01,$00
@sfx_ntsc_3:
.byte $83,$38,$84,$46,$85,$00,$01,$83,$3a,$84,$42,$01,$83,$3c,$84,$5e
.byte $01,$83,$3e,$84,$46,$01,$83,$3f,$84,$42,$01,$84,$5e,$01,$84,$46
.byte $01,$84,$42,$01,$83,$32,$84,$5e,$01,$84,$46,$01,$84,$42,$01,$84
.byte $5e,$01,$84,$46,$01,$84,$42,$01,$84,$5e,$01,$84,$46,$01,$84,$42
.byte $01,$84,$5e,$01,$84,$46,$01,$84,$42,$01,$84,$5e,$01,$00
@sfx_pal_3:
.byte $83,$38,$84,$41,$85,$00,$01,$83,$3a,$84,$3e,$01,$83,$3c,$84,$57
.byte $01,$83,$3e,$84,$41,$01,$83,$3f,$84,$3e,$01,$84,$57,$01,$84,$41
.byte $01,$84,$3e,$01,$83,$32,$84,$57,$01,$84,$41,$01,$84,$3e,$01,$84
.byte $57,$01,$84,$41,$01,$84,$3e,$01,$84,$57,$01,$84,$41,$01,$84,$3e
.byte $01,$84,$57,$01,$84,$41,$01,$84,$3e,$01,$84,$57,$01,$00

Binary file not shown.

View File

@ -0,0 +1,2 @@
.segment "CHARS"
.incbin "tileset.chr"

View File

@ -0,0 +1,26 @@
const unsigned char title_nam[380]={
0x01,0x00,0x01,0x85,0x40,0x41,0x00,0x00,0x40,0x41,0x00,0x01,0x05,0x40,0x41,0x40,
0x41,0x40,0x41,0x00,0x01,0x07,0x40,0x41,0x40,0x41,0x40,0x41,0x42,0x43,0x00,0x00,
0x42,0x43,0x40,0x41,0x40,0x41,0x40,0x41,0x42,0x43,0x42,0x43,0x42,0x43,0x40,0x41,
0x40,0x41,0x40,0x41,0x00,0x00,0x42,0x43,0x42,0x43,0x42,0x43,0x40,0x41,0x00,0x00,
0x40,0x41,0x42,0x43,0x42,0x43,0x42,0x43,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x42,
0x43,0x42,0x43,0x00,0x00,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x00,0x00,0x42,0x43,
0x40,0x41,0x00,0x00,0x40,0x41,0x42,0x43,0x00,0x01,0x03,0x40,0x41,0x00,0x01,0x05,
0x42,0x43,0x00,0x01,0x03,0x40,0x41,0x40,0x41,0x40,0x41,0x42,0x43,0x00,0x00,0x42,
0x43,0x40,0x41,0x40,0x41,0x40,0x41,0x42,0x43,0x00,0x01,0x05,0x40,0x41,0x00,0x01,
0x03,0x42,0x43,0x42,0x43,0x42,0x43,0x40,0x41,0x00,0x00,0x40,0x41,0x42,0x43,0x42,
0x43,0x42,0x43,0x40,0x41,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x00,0x01,0x03,0x40,
0x41,0x00,0x00,0x40,0x41,0x42,0x43,0x00,0x00,0x42,0x43,0x00,0x01,0x03,0x40,0x41,
0x42,0x43,0x42,0x43,0x00,0x01,0x03,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x00,0x00,
0x42,0x43,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x01,0x03,0x42,0x43,0x40,0x41,0x00,
0x01,0x05,0x42,0x43,0x00,0x01,0x03,0x40,0x41,0x00,0x00,0x40,0x41,0x42,0x43,0x42,
0x43,0x42,0x43,0x40,0x41,0x40,0x41,0x40,0x41,0x42,0x43,0x00,0x01,0x05,0x40,0x41,
0x40,0x41,0x40,0x41,0x42,0x43,0x00,0x00,0x42,0x43,0x40,0x41,0x00,0x00,0x40,0x41,
0x42,0x43,0x42,0x43,0x42,0x43,0x40,0x41,0x40,0x41,0x40,0x41,0x00,0x00,0x42,0x43,
0x42,0x43,0x42,0x43,0x00,0x01,0x05,0x42,0x43,0x00,0x00,0x42,0x43,0x00,0x01,0x05,
0x42,0x43,0x42,0x43,0x42,0x43,0x00,0x01,0xaa,0x30,0x32,0x25,0x33,0x33,0x00,0x00,
0x33,0x34,0x21,0x32,0x34,0x00,0x01,0x93,0x30,0x24,0x12,0x10,0x11,0x12,0x00,0x33,
0x28,0x29,0x32,0x35,0x00,0x01,0x8a,0x55,0x01,0x08,0x99,0xaa,0xff,0xbb,0xaa,0x55,
0x01,0x02,0x99,0xaa,0xff,0xbb,0xaa,0x55,0x01,0x02,0x99,0xaa,0xff,0xbb,0xaa,0x55,
0x55,0x00,0x01,0x0f,0xaa,0x01,0x07,0x0a,0x01,0x07,0x01,0x00
};

View File

@ -0,0 +1,9 @@
const unsigned char welldone_nam[106]={
0x02,0x00,0x02,0xfe,0x00,0x02,0x86,0x67,0x68,0x65,0x66,0x67,0x00,0x67,0x00,0x00,
0x65,0x62,0x60,0x62,0x63,0x79,0x65,0x66,0x00,0x97,0x00,0x02,0x0c,0x82,0x83,0x65,
0x6d,0x67,0x00,0x67,0x00,0x00,0x67,0x68,0x67,0x68,0x84,0x85,0x65,0x6d,0x00,0x98,
0x00,0x02,0x0c,0x8e,0x8f,0x72,0x73,0x72,0x78,0x72,0x78,0x00,0x72,0x74,0x6f,0x74,
0x67,0x68,0x72,0x73,0x00,0x99,0x00,0x02,0x2c,0x21,0x2c,0x2c,0x00,0x27,0x25,0x2d,
0x33,0x00,0x23,0x2f,0x2c,0x2c,0x25,0x23,0x34,0x25,0x24,0x01,0x00,0x02,0xfe,0x00,
0x02,0xc7,0x55,0x02,0x17,0x00,0x02,0x07,0x02,0x00
};

View File

@ -31,11 +31,8 @@ var _qs = (function (a) {
function installErrorHandler() { function installErrorHandler() {
if (typeof window.onerror == "object") { if (typeof window.onerror == "object") {
window.onerror = function (msgevent, url, line, col, error) { window.onerror = function (msgevent, url, line, col, error) {
ga('send', 'exception', { var msg = msgevent + " " + url + " " + " " + line + ":" + col + ", " + error;
'exDescription': msgevent + " " + url + " " + " " + line + ":" + col + ", " + error, $.get("/error?msg=" + encodeURIComponent(msg), "text");
'exFatal': true
});
//alert(msgevent+"");
}; };
} }
} }

View File

@ -38,6 +38,7 @@ const JSNES_PRESETS = [
{id:'xyscroll.asm', name:'XY Split Scrolling (ASM)'}, {id:'xyscroll.asm', name:'XY Split Scrolling (ASM)'},
{id:'scrollrt.asm', name:'Line-by-line Scrolling (ASM)'}, {id:'scrollrt.asm', name:'Line-by-line Scrolling (ASM)'},
{id:'road.asm', name:'3-D Road Demo (ASM)'}, {id:'road.asm', name:'3-D Road Demo (ASM)'},
{id:'chase/game.c', name:'Shiru\'s Chase Game'},
]; ];
/// JSNES /// JSNES

View File

@ -2,6 +2,7 @@
import { FileData, Dependency, SourceLine, SourceFile, CodeListing, CodeListingMap, WorkerError, Segment, WorkerResult } from "./workertypes"; import { FileData, Dependency, SourceLine, SourceFile, CodeListing, CodeListingMap, WorkerError, Segment, WorkerResult } from "./workertypes";
import { getFilenamePrefix, getFolderForPath, isProbablyBinary } from "./util"; import { getFilenamePrefix, getFolderForPath, isProbablyBinary } from "./util";
import { Platform } from "./baseplatform";
type BuildResultCallback = (result:WorkerResult) => void; type BuildResultCallback = (result:WorkerResult) => void;
type BuildStatusCallback = (busy:boolean) => void; type BuildStatusCallback = (busy:boolean) => void;
@ -20,8 +21,8 @@ export class CodeProject {
callbackBuildStatus : BuildStatusCallback; callbackBuildStatus : BuildStatusCallback;
worker : Worker; worker : Worker;
platform_id : string; platform_id : string;
platform: any; // TODO: use type platform : Platform;
store: any; store : any;
callbackGetRemote : GetRemoteCallback; callbackGetRemote : GetRemoteCallback;
mainPath : string; mainPath : string;
isCompiling : boolean = false; isCompiling : boolean = false;
@ -329,12 +330,9 @@ export class CodeProject {
} }
stripLocalPath(path : string) : string { stripLocalPath(path : string) : string {
// TODO: strip main path as well var folder = getFolderForPath(this.mainPath);
if (path.startsWith('local/')) { if (folder != '' && path.startsWith(folder)) {
path = path.substring(6); path = path.substring(folder.length+1);
}
if (path.startsWith('share/')) {
path = path.substring(6);
} }
return path; return path;
} }

221
src/ui.ts
View File

@ -12,11 +12,11 @@ import { PLATFORMS, EmuHalt, Toolbar } from "./emu";
import * as Views from "./views"; import * as Views from "./views";
import { createNewPersistentStore } from "./store"; import { createNewPersistentStore } from "./store";
import { getFilenameForPath, getFilenamePrefix, highlightDifferences, invertMap, byteArrayToString, compressLZG, import { getFilenameForPath, getFilenamePrefix, highlightDifferences, invertMap, byteArrayToString, compressLZG,
byteArrayToUTF8, isProbablyBinary, getWithBinary } from "./util"; byteArrayToUTF8, isProbablyBinary, getWithBinary, stringToByteArray } from "./util";
import { StateRecorderImpl } from "./recorder"; import { StateRecorderImpl } from "./recorder";
// external libs (TODO) // external libs (TODO)
declare var ga, Tour, GIF, saveAs, JSZip, Mousetrap, Split; declare var Tour, GIF, saveAs, JSZip, Mousetrap, Split, GitHub;
// in index.html // in index.html
declare var exports; declare var exports;
@ -42,7 +42,6 @@ var userPaused : boolean; // did user explicitly pause?
var current_output : WorkerOutput; // current ROM var current_output : WorkerOutput; // current ROM
var current_preset_entry : Preset; // current preset object (if selected) var current_preset_entry : Preset; // current preset object (if selected)
var main_file_id : string; // main file ID
var store; // persistent store var store; // persistent store
export var compparams; // received build params from worker export var compparams; // received build params from worker
@ -89,9 +88,9 @@ var hasLocalStorage : boolean = function() {
function getCurrentPresetTitle() : string { function getCurrentPresetTitle() : string {
if (!current_preset_entry) if (!current_preset_entry)
return main_file_id || "ROM"; return current_project.mainPath || "ROM";
else else
return current_preset_entry.title || current_preset_entry.name || main_file_id || "ROM"; return current_preset_entry.title || current_preset_entry.name || current_project.mainPath || "ROM";
} }
function setLastPreset(id:string) { function setLastPreset(id:string) {
@ -149,7 +148,7 @@ function refreshWindowList() {
ul.append(li); ul.append(li);
if (createfn) { if (createfn) {
projectWindows.setCreateFunc(id, createfn); projectWindows.setCreateFunc(id, createfn);
$(a).click(function(e) { $(a).click( (e) => {
projectWindows.createOrShow(id); projectWindows.createOrShow(id);
ul.find('a').removeClass("dropdown-item-checked"); ul.find('a').removeClass("dropdown-item-checked");
ul.find(e.target).addClass("dropdown-item-checked"); ul.find(e.target).addClass("dropdown-item-checked");
@ -172,11 +171,11 @@ function refreshWindowList() {
} }
// add main file editor // add main file editor
addEditorItem(main_file_id); addEditorItem(current_project.mainPath);
// add other source files // add other source files
current_project.iterateFiles(function(id, text) { current_project.iterateFiles( (id, text) => {
if (text && id != main_file_id) if (text && id != current_project.mainPath)
addEditorItem(id); addEditorItem(id);
}); });
@ -199,31 +198,31 @@ function refreshWindowList() {
// add other tools // add other tools
separate = true; separate = true;
if (platform.disassemble) { if (platform.disassemble) {
addWindowItem("#disasm", "Disassembly", function() { addWindowItem("#disasm", "Disassembly", () => {
return new Views.DisassemblerView(); return new Views.DisassemblerView();
}); });
} }
if (platform.readAddress) { if (platform.readAddress) {
addWindowItem("#memory", "Memory Browser", function() { addWindowItem("#memory", "Memory Browser", () => {
return new Views.MemoryView(); return new Views.MemoryView();
}); });
} }
if (platform.readVRAMAddress) { if (platform.readVRAMAddress) {
addWindowItem("#memvram", "VRAM Browser", function() { addWindowItem("#memvram", "VRAM Browser", () => {
return new Views.VRAMMemoryView(); return new Views.VRAMMemoryView();
}); });
} }
if (current_project.segments) { if (current_project.segments) {
addWindowItem("#memmap", "Memory Map", function() { addWindowItem("#memmap", "Memory Map", () => {
return new Views.MemoryMapView(); return new Views.MemoryMapView();
}); });
} }
if (platform.startProfiling && platform.runEval && platform.getRasterScanline) { if (platform.startProfiling && platform.runEval && platform.getRasterScanline) {
addWindowItem("#profiler", "Profiler", function() { addWindowItem("#profiler", "Profiler", () => {
return new Views.ProfileView(); return new Views.ProfileView();
}); });
} }
addWindowItem('#asseteditor', 'Asset Editor', function() { addWindowItem('#asseteditor', 'Asset Editor', () => {
return new Views.AssetEditorView(); return new Views.AssetEditorView();
}); });
} }
@ -241,9 +240,8 @@ function loadProject(preset_id:string) {
preset_id = current_preset_entry.id; preset_id = current_preset_entry.id;
} }
// set current file ID // set current file ID
main_file_id = preset_id;
setLastPreset(preset_id);
current_project.mainPath = preset_id; current_project.mainPath = preset_id;
setLastPreset(preset_id);
// load files from storage or web URLs // load files from storage or web URLs
current_project.loadFiles([preset_id], function(err, result) { current_project.loadFiles([preset_id], function(err, result) {
if (err) { if (err) {
@ -271,7 +269,7 @@ function getSkeletonFile(fileid:string, callback) {
$.get( "presets/"+platform_id+"/skeleton."+ext, function( text ) { $.get( "presets/"+platform_id+"/skeleton."+ext, function( text ) {
callback(null, text); callback(null, text);
}, 'text') }, 'text')
.fail(function() { .fail(() => {
alert("Could not load skeleton for " + platform_id + "/" + ext + "; using blank file"); alert("Could not load skeleton for " + platform_id + "/" + ext + "; using blank file");
callback(null, '\n'); callback(null, '\n');
}); });
@ -339,6 +337,7 @@ function handleFileUpload(files: File[]) {
data = byteArrayToUTF8(data).replace('\r\n','\n'); // convert CRLF to LF data = byteArrayToUTF8(data).replace('\r\n','\n'); // convert CRLF to LF
} }
// store in local forage // store in local forage
// TODO: use projectWindows uploadFile()
store.setItem(path, data, function(err, result) { store.setItem(path, data, function(err, result) {
if (err) if (err)
alert("Error uploading " + path + ": " + err); alert("Error uploading " + path + ": " + err);
@ -358,32 +357,110 @@ function handleFileUpload(files: File[]) {
} }
function getCurrentMainFilename() : string { function getCurrentMainFilename() : string {
return getFilenameForPath(main_file_id); return getFilenameForPath(current_project.mainPath);
} }
function getCurrentEditorFilename() : string { function getCurrentEditorFilename() : string {
return getFilenameForPath(projectWindows.getActiveID()); return getFilenameForPath(projectWindows.getActiveID());
} }
function _shareFileAsGist(e) { // GITHUB stuff (TODO: move)
var gisturl_ta = $("#embedGistURL");
var shareurl_ta = $("#embedGistShareURL"); function _importProjectFromGithub(e) {
loadClipboardLibrary(); var githuburl_ta = $("#importGithubURL");
gisturl_ta.change(() => { var modal = $("#importGithubModal");
var gisturl = gisturl_ta.val() + ''; var btn = $("#importGithubButton");
var pos = gisturl.lastIndexOf('/'); modal.modal('show');
if (pos >= 0) { btn.off('click').on('click', () => {
var gistkey = gisturl.substring(pos+1); importFromGithub(githuburl_ta.val());
var embed = {
platform: platform_id,
gistkey: gistkey
};
var linkqs = $.param(embed);
var fulllink = get8bitworkshopLink(linkqs, 'redir.html');
shareurl_ta.val(fulllink);
}
}); });
$("#embedGistModal").modal('show'); }
function _connectProjectToGithub(e) {
var githuburl_ta = $("#connectGithubURL");
var modal = $("#connectGithubModal");
var btn = $("#connectGithubButton");
modal.modal('show');
btn.off('click').on('click', () => {
connectToGithub(githuburl_ta.val());
});
}
function parseGithubURL(ghurl) {
var toks = ghurl.split('/');
console.log(toks)
if (toks.length < 5) return null;
if (toks[0] != 'https:') return null;
if (toks[2] != 'github.com') return null;
return {user:toks[3], repo:toks[4]};
}
function getGithubRepo(ghurl, callback) {
var urlparse = parseGithubURL(ghurl);
if (!urlparse) {
alert("Please enter a valid GitHub URL.");
return;
}
loadScript("lib/octokat.js", () => {
var github = new exports['Octokat']();
var prefix = 'shared/' + urlparse.user + '-' + urlparse.repo + '/';
var repo = github.repos(urlparse.user, urlparse.repo);
callback(github, repo, prefix);
});
}
function importFromGithub(ghurl) {
getGithubRepo(ghurl, (github, repo, prefix) => {
repo.commits('master').fetch().then( (sha) => {
repo.git.trees(sha.sha).fetch().then( (tree) => {
tree.tree.forEach( (item) => {
console.log(item);
if (item.type == 'blob') {
repo.git.blobs(item.sha).readBinary().then( (blob) => {
var path = prefix + item.path;
var size = item.size;
var isBinary = isProbablyBinary(blob);
var data = isBinary ? stringToByteArray(blob) : blob; //byteArrayToUTF8(blob);
// TODO projectWindows.updateFile(path, data);
store.setItem(path, data);
// TODO; wait for set?
console.log(path, size, isBinary, typeof blob);
// TODO: redirect to main file?
});
}
});
});
});
});
}
function connectToGithub(ghurl) {
getGithubRepo(ghurl, (github, repo, prefix) => {
// TODO
});
}
function loadSharedGist(gistkey : string) {
loadScript("lib/octokat.js", () => {
var github = new exports['Octokat']();
var gist = github.gists(gistkey);
gist.fetch().done( (val) => {
var filename;
var newid;
console.log("Fetched " + gistkey, val);
store = createNewPersistentStore(platform_id, (store) => {
for (filename in val.files) {
store.setItem('shared/'+filename, val.files[filename].content);
if (!newid) newid = 'shared/'+filename;
}
// TODO: wait for set?
delete qs['gistkey'];
reloadPresetNamed(newid);
});
}).fail(function(err) {
alert("Error loading share file: " + err.message);
});
});
} }
function _shareEmbedLink(e) { function _shareEmbedLink(e) {
@ -403,7 +480,7 @@ function _shareEmbedLink(e) {
var lzgb64 = btoa(byteArrayToString(lzgrom)); var lzgb64 = btoa(byteArrayToString(lzgrom));
var embed = { var embed = {
p: platform_id, p: platform_id,
//n: main_file_id, //n: current_project.mainPath,
r: lzgb64 r: lzgb64
}; };
var linkqs = $.param(embed); var linkqs = $.param(embed);
@ -486,7 +563,7 @@ function _revertFile(e) {
wnd.setText(text); wnd.setText(text);
} }
}, 'text') }, 'text')
.fail(function() { .fail(() => {
// TODO: delete file // TODO: delete file
alert("Can only revert built-in files."); alert("Can only revert built-in files.");
}); });
@ -499,7 +576,7 @@ function _deleteFile(e) {
var wnd = projectWindows.getActive(); var wnd = projectWindows.getActive();
if (wnd && wnd.getPath) { if (wnd && wnd.getPath) {
var fn = projectWindows.getActiveID(); var fn = projectWindows.getActiveID();
if (fn.startsWith("local/")) { if (fn.startsWith("local/") || fn.startsWith("shared/")) {
if (confirm("Delete '" + fn + "'?")) { if (confirm("Delete '" + fn + "'?")) {
store.removeItem(fn, () => { store.removeItem(fn, () => {
// if we delete what is selected // if we delete what is selected
@ -532,7 +609,7 @@ function _renameFile(e) {
store.setItem(newfn, data, () => { store.setItem(newfn, data, () => {
alert("Renamed " + fn + " to " + newfn); alert("Renamed " + fn + " to " + newfn);
updateSelector(); updateSelector();
if (fn == main_file_id) { if (fn == current_project.mainPath) {
reloadPresetNamed(newfn); reloadPresetNamed(newfn);
} }
}); });
@ -608,7 +685,7 @@ function populateExamples(sel) {
for (var i=0; i<PRESETS.length; i++) { for (var i=0; i<PRESETS.length; i++) {
var preset = PRESETS[i]; var preset = PRESETS[i];
var name = preset.chapter ? (preset.chapter + ". " + preset.name) : preset.name; var name = preset.chapter ? (preset.chapter + ". " + preset.name) : preset.name;
sel.append($("<option />").val(preset.id).text(name).attr('selected',(preset.id==main_file_id)?'selected':null)); sel.append($("<option />").val(preset.id).text(name).attr('selected',(preset.id==current_project.mainPath)?'selected':null));
} }
// don't create new entry if example not found // don't create new entry if example not found
}); });
@ -625,13 +702,13 @@ function populateFiles(sel:JQuery, category:string, prefix:string, callback:() =
if (numFound++ == 0) if (numFound++ == 0)
sel.append($("<option />").text("------- " + category + " -------").attr('disabled','true')); sel.append($("<option />").text("------- " + category + " -------").attr('disabled','true'));
var name = key.substring(prefix.length); var name = key.substring(prefix.length);
sel.append($("<option />").val(key).text(name).attr('selected',(key==main_file_id)?'selected':null)); sel.append($("<option />").val(key).text(name).attr('selected',(key==current_project.mainPath)?'selected':null));
if (key == main_file_id) foundSelected = true; if (key == current_project.mainPath) foundSelected = true;
} }
} }
// create new entry if not found, but it matches our prefix // create new entry if not found, but it matches our prefix
if (!foundSelected && main_file_id && main_file_id.startsWith(prefix)) { if (!foundSelected && current_project.mainPath && current_project.mainPath.startsWith(prefix)) {
var name = main_file_id.substring(prefix.length); var name = current_project.mainPath.substring(prefix.length);
var key = prefix + name; var key = prefix + name;
sel.append($("<option />").val(key).text(name).attr('selected','true')); sel.append($("<option />").val(key).text(name).attr('selected','true'));
} }
@ -936,7 +1013,6 @@ function _recordVideo() {
rotate: rotate rotate: rotate
}); });
var img = $('#videoPreviewImage'); var img = $('#videoPreviewImage');
//img.attr('src', 'https://articulate-heroes.s3.amazonaws.com/uploads/rte/kgrtehja_DancingBannana.gif');
gif.on('finished', function(blob) { gif.on('finished', function(blob) {
img.attr('src', URL.createObjectURL(blob)); img.attr('src', URL.createObjectURL(blob));
setWaitDialog(false); setWaitDialog(false);
@ -948,7 +1024,7 @@ function _recordVideo() {
var nframes = 0; var nframes = 0;
console.log("Recording video", canvas); console.log("Recording video", canvas);
$("#emulator").css('backgroundColor', '#cc3333'); $("#emulator").css('backgroundColor', '#cc3333');
var f = function() { var f = () => {
if (nframes++ > maxFrames) { if (nframes++ > maxFrames) {
console.log("Rendering video"); console.log("Rendering video");
$("#emulator").css('backgroundColor', 'inherit'); $("#emulator").css('backgroundColor', 'inherit');
@ -1039,7 +1115,7 @@ function _toggleRecording() {
function _lookupHelp() { function _lookupHelp() {
if (platform.showHelp) { if (platform.showHelp) {
let tool = platform.getToolForFilename(main_file_id); let tool = platform.getToolForFilename(current_project.mainPath);
platform.showHelp(tool); // TODO: tool, identifier platform.showHelp(tool); // TODO: tool, identifier
} }
} }
@ -1121,7 +1197,8 @@ function setupDebugControls() {
$(".dropdown-menu").collapse({toggle: false}); $(".dropdown-menu").collapse({toggle: false});
$("#item_new_file").click(_createNewFile); $("#item_new_file").click(_createNewFile);
$("#item_upload_file").click(_uploadNewFile); $("#item_upload_file").click(_uploadNewFile);
$("#item_share_github").click(_shareFileAsGist); $("#item_github_import").click(_importProjectFromGithub);
$("#item_github_connect").click(_connectProjectToGithub);
$("#item_share_file").click(_shareEmbedLink); $("#item_share_file").click(_shareEmbedLink);
$("#item_reset_file").click(_revertFile); $("#item_reset_file").click(_revertFile);
$("#item_rename_file").click(_renameFile); $("#item_rename_file").click(_renameFile);
@ -1274,7 +1351,7 @@ function showWelcomeMessage() {
//storage:false, //storage:false,
steps:steps steps:steps
}); });
setTimeout(function() { tour.start(); }, 2000); setTimeout(() => { tour.start(); }, 2000);
} }
} }
@ -1305,10 +1382,8 @@ function installErrorHandler() {
uiDebugCallback(platform.saveState()); uiDebugCallback(platform.saveState());
setDebugButtonState("pause", "stopped"); // TODO? setDebugButtonState("pause", "stopped"); // TODO?
} else { } else {
ga('send', 'exception', { var msg = msgevent + " " + url + " " + " " + line + ":" + col + ", " + error;
'exDescription': msgevent + " " + url + " " + " " + line + ":" + col + ", " + error, $.get("/error?msg=" + encodeURIComponent(msg), "text");
'exFatal': true
});
alert(msgevent+""); alert(msgevent+"");
} }
_pause(); _pause();
@ -1332,7 +1407,7 @@ function replaceURLState() {
function addPageFocusHandlers() { function addPageFocusHandlers() {
var hidden = false; var hidden = false;
document.addEventListener("visibilitychange", function() { document.addEventListener("visibilitychange", () => {
if (document.visibilityState == 'hidden' && platform.isRunning()) { if (document.visibilityState == 'hidden' && platform.isRunning()) {
_pause(); _pause();
hidden = true; hidden = true;
@ -1341,13 +1416,13 @@ function addPageFocusHandlers() {
hidden = false; hidden = false;
} }
}); });
$(window).on("focus", function() { $(window).on("focus", () => {
if (hidden) { if (hidden) {
_resume(); _resume();
hidden = false; hidden = false;
} }
}); });
$(window).on("blur", function() { $(window).on("blur", () => {
if (platform.isRunning()) { if (platform.isRunning()) {
_pause(); _pause();
hidden = true; hidden = true;
@ -1380,29 +1455,6 @@ function startPlatform() {
return true; return true;
} }
function loadSharedGist(gistkey : string) {
loadScript("octokat.js/dist/octokat.js", () => {
var github = new exports['Octokat']();
var gist = github.gists(gistkey);
gist.fetch().done(function(val) {
var filename;
var newid;
console.log("Fetched " + gistkey, val);
store = createNewPersistentStore(platform_id, (store) => {
for (filename in val.files) {
store.setItem('shared/'+filename, val.files[filename].content);
if (!newid) newid = 'shared/'+filename;
}
// TODO: wait for set?
delete qs['gistkey'];
reloadPresetNamed(newid);
});
}).fail(function(err) {
alert("Error loading share file: " + err.message);
});
});
}
function loadScript(scriptfn, onload, onerror?) { function loadScript(scriptfn, onload, onerror?) {
var script = document.createElement('script'); var script = document.createElement('script');
script.onload = onload; script.onload = onload;
@ -1485,6 +1537,11 @@ export function startUI(loadplatform : boolean) {
else { else {
// create store for platform // create store for platform
store = createNewPersistentStore(platform_id, (store) => { store = createNewPersistentStore(platform_id, (store) => {
// is this an importURL?
if (qs['githubURL']) {
importFromGithub(qs['githubURL']);
return;
}
// is this an importURL? // is this an importURL?
if (qs['importURL']) { if (qs['importURL']) {
loadImportedURL(qs['importURL']); loadImportedURL(qs['importURL']);
@ -1506,7 +1563,7 @@ function loadAndStartPlatform() {
console.log("loaded platform", platform_id); console.log("loaded platform", platform_id);
startPlatform(); startPlatform();
showWelcomeMessage(); showWelcomeMessage();
document.title = document.title + " [" + platform_id + "] - " + main_file_id; document.title = document.title + " [" + platform_id + "] - " + current_project.mainPath;
}, () => { }, () => {
alert('Platform "' + platform_id + '" not supported.'); alert('Platform "' + platform_id + '" not supported.');
}); });

View File

@ -1195,7 +1195,7 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
// rle-compressed? TODO // rle-compressed? TODO
if (frag.fmt.comp == 'rletag') { if (frag.fmt.comp == 'rletag') {
//node = node.addRight(new pixed.Compressor()); //node = node.addRight(new pixed.Compressor());
continue; continue; // TODO
} }
// is this a nes nametable? // is this a nes nametable?
if (frag.fmt.map == 'nesnt') { if (frag.fmt.map == 'nesnt') {