From fe1e0fc9aa8fa2594de219b809c69325dbcf7a1e Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Fri, 26 Apr 2019 15:38:34 -0400 Subject: [PATCH] nes: added road, tint demo; extra tools; embed.html fetch remote url --- doc/notes.txt | 2 + index.html | 8 +++ presets/nes/ex0.asm | 4 +- presets/nes/ex1.asm | 4 +- presets/nes/ex2.asm | 4 +- presets/nes/ex3.asm | 4 +- presets/nes/ex4.asm | 4 +- presets/nes/neslib.h | 4 ++ presets/nes/rletitle.c | 2 - presets/nes/road.asm | 114 +++++++++++++++++++------------- presets/nes/road/attribute.dat | Bin 0 -> 64 bytes presets/nes/road/attribute1.dat | Bin 0 -> 64 bytes presets/nes/road/nametable.dat | Bin 0 -> 960 bytes presets/nes/road/nametable1.dat | Bin 0 -> 960 bytes presets/nes/road/palette.dat | Bin 0 -> 32 bytes presets/nes/road/road.chr | Bin 0 -> 8192 bytes presets/nes/scrollrt.asm | 20 ++++-- presets/nes/skeleton.cc65 | 39 +++++++++-- presets/nes/tint.c | 69 +++++++++++++++++++ presets/nes/xyscroll.asm | 26 ++++---- src/embedui.ts | 32 +++++++-- src/platform/nes.ts | 4 +- src/project.ts | 21 ++++-- src/ui.ts | 18 +---- src/util.ts | 24 ++++++- src/worker/workermain.ts | 9 +++ tools/nes/Makefile | 6 ++ tools/nes/road.py | 102 ++++++++++++++++++++++++++++ 28 files changed, 407 insertions(+), 113 deletions(-) create mode 100644 presets/nes/road/attribute.dat create mode 100644 presets/nes/road/attribute1.dat create mode 100644 presets/nes/road/nametable.dat create mode 100644 presets/nes/road/nametable1.dat create mode 100644 presets/nes/road/palette.dat create mode 100644 presets/nes/road/road.chr create mode 100644 presets/nes/tint.c create mode 100644 tools/nes/Makefile create mode 100755 tools/nes/road.py diff --git a/doc/notes.txt b/doc/notes.txt index f5e03eae..6d67c6aa 100644 --- a/doc/notes.txt +++ b/doc/notes.txt @@ -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 diff --git a/index.html b/index.html index 88f025c1..c5cc8aa5 100644 --- a/index.html +++ b/index.html @@ -83,6 +83,14 @@ if (window.location.host.endsWith('8bitworkshop.com')) { Tools
diff --git a/presets/nes/ex0.asm b/presets/nes/ex0.asm index 26a90ce2..e1743970 100644 --- a/presets/nes/ex0.asm +++ b/presets/nes/ex0.asm @@ -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 diff --git a/presets/nes/ex1.asm b/presets/nes/ex1.asm index 9b99ac5a..7595af16 100644 --- a/presets/nes/ex1.asm +++ b/presets/nes/ex1.asm @@ -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 diff --git a/presets/nes/ex2.asm b/presets/nes/ex2.asm index 35928026..9eebdd31 100644 --- a/presets/nes/ex2.asm +++ b/presets/nes/ex2.asm @@ -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 diff --git a/presets/nes/ex3.asm b/presets/nes/ex3.asm index b79c3b5d..ef0b274d 100644 --- a/presets/nes/ex3.asm +++ b/presets/nes/ex3.asm @@ -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 diff --git a/presets/nes/ex4.asm b/presets/nes/ex4.asm index 675a27f1..a30a4b07 100644 --- a/presets/nes/ex4.asm +++ b/presets/nes/ex4.asm @@ -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 diff --git a/presets/nes/neslib.h b/presets/nes/neslib.h index 62a1a53c..e2a433b8 100644 --- a/presets/nes/neslib.h +++ b/presets/nes/neslib.h @@ -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 diff --git a/presets/nes/rletitle.c b/presets/nes/rletitle.c index e248f485..a6cf96dd 100644 --- a/presets/nes/rletitle.c +++ b/presets/nes/rletitle.c @@ -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++) { diff --git a/presets/nes/road.asm b/presets/nes/road.asm index f966d4ed..1050fad8 100644 --- a/presets/nes/road.asm +++ b/presets/nes/road.asm @@ -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+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" diff --git a/presets/nes/road/attribute.dat b/presets/nes/road/attribute.dat new file mode 100644 index 0000000000000000000000000000000000000000..ad96393e510f6d1d1b86237bceaa64f882577851 GIT binary patch literal 64 mcmezWA3KPLfc#J(Sh|vnA$01}Ra{IA3_v!JWMF`h3=9D46d_0e literal 0 HcmV?d00001 diff --git a/presets/nes/road/attribute1.dat b/presets/nes/road/attribute1.dat new file mode 100644 index 0000000000000000000000000000000000000000..43e6b4a03d84bb2d1e16ffc12d684b326ef6f648 GIT binary patch literal 64 lcmezWA3K;I4*?8Z%a(=$0RsaA*Q%wdAR5S8wiHYQSpeK&Av^#8 literal 0 HcmV?d00001 diff --git a/presets/nes/road/nametable.dat b/presets/nes/road/nametable.dat new file mode 100644 index 0000000000000000000000000000000000000000..cab17ce8b6f7f9bd89f5f83954106f6bde846402 GIT binary patch literal 960 zcmZQz7zKkl1Q?l^SyzkTklh-o0u(Sfo>Ra3BW6G=A+SxmRWc3}LoYCdA zTwLAUJ;1X1`kr1uMacGh`}q3#2S8=@1A{<@z~!}EfX$N*^aCo0?l%+uA!iySjUN`}!wLoHTjL)M?Xa%$zlQ&Rj)&VBY)% z3m4&0puc#D{?cX3SKv~jzjBqnzW(YpYu8~{p|8Jw15knf#!Z{IU^4_LwRIavf&TU# zJ9lBa1Sqk44_IDbfA2oG{Rhwt0ZAP^1XZAa_=w-pW5IzA!m^c z0ZW`ae*vyQ|M10_m`j&oE`f+&xr&h2*S~f>DJkj3O|VNK;cIJ+u4!H@i+5^gV9KJwl@v%_U8FpiqAd|ymQ=`vM1DDo9`|1)znpa=Le_1A^IP0D_mQ2 z@y=h@3Di;t*20uDhnq=Umzjsg)_2bLW@eFj(4$oSs!)Y6Ce9n;AWR@_u4~asRb;A! zKIrK<=*=%K4l)2Q)t>eK1Hq++*N;-b0>M_s^yAdheq+Qg$7&Pi(K6}(--UAv3(Kpk zg)s}ptQr_&tJHyE{5X4{N#e%}ToV^j0stT8fWIK;A5%gLV0Ta8j?ZY)Cc$el;nqe|NZGcPvfZz?~WekmZNghDM+2o)CM?D!Y#>cBAz;H8i=VFRTQYPimu6*}U)qzCGF z>C5FMuRjU!Qcq8wc`1IU`Ew@?Ck~5gO3QdvQgpzMKJW(`1&^znH{FYO?J3DSO@>hB z%QOJqb+4EGaz^yIBu(+SDzDb^p4yXrzK8b*CU{ddny-valOs!K_5^QVq;dxLk>p8Z_xBjusm z0~Hwf_j!nLfk#*RCw1Aq-`67f#Q-A7_i*U+$)@BxJks0L4R($D?+zB%6ypaJ2WwZy zicj_g?-sj)hw(GO+nd4Cy5Q#aN5<|wECwI^qWb4vGWOD|i;MHKvspF}$%WW|P4?@Z zU?^>-*OPC#mz?BYFKrOXU8q)6(q52ooROjh7w@b*Ie78G)e#DkAFmrDR+5;SC<7pwG{o5Gl7_&i`Arg%^K6-z4i z6Jq=!eld+MjeyY*e;h?&pOuREqCsX^UKC{o30(5wmz>)8nL;9URr@h1!8Yd8Hf%*> zKGnv`3VrZ3h7YX_d=S!?@w_+*>og~VK0}8kA8%haYd)Y}C~}`yQl)bG)ZDN1*rvcxb%Ko$#f?2lk8yL*Jr=nTK1}{<-U5UcKw^{PxwVRai08r=6Q1E_O`T+@Yznd0(mU? zqYhqzN}+)3Jo*0PMob+DA()sq!Of{3XGhjte2$LxenOw+io7fxv0mzF3XGR}n(D?& zM_(usj_AK_bnH%`NWthP^7B)j>=@`6=osi2=osi2=osi2=osi2=osi2=osi2=osi2 IcrpY30ZP=;W&i*H literal 0 HcmV?d00001 diff --git a/presets/nes/scrollrt.asm b/presets/nes/scrollrt.asm index ed5596fc..c517e1d8 100644 --- a/presets/nes/scrollrt.asm +++ b/presets/nes/scrollrt.asm @@ -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 diff --git a/presets/nes/skeleton.cc65 b/presets/nes/skeleton.cc65 index 6eac344b..929c1fe5 100644 --- a/presets/nes/skeleton.cc65 +++ b/presets/nes/skeleton.cc65 @@ -1,16 +1,45 @@ +#include +#include + +// 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) { + } } diff --git a/presets/nes/tint.c b/presets/nes/tint.c new file mode 100644 index 00000000..9811e1d1 --- /dev/null +++ b/presets/nes/tint.c @@ -0,0 +1,69 @@ + +#include +#include + +// 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); + } +} diff --git a/presets/nes/xyscroll.asm b/presets/nes/xyscroll.asm index 816daa06..1bbcdd48 100644 --- a/presets/nes/xyscroll.asm +++ b/presets/nes/xyscroll.asm @@ -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 diff --git a/src/embedui.ts b/src/embedui.ts index 7bf1f5e2..131a7b76 100644 --- a/src/embedui.ts +++ b/src/embedui.ts @@ -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; } diff --git a/src/platform/nes.ts b/src/platform/nes.ts index 3f5be53f..adb185bb 100644 --- a/src/platform/nes.ts +++ b/src/platform/nes.ts @@ -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 diff --git a/src/project.ts b/src/project.ts index 5d50ee25..2a656fb2 100644 --- a/src/project.ts +++ b/src/project.ts @@ -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; + } } diff --git a/src/ui.ts b/src/ui.ts index 3c617547..d4c5f6ef 100644 --- a/src/ui.ts +++ b/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); diff --git a/src/util.ts b/src/util.ts index a7a3a8c2..8ab59e12 100644 --- a/src/util.ts +++ b/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); +} + diff --git a/src/worker/workermain.ts b/src/worker/workermain.ts index cbd04ccf..6bad97ec 100644 --- a/src/worker/workermain.ts +++ b/src/worker/workermain.ts @@ -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 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()