nes: added road, tint demo; extra tools; embed.html fetch remote url
This commit is contained in:
parent
0e47e7d035
commit
fe1e0fc9aa
|
@ -103,6 +103,7 @@ TODO:
|
|||
- per-View keyboard shortcuts
|
||||
- parse labels
|
||||
- parse .incbin directives?
|
||||
- can't replace in hex directives
|
||||
- crt0.s compiled each time?
|
||||
- debug highlight doesn't go away when debugging -> running
|
||||
- show breakpoint of PC or highest address on stack
|
||||
|
@ -124,6 +125,7 @@ TODO:
|
|||
- CPU debugging
|
||||
- disassemble more code around breakpoint
|
||||
- single-stepping vector games makes screen fade
|
||||
- break on stack overflow, bad op, bad access, etc
|
||||
|
||||
WEB WORKER FORMAT
|
||||
|
||||
|
|
|
@ -83,6 +83,14 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<a tabindex="-1" href="#">Tools</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" target="_8bws_tools" href="./tools/fontgen/">Bitmap Font Generator</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_tools" href="http://tomeko.net/online_tools/file_to_hex.php?lang=en">Binary File to Hex Converter</a></li>
|
||||
<li class="dropdown dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Atari 2600/VCS</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" target="_8bws_tools" href="https://alienbill.com/2600/playerpalnext.html">playerpal 2600</a></li>
|
||||
<li><a class="dropdown-item" target="_8bws_tools" href="https://alienbill.com/2600/playfieldpal.html">playfieldpal 2600</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<hr>
|
||||
|
|
|
@ -26,10 +26,10 @@ Start:
|
|||
lda #$1c ; $1C = light blue color
|
||||
sta PPU_DATA ; $1C -> PPU data
|
||||
; activate PPU graphics
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_COLOR
|
||||
sta PPU_MASK ; enable rendering
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
.endless
|
||||
jmp .endless ; endless loop
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@ Start:
|
|||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL ; PPU scroll = $0000
|
||||
; activate PPU graphics
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_BG
|
||||
sta PPU_MASK ; enable rendering
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
.endless
|
||||
jmp .endless ; endless loop
|
||||
|
||||
|
|
|
@ -30,10 +30,10 @@ Start:
|
|||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL ; scroll = $0000
|
||||
; activate PPU graphics
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_BG
|
||||
sta PPU_MASK ; enable rendering
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
.endless
|
||||
jmp .endless ; endless loop
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ Start:
|
|||
sta PPU_ADDR ;PPU addr = 0
|
||||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL ;scroll = 0
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_BG|MASK_SPR
|
||||
sta PPU_MASK ; enable rendering
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
.endless
|
||||
jmp .endless ;endless loop
|
||||
|
||||
|
|
|
@ -29,10 +29,10 @@ Start:
|
|||
sta PPU_ADDR ;PPU addr = 0
|
||||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL ;scroll = 0
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_BG|MASK_SPR
|
||||
sta PPU_MASK ; enable rendering
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
.endless
|
||||
jmp .endless ;endless loop
|
||||
|
||||
|
|
|
@ -287,6 +287,10 @@ void __fastcall__ nmi_set_callback(void (*callback)(void));
|
|||
#define MASK_BG 0x08
|
||||
#define MASK_EDGE_SPR 0x04
|
||||
#define MASK_EDGE_BG 0x02
|
||||
#define MASK_TINT_RED 0x20
|
||||
#define MASK_TINT_BLUE 0x40
|
||||
#define MASK_TINT_GREEN 0x80
|
||||
#define MASK_MONO 0x01
|
||||
|
||||
#define NAMETABLE_A 0x2000
|
||||
#define NAMETABLE_B 0x2400
|
||||
|
|
|
@ -12,8 +12,6 @@ extern const byte climbr_title_rle[];
|
|||
|
||||
// link title screen palette and RLE nametable
|
||||
//#link "climbr_title.s"
|
||||
|
||||
|
||||
void fade_in() {
|
||||
byte vb;
|
||||
for (vb=0; vb<=4; vb++) {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
seg.u ZEROPAGE
|
||||
org $0
|
||||
|
||||
Ptr1 .word ; for temporary pointer storage
|
||||
|
||||
TrackFrac .byte ; fractional position along track
|
||||
Speed .byte ; speed of car
|
||||
|
@ -24,9 +26,8 @@ ZOfs .byte ; counter to draw striped center line
|
|||
Weather .byte ; bitmask for weather
|
||||
Heading .word ; sky scroll pos.
|
||||
|
||||
XCenter = 128
|
||||
NumRoadSegments = 28
|
||||
|
||||
NumRoadScanlines = 112
|
||||
NumRoadSegments = 56
|
||||
; Preprocessing result: X positions for all track segments
|
||||
RoadX0 ds NumRoadSegments
|
||||
|
||||
|
@ -43,7 +44,7 @@ InitialSpeed equ 10 ; starting speed
|
|||
|
||||
;;;;; NES CARTRIDGE HEADER
|
||||
|
||||
NES_HEADER 0,2,1,0 ; mapper 0, 2 PRGs, 1 CHR, horiz. mirror
|
||||
NES_HEADER 0,2,1,1 ; mapper 0, 2 PRGs, 1 CHR, vert mirror
|
||||
|
||||
;;;;; START OF CODE
|
||||
|
||||
|
@ -53,7 +54,6 @@ Start:
|
|||
jsr ClearRAM ; clear RAM
|
||||
jsr WaitSync ; wait for VSYNC (and PPU warmup)
|
||||
|
||||
jsr SetPalette ; set palette colors
|
||||
jsr FillVRAM ; set PPU video RAM
|
||||
|
||||
jsr RoadSetup
|
||||
|
@ -63,10 +63,10 @@ Start:
|
|||
sta PPU_ADDR ; PPU addr = $0000
|
||||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL ; scroll = $0000
|
||||
lda #MASK_BG|MASK_SPR|MASK_BG_CLIP
|
||||
sta PPU_MASK ; enable rendering (first!)
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_BG|MASK_SPR
|
||||
sta PPU_MASK ; enable rendering
|
||||
|
||||
.endless
|
||||
jmp .endless ; endless loop
|
||||
|
@ -249,43 +249,43 @@ GenTrack subroutine
|
|||
|
||||
; fill video RAM
|
||||
FillVRAM: subroutine
|
||||
txa
|
||||
ldy #$20
|
||||
sty PPU_ADDR
|
||||
sta PPU_ADDR
|
||||
ldy #$10
|
||||
PPU_SETADDR $2000
|
||||
lda #<RoadTables
|
||||
sta Ptr1
|
||||
lda #>RoadTables
|
||||
sta Ptr1+1
|
||||
ldx #8
|
||||
ldy #0
|
||||
.loop:
|
||||
lda (Ptr1),y
|
||||
sta PPU_DATA
|
||||
adc #7
|
||||
inx
|
||||
iny
|
||||
bne .loop
|
||||
dey
|
||||
inc Ptr1+1
|
||||
dex
|
||||
bne .loop
|
||||
rts
|
||||
|
||||
; set palette colors
|
||||
SetPalette: subroutine
|
||||
ldy #$00
|
||||
lda #$3f
|
||||
sta PPU_ADDR
|
||||
sty PPU_ADDR
|
||||
ldx #32
|
||||
PPU_SETADDR $3f00
|
||||
ldx #16
|
||||
.loop:
|
||||
lda Palette,y
|
||||
sta PPU_DATA
|
||||
iny
|
||||
dex
|
||||
dex
|
||||
bne .loop
|
||||
rts
|
||||
|
||||
; set sprite 0
|
||||
SetSprite0: subroutine
|
||||
sta $200 ;y
|
||||
lda #1 ;code
|
||||
sta $200 ;ypos
|
||||
lda #$00 ;code
|
||||
sta $201
|
||||
lda #0 ;flags
|
||||
lda #$20 ;flags
|
||||
sta $202
|
||||
lda #8 ;xpos
|
||||
lda #$fe ;xpos
|
||||
sta $203
|
||||
rts
|
||||
|
||||
|
@ -314,18 +314,26 @@ SetSprite0: subroutine
|
|||
ENDM
|
||||
|
||||
NMIHandler: subroutine
|
||||
; save registers
|
||||
SAVE_REGS
|
||||
; setup sky scroll
|
||||
lda Heading+1
|
||||
sta PPU_SCROLL
|
||||
lda #0
|
||||
sta PPU_SCROLL
|
||||
; load sprites
|
||||
lda #112
|
||||
; cycle palette colors
|
||||
lda TPos ; track position
|
||||
lsr ; / 2
|
||||
and #16 ; now either 0 or 16
|
||||
tay ; Y is palette offset
|
||||
jsr SetPalette ; call SetPalette
|
||||
PPU_SETADDR $2000 ; reset PPU address
|
||||
; load sprite zero
|
||||
lda #109
|
||||
jsr SetSprite0
|
||||
lda #$02
|
||||
sta PPU_OAM_DMA
|
||||
; do road calc
|
||||
; setup sky scroll
|
||||
lda Heading+1
|
||||
sta PPU_SCROLL ; X scroll
|
||||
lda #0
|
||||
sta PPU_SCROLL ; Y scroll = 0
|
||||
; do road calculations
|
||||
jsr RoadPreSetup
|
||||
jsr PreprocessCurve
|
||||
jsr RoadPostFrame
|
||||
|
@ -337,30 +345,42 @@ NMIHandler: subroutine
|
|||
; alter horiz. scroll position for each scanline
|
||||
ldy #0
|
||||
.loop
|
||||
; pad out rest of scanline
|
||||
SLEEP 78
|
||||
; change scroll register
|
||||
tya
|
||||
lsr
|
||||
lsr
|
||||
lsr ; / 2
|
||||
tax
|
||||
lda RoadX0,x
|
||||
lda RoadX0,x ; get X offset of scanline
|
||||
eor #$80 ; + 128
|
||||
sta PPU_SCROLL ; horiz byte
|
||||
lda #0
|
||||
sta PPU_SCROLL ; vert byte
|
||||
SLEEP 84
|
||||
sta PPU_SCROLL ; vert byte = 0
|
||||
; take extra cycle every 4th line
|
||||
tya
|
||||
and #3
|
||||
bne .skipcyc
|
||||
.skipcyc
|
||||
; next loop iteration
|
||||
iny
|
||||
cpy #112
|
||||
bne .loop
|
||||
cpy #NumRoadScanlines
|
||||
bne .loop ; do next scanline
|
||||
; restore registers and return from interrupt
|
||||
RESTORE_REGS
|
||||
rti
|
||||
|
||||
;;;;; CONSTANT DATA
|
||||
|
||||
align $100
|
||||
;;{pal:"nes",layout:"nes"};;
|
||||
Palette:
|
||||
hex 1f ;background
|
||||
hex 09092c00 ;bg0
|
||||
hex 09091900 ;bg1
|
||||
hex 09091500 ;bg2
|
||||
hex 09092500 ;bg3
|
||||
hex 0F3F06300F19063F0F1916063F180801
|
||||
hex 0F30163F0F19163F0F1906160F180801
|
||||
;;
|
||||
RoadTables:
|
||||
incbin "road/nametable.dat"
|
||||
incbin "road/attribute.dat"
|
||||
incbin "road/nametable1.dat"
|
||||
incbin "road/attribute1.dat"
|
||||
|
||||
;;;;; CPU VECTORS
|
||||
|
||||
|
@ -369,4 +389,4 @@ Palette:
|
|||
;;;;; TILE SETS
|
||||
|
||||
org $10000
|
||||
incbin "jroatch.chr"
|
||||
incbin "road/road.chr"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,6 +5,8 @@
|
|||
|
||||
seg.u ZEROPAGE
|
||||
org $0
|
||||
|
||||
SkipY ds 1
|
||||
|
||||
;;;;; OTHER VARIABLES
|
||||
|
||||
|
@ -34,10 +36,10 @@ Start:
|
|||
sta PPU_ADDR ; PPU addr = $0000
|
||||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL ; scroll = $0000
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_BG|MASK_SPR
|
||||
sta PPU_MASK ; enable rendering
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
.endless
|
||||
jmp .endless ; endless loop
|
||||
|
||||
|
@ -69,7 +71,7 @@ SetPalette: subroutine
|
|||
; set sprite 0
|
||||
SetSprite0: subroutine
|
||||
sta $200 ;y
|
||||
lda #$01 ;code
|
||||
lda #$a0 ;code
|
||||
sta $201
|
||||
lda #$20 ;flags
|
||||
sta $202
|
||||
|
@ -100,6 +102,13 @@ NMIHandler: subroutine
|
|||
bvc .wait1
|
||||
ldy #0
|
||||
.loop
|
||||
; take out cycle every 4th line
|
||||
tya
|
||||
and #3
|
||||
bne .skipcyc ; clks = 2/3/3/3
|
||||
.skipcyc
|
||||
; pad out rest of scanline
|
||||
SLEEP 65
|
||||
; alter horiz. scroll position for each scanline
|
||||
tya
|
||||
sec
|
||||
|
@ -111,10 +120,9 @@ NMIHandler: subroutine
|
|||
sta PPU_SCROLL ; horiz byte
|
||||
lda #0
|
||||
sta PPU_SCROLL ; vert byte
|
||||
; pad out rest of scanline
|
||||
SLEEP 72
|
||||
; next iteration of loop
|
||||
iny
|
||||
cpy #224
|
||||
cpy #112
|
||||
bne .loop
|
||||
RESTORE_REGS
|
||||
rti
|
||||
|
|
|
@ -1,16 +1,45 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// include NESLIB header
|
||||
#include "neslib.h"
|
||||
|
||||
// link the pattern table into CHR ROM
|
||||
//#link "chr_generic.s"
|
||||
|
||||
/*{pal:"nes",layout:"nes"}*/
|
||||
const char PALETTE[32] = {
|
||||
0x03, // screen color
|
||||
|
||||
0x11,0x30,0x27,0x0, // background palette 0
|
||||
0x1c,0x20,0x2c,0x0, // background palette 1
|
||||
0x00,0x10,0x20,0x0, // background palette 2
|
||||
0x06,0x16,0x26,0x0, // background palette 3
|
||||
|
||||
0x16,0x35,0x24,0x0, // sprite palette 0
|
||||
0x00,0x37,0x25,0x0, // sprite palette 1
|
||||
0x0d,0x2d,0x3a,0x0, // sprite palette 2
|
||||
0x0d,0x27,0x2a // sprite palette 3
|
||||
};
|
||||
|
||||
// setup PPU and tables
|
||||
void setup_graphics() {
|
||||
// clear sprites
|
||||
oam_clear();
|
||||
// set palette colors
|
||||
pal_all(PALETTE);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
pal_col(1,0x04);
|
||||
pal_col(2,0x20);
|
||||
pal_col(3,0x30);
|
||||
setup_graphics();
|
||||
// draw message
|
||||
vram_adr(NTADR_A(2,2));
|
||||
vram_write("HELLO, WORLD!", 12);
|
||||
ppu_on_all();//enable rendering
|
||||
while(1);//do nothing, infinite loop
|
||||
// enable rendering
|
||||
ppu_on_all();
|
||||
// infinite loop
|
||||
while(1) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// include NESLIB header
|
||||
#include "neslib.h"
|
||||
|
||||
// link the pattern table into CHR ROM
|
||||
//#link "chr_generic.s"
|
||||
|
||||
/*{pal:"nes",layout:"nes"}*/
|
||||
const char PALETTE[32] = {
|
||||
0x2D, // screen color
|
||||
|
||||
0x00,0x30,0x30,0x00, // background palette 0
|
||||
0x0C,0x20,0x2C,0x00, // background palette 1
|
||||
0x14,0x10,0x25,0x00, // background palette 2
|
||||
0x17,0x16,0x28,0x00, // background palette 3
|
||||
|
||||
0x16,0x35,0x24,0x00, // sprite palette 0
|
||||
0x00,0x37,0x25,0x00, // sprite palette 1
|
||||
0x0D,0x2D,0x3A,0x00, // sprite palette 2
|
||||
0x0D,0x27,0x2A // sprite palette 3
|
||||
};
|
||||
|
||||
// setup PPU and tables
|
||||
void setup_graphics() {
|
||||
// clear sprites
|
||||
oam_clear();
|
||||
// set palette colors
|
||||
pal_all(PALETTE);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
byte i;
|
||||
setup_graphics();
|
||||
// draw message
|
||||
for (i=0; i<30; i++) {
|
||||
vram_adr(NTADR_A(1,i));
|
||||
// vram_write("\x18\x18 USE CONTROLLER FOR TINT \x18\x18\x18", 30);
|
||||
vram_write(" A:red B:green \x1e\x1f:blue \x1c\x1d:mono", 30);
|
||||
}
|
||||
// attributes
|
||||
vram_adr(0x23c0);
|
||||
vram_fill(0x00, 8);
|
||||
vram_fill(0x55, 8);
|
||||
vram_fill(0xaa, 8);
|
||||
vram_fill(0xff, 8);
|
||||
vram_fill(0x11, 8);
|
||||
vram_fill(0x33, 8);
|
||||
vram_fill(0xdd, 8);
|
||||
// enable rendering
|
||||
ppu_on_all();
|
||||
// infinite loop
|
||||
while(1) {
|
||||
byte pad = pad_poll(0);
|
||||
byte mask = MASK_BG;
|
||||
if (pad & PAD_A)
|
||||
mask |= MASK_TINT_RED;
|
||||
if (pad & PAD_B)
|
||||
mask |= MASK_TINT_GREEN;
|
||||
if (pad & (PAD_LEFT|PAD_RIGHT))
|
||||
mask |= MASK_TINT_BLUE;
|
||||
if (pad & (PAD_UP|PAD_DOWN))
|
||||
mask |= MASK_MONO;
|
||||
ppu_mask(mask);
|
||||
}
|
||||
}
|
|
@ -34,10 +34,10 @@ Start:
|
|||
sta PPU_ADDR ; PPU addr = $0000
|
||||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL ; scroll = $0000
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
lda #MASK_BG|MASK_SPR
|
||||
sta PPU_MASK ; enable rendering
|
||||
lda #CTRL_NMI
|
||||
sta PPU_CTRL ; enable NMI
|
||||
.endless
|
||||
jmp .endless ; endless loop
|
||||
|
||||
|
@ -93,26 +93,26 @@ NMIHandler: subroutine
|
|||
; load sprites
|
||||
lda #$02
|
||||
sta PPU_OAM_DMA
|
||||
; wait for sprite 0
|
||||
.wait0 bit PPU_STATUS
|
||||
bvs .wait0
|
||||
.wait1 bit PPU_STATUS
|
||||
bvc .wait1
|
||||
; set XY scroll
|
||||
; compute first PPU_ADDR write
|
||||
; compute second PPU_ADDR write
|
||||
lda ScrollX
|
||||
tax
|
||||
tax ; ScrollX -> X
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
sta Temp
|
||||
lda ScrollY
|
||||
tay
|
||||
and #$f8
|
||||
tay ; ScrollY -> Y
|
||||
and #$38
|
||||
asl
|
||||
asl
|
||||
ora Temp
|
||||
pha
|
||||
ora Temp ; (ScrollX >> 3) | ((ScrollY & 0x38) << 2)
|
||||
pha ; push onto stack
|
||||
; wait for sprite 0
|
||||
.wait0 bit PPU_STATUS
|
||||
bvs .wait0
|
||||
.wait1 bit PPU_STATUS
|
||||
bvc .wait1
|
||||
; set PPU_ADDR.1
|
||||
lda #0
|
||||
sta PPU_ADDR
|
||||
|
|
|
@ -3,7 +3,7 @@ window['Javatari'].AUTO_START = false;
|
|||
|
||||
import { PLATFORMS } from "./emu";
|
||||
import { Platform } from "./baseplatform";
|
||||
import { stringToByteArray } from "./util";
|
||||
import { stringToByteArray, getWithBinary } from "./util";
|
||||
|
||||
export var platform_id : string; // platform ID string
|
||||
export var platform : Platform; // platform object
|
||||
|
@ -67,17 +67,37 @@ function addPageFocusHandlers() {
|
|||
});
|
||||
}
|
||||
|
||||
function startROM(title, rom) {
|
||||
if (!rom ) {
|
||||
alert("No ROM found.");
|
||||
return;
|
||||
}
|
||||
console.log(rom.length + ' bytes');
|
||||
platform.loadROM(title, rom);
|
||||
platform.resume();
|
||||
}
|
||||
|
||||
function startPlatform(qs) {
|
||||
if (!PLATFORMS[platform_id]) throw Error("Invalid platform '" + platform_id + "'.");
|
||||
platform = new PLATFORMS[platform_id]($("#emulator")[0]);
|
||||
platform.start();
|
||||
var title = qs['n'] || 'Game';
|
||||
var rom : Uint8Array;
|
||||
var romurl = qs['url'];
|
||||
var lzgvar = qs['r'];
|
||||
var lzgrom = stringToByteArray(atob(lzgvar));
|
||||
var rom = new lzgmini().decode(lzgrom);
|
||||
console.log(rom.length + ' bytes');
|
||||
platform.loadROM(title, rom);
|
||||
platform.resume();
|
||||
if (romurl) {
|
||||
// load rom url remotely
|
||||
console.log(romurl);
|
||||
getWithBinary(romurl, (data) => {
|
||||
startROM(title, data);
|
||||
}, 'arraybuffer');
|
||||
return true;
|
||||
} else if (lzgvar) {
|
||||
// decompress from lzg
|
||||
var lzgrom = stringToByteArray(atob(lzgvar));
|
||||
rom = new lzgmini().decode(lzgrom);
|
||||
}
|
||||
startROM(title, rom);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ const JSNES_PRESETS = [
|
|||
{id:'metasprites.c', name:'Metasprites'},
|
||||
{id:'flicker.c', name:'Flickering Sprites'},
|
||||
{id:'metacursor.c', name:'Controllers'},
|
||||
{id:'tint.c', name:'Color Emphasis'},
|
||||
{id:'rletitle.c', name:'Title Screen RLE'},
|
||||
{id:'statusbar.c', name:'Split Status Bar'},
|
||||
{id:'horizmask.c', name:'Offscreen Scrolling'},
|
||||
|
@ -34,8 +35,9 @@ const JSNES_PRESETS = [
|
|||
{id:'ex3.asm', name:'Sprite Demo (ASM)'},
|
||||
{id:'ex4.asm', name:'Controller Demo (ASM)'},
|
||||
{id:'musicdemo.asm', name:'Famitone Demo (ASM)'},
|
||||
{id:'scrollrt.asm', name:'Line-by-line Scrolling (ASM)'},
|
||||
{id:'xyscroll.asm', name:'XY Split Scrolling (ASM)'},
|
||||
{id:'scrollrt.asm', name:'Line-by-line Scrolling (ASM)'},
|
||||
{id:'road.asm', name:'3-D Road Demo (ASM)'},
|
||||
];
|
||||
|
||||
/// JSNES
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
import { FileData, Dependency, SourceLine, SourceFile, CodeListing, CodeListingMap, WorkerError, Segment, WorkerResult } from "./workertypes";
|
||||
import { getFilenameForPath, getFilenamePrefix, getFolderForPath, isProbablyBinary } from "./util";
|
||||
import { getFilenamePrefix, getFolderForPath, isProbablyBinary } from "./util";
|
||||
|
||||
type BuildResultCallback = (result:WorkerResult) => void;
|
||||
type BuildStatusCallback = (busy:boolean) => void;
|
||||
|
@ -153,7 +153,7 @@ export class CodeProject {
|
|||
this.preloadWorker(this.mainpath);
|
||||
var msg = {updates:[], buildsteps:[]};
|
||||
// TODO: add preproc directive for __MAINFILE__
|
||||
var mainfilename = getFilenameForPath(this.mainpath);
|
||||
var mainfilename = this.stripLocalPath(this.mainpath);
|
||||
var maintext = this.getFile(this.mainpath);
|
||||
var depfiles = [];
|
||||
msg.updates.push({path:mainfilename, data:maintext});
|
||||
|
@ -177,10 +177,10 @@ export class CodeProject {
|
|||
// TODO: get local file as well as presets?
|
||||
loadFiles(paths:string[], callback:LoadFilesCallback) {
|
||||
var result : Dependency[] = [];
|
||||
function addResult(path, data) {
|
||||
var addResult = (path, data) => {
|
||||
result.push({
|
||||
path:path,
|
||||
filename:getFilenameForPath(path),
|
||||
filename:this.stripLocalPath(path),
|
||||
link:true,
|
||||
data:data
|
||||
});
|
||||
|
@ -319,7 +319,7 @@ export class CodeProject {
|
|||
|
||||
// returns first listing in format [prefix].lst (TODO: could be better)
|
||||
getListingForFile(path) : CodeListing {
|
||||
var fnprefix = getFilenamePrefix(getFilenameForPath(path));
|
||||
var fnprefix = getFilenamePrefix(this.stripLocalPath(path));
|
||||
var listings = this.getListings();
|
||||
for (var lstfn in listings) {
|
||||
if (getFilenamePrefix(lstfn) == fnprefix) {
|
||||
|
@ -327,4 +327,15 @@ export class CodeProject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
stripLocalPath(path : string) : string {
|
||||
// TODO: strip main path as well
|
||||
if (path.startsWith('local/')) {
|
||||
path = path.substring(6);
|
||||
}
|
||||
if (path.startsWith('share/')) {
|
||||
path = path.substring(6);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
|
18
src/ui.ts
18
src/ui.ts
|
@ -12,7 +12,7 @@ import { PLATFORMS, EmuHalt, Toolbar } from "./emu";
|
|||
import * as Views from "./views";
|
||||
import { createNewPersistentStore } from "./store";
|
||||
import { getFilenameForPath, getFilenamePrefix, highlightDifferences, invertMap, byteArrayToString, compressLZG,
|
||||
byteArrayToUTF8, isProbablyBinary } from "./util";
|
||||
byteArrayToUTF8, isProbablyBinary, getWithBinary } from "./util";
|
||||
import { StateRecorderImpl } from "./recorder";
|
||||
|
||||
// external libs (TODO)
|
||||
|
@ -101,22 +101,6 @@ function setLastPreset(id:string) {
|
|||
}
|
||||
}
|
||||
|
||||
// firefox doesn't do GET with binary files
|
||||
function getWithBinary(url:string, success:(text:FileData)=>void, datatype:'text'|'arraybuffer') {
|
||||
var oReq = new XMLHttpRequest();
|
||||
oReq.open("GET", url, true);
|
||||
oReq.responseType = datatype;
|
||||
oReq.onload = function (oEvent) {
|
||||
if (oReq.status == 200)
|
||||
success(oReq.response);
|
||||
else if (oReq.status == 404)
|
||||
success(null);
|
||||
else
|
||||
throw "Error " + oReq.status + " loading " + url;
|
||||
}
|
||||
oReq.send(null);
|
||||
}
|
||||
|
||||
function initProject() {
|
||||
current_project = new CodeProject(newWorker(), platform_id, platform, store);
|
||||
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
|
||||
|
|
24
src/util.ts
24
src/util.ts
|
@ -320,7 +320,7 @@ export function isProbablyBinary(path:string, data?:number[] | Uint8Array) : boo
|
|||
// check extensions
|
||||
if (path) {
|
||||
path = path.toUpperCase();
|
||||
const BINEXTS = ['.CHR','.BIN','.PAL','.NAM','.RLE','.LZ4'];
|
||||
const BINEXTS = ['.CHR','.BIN','.DAT','.PAL','.NAM','.RLE','.LZ4'];
|
||||
for (var ext of BINEXTS) {
|
||||
if (path.endsWith(ext)) score++;
|
||||
}
|
||||
|
@ -446,3 +446,25 @@ export function rle_unpack(src : Uint8Array) : Uint8Array {
|
|||
}
|
||||
return new Uint8Array(dest);
|
||||
}
|
||||
|
||||
// firefox doesn't do GET with binary files
|
||||
export function getWithBinary(url:string, success:(text:string|Uint8Array)=>void, datatype:'text'|'arraybuffer') {
|
||||
var oReq = new XMLHttpRequest();
|
||||
oReq.open("GET", url, true);
|
||||
oReq.responseType = datatype;
|
||||
oReq.onload = function (oEvent) {
|
||||
if (oReq.status == 200) {
|
||||
var data = oReq.response;
|
||||
if (data instanceof ArrayBuffer) {
|
||||
data = new Uint8Array(data);
|
||||
}
|
||||
success(data);
|
||||
} else if (oReq.status == 404) {
|
||||
success(null);
|
||||
} else {
|
||||
throw "Error " + oReq.status + " loading " + url;
|
||||
}
|
||||
}
|
||||
oReq.send(null);
|
||||
}
|
||||
|
||||
|
|
|
@ -342,6 +342,15 @@ function populateEntry(fs, path:string, entry:FileEntry, options:BuildOptions) {
|
|||
var data = entry.data;
|
||||
if (options && options.processFn)
|
||||
data = options.processFn(data);
|
||||
// create subfolders
|
||||
var toks = path.split('/');
|
||||
if (toks.length > 1) {
|
||||
for (var i=0; i<toks.length-1; i++)
|
||||
try {
|
||||
fs.mkdir(toks[i]);
|
||||
} catch (e) { }
|
||||
}
|
||||
// write file
|
||||
fs.writeFile(path, data, {encoding:entry.encoding});
|
||||
fs.utime(path, entry.ts, entry.ts);
|
||||
console.log("<<<", path, entry.data.length);
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
nametable.dat: road.png
|
||||
makechr -e error.png $< #-b 0000ff
|
||||
|
||||
road.png: road.py
|
||||
python road.py
|
|
@ -0,0 +1,102 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Import a library of functions called 'pygame'
|
||||
import pygame
|
||||
import random
|
||||
from math import pi
|
||||
|
||||
# Initialize the game engine
|
||||
pygame.init()
|
||||
|
||||
# Define the colors we will use in RGB format
|
||||
BLACK = ( 0, 0, 0)
|
||||
WHITE = (255, 255, 255)
|
||||
BLUE = ( 0, 0, 255)
|
||||
GREEN = ( 0, 184, 0)
|
||||
|
||||
CURBING = [
|
||||
(136,20,0),
|
||||
(168,16,0),
|
||||
]
|
||||
|
||||
CENLINE = [
|
||||
(124,124,124),
|
||||
(188,188,188),
|
||||
]
|
||||
|
||||
MOUNTAINS = [
|
||||
(80,48,0),
|
||||
(172,124,0)
|
||||
]
|
||||
|
||||
# Set the height and width of the screen
|
||||
size = [512, 240]
|
||||
y0 = 112
|
||||
x0 = 256
|
||||
screen = pygame.display.set_mode(size)
|
||||
|
||||
pygame.display.set_caption("Example code for the draw module")
|
||||
|
||||
#Loop until the user clicks the close button.
|
||||
done = False
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
while not done:
|
||||
|
||||
# This limits the while loop to a max of 10 times per second.
|
||||
# Leave this out and we will use all CPU we can.
|
||||
clock.tick(10)
|
||||
|
||||
for event in pygame.event.get(): # User did something
|
||||
if event.type == pygame.QUIT: # If user clicked close
|
||||
done=True # Flag that we are done so we exit this loop
|
||||
|
||||
# All drawing code happens after the for loop and but
|
||||
# inside the main while done==False loop.
|
||||
|
||||
# Clear the screen and set the screen background
|
||||
screen.fill(BLUE)
|
||||
pygame.draw.rect(screen, GREEN, [0, y0, 512, 240-y0])
|
||||
|
||||
# draw the road
|
||||
for y in range(y0,240):
|
||||
i = y-y0
|
||||
rw = i*2
|
||||
cw = rw/4
|
||||
lw = rw/32
|
||||
z = 500.0/(i+1)
|
||||
curbcol = CURBING[int(z) % 2]
|
||||
cencol = CENLINE[int(z) % 2]
|
||||
if i < 16:
|
||||
cencol = BLACK #CENLINE[0]
|
||||
if i < 0:
|
||||
curbcol = BLACK #CURBING[0]
|
||||
pygame.draw.line(screen, BLACK, [x0-rw, y], [x0+rw, y], 1)
|
||||
pygame.draw.line(screen, curbcol, [x0-rw-cw, y], [x0-rw, y], 1)
|
||||
pygame.draw.line(screen, curbcol, [x0+rw, y], [x0+rw+cw, y], 1)
|
||||
pygame.draw.line(screen, cencol, [x0-rw/3-lw, y], [x0-rw/3+lw, y], 1)
|
||||
pygame.draw.line(screen, cencol, [x0+rw/3-lw, y], [x0+rw/3+lw, y], 1)
|
||||
|
||||
# draw mountains
|
||||
h1 = 1
|
||||
h2 = 2
|
||||
for x in range(0,512):
|
||||
pygame.draw.line(screen, MOUNTAINS[0], [x, y0-1], [x, y0-h1], 1)
|
||||
pygame.draw.line(screen, MOUNTAINS[1], [x, y0-1], [x, y0-h2], 1)
|
||||
if random.randint(0,8) > h1:
|
||||
h1 += 1
|
||||
elif h1 > 1:
|
||||
h1 -= 1
|
||||
if random.randint(0,6) > h2:
|
||||
h2 += 1
|
||||
elif h2 > 1:
|
||||
h2 -= 1
|
||||
|
||||
# Go ahead and update the screen with what we've drawn.
|
||||
# This MUST happen after all the other drawing commands.
|
||||
pygame.display.flip()
|
||||
|
||||
pygame.image.save(screen, 'road.png')
|
||||
|
||||
# Be IDLE friendly
|
||||
pygame.quit()
|
Loading…
Reference in New Issue