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
|
- per-View keyboard shortcuts
|
||||||
- parse labels
|
- parse labels
|
||||||
- parse .incbin directives?
|
- parse .incbin directives?
|
||||||
|
- can't replace in hex directives
|
||||||
- crt0.s compiled each time?
|
- crt0.s compiled each time?
|
||||||
- debug highlight doesn't go away when debugging -> running
|
- debug highlight doesn't go away when debugging -> running
|
||||||
- show breakpoint of PC or highest address on stack
|
- show breakpoint of PC or highest address on stack
|
||||||
|
@ -124,6 +125,7 @@ TODO:
|
||||||
- CPU debugging
|
- CPU debugging
|
||||||
- disassemble more code around breakpoint
|
- disassemble more code around breakpoint
|
||||||
- single-stepping vector games makes screen fade
|
- single-stepping vector games makes screen fade
|
||||||
|
- break on stack overflow, bad op, bad access, etc
|
||||||
|
|
||||||
WEB WORKER FORMAT
|
WEB WORKER FORMAT
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,14 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<a tabindex="-1" href="#">Tools</a>
|
<a tabindex="-1" href="#">Tools</a>
|
||||||
<ul class="dropdown-menu">
|
<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="./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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
|
@ -26,10 +26,10 @@ Start:
|
||||||
lda #$1c ; $1C = light blue color
|
lda #$1c ; $1C = light blue color
|
||||||
sta PPU_DATA ; $1C -> PPU data
|
sta PPU_DATA ; $1C -> PPU data
|
||||||
; activate PPU graphics
|
; activate PPU graphics
|
||||||
lda #CTRL_NMI
|
|
||||||
sta PPU_CTRL ; enable NMI
|
|
||||||
lda #MASK_COLOR
|
lda #MASK_COLOR
|
||||||
sta PPU_MASK ; enable rendering
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ; endless loop
|
jmp .endless ; endless loop
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,10 @@ Start:
|
||||||
sta PPU_SCROLL
|
sta PPU_SCROLL
|
||||||
sta PPU_SCROLL ; PPU scroll = $0000
|
sta PPU_SCROLL ; PPU scroll = $0000
|
||||||
; activate PPU graphics
|
; activate PPU graphics
|
||||||
lda #CTRL_NMI
|
|
||||||
sta PPU_CTRL ; enable NMI
|
|
||||||
lda #MASK_BG
|
lda #MASK_BG
|
||||||
sta PPU_MASK ; enable rendering
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ; endless loop
|
jmp .endless ; endless loop
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,10 @@ Start:
|
||||||
sta PPU_SCROLL
|
sta PPU_SCROLL
|
||||||
sta PPU_SCROLL ; scroll = $0000
|
sta PPU_SCROLL ; scroll = $0000
|
||||||
; activate PPU graphics
|
; activate PPU graphics
|
||||||
lda #CTRL_NMI
|
|
||||||
sta PPU_CTRL ; enable NMI
|
|
||||||
lda #MASK_BG
|
lda #MASK_BG
|
||||||
sta PPU_MASK ; enable rendering
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ; endless loop
|
jmp .endless ; endless loop
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ Start:
|
||||||
sta PPU_ADDR ;PPU addr = 0
|
sta PPU_ADDR ;PPU addr = 0
|
||||||
sta PPU_SCROLL
|
sta PPU_SCROLL
|
||||||
sta PPU_SCROLL ;scroll = 0
|
sta PPU_SCROLL ;scroll = 0
|
||||||
lda #CTRL_NMI
|
|
||||||
sta PPU_CTRL ; enable NMI
|
|
||||||
lda #MASK_BG|MASK_SPR
|
lda #MASK_BG|MASK_SPR
|
||||||
sta PPU_MASK ; enable rendering
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ;endless loop
|
jmp .endless ;endless loop
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,10 @@ Start:
|
||||||
sta PPU_ADDR ;PPU addr = 0
|
sta PPU_ADDR ;PPU addr = 0
|
||||||
sta PPU_SCROLL
|
sta PPU_SCROLL
|
||||||
sta PPU_SCROLL ;scroll = 0
|
sta PPU_SCROLL ;scroll = 0
|
||||||
lda #CTRL_NMI
|
|
||||||
sta PPU_CTRL ; enable NMI
|
|
||||||
lda #MASK_BG|MASK_SPR
|
lda #MASK_BG|MASK_SPR
|
||||||
sta PPU_MASK ; enable rendering
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ;endless loop
|
jmp .endless ;endless loop
|
||||||
|
|
||||||
|
|
|
@ -287,6 +287,10 @@ void __fastcall__ nmi_set_callback(void (*callback)(void));
|
||||||
#define MASK_BG 0x08
|
#define MASK_BG 0x08
|
||||||
#define MASK_EDGE_SPR 0x04
|
#define MASK_EDGE_SPR 0x04
|
||||||
#define MASK_EDGE_BG 0x02
|
#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_A 0x2000
|
||||||
#define NAMETABLE_B 0x2400
|
#define NAMETABLE_B 0x2400
|
||||||
|
|
|
@ -12,8 +12,6 @@ extern const byte climbr_title_rle[];
|
||||||
|
|
||||||
// link title screen palette and RLE nametable
|
// link title screen palette and RLE nametable
|
||||||
//#link "climbr_title.s"
|
//#link "climbr_title.s"
|
||||||
|
|
||||||
|
|
||||||
void fade_in() {
|
void fade_in() {
|
||||||
byte vb;
|
byte vb;
|
||||||
for (vb=0; vb<=4; vb++) {
|
for (vb=0; vb<=4; vb++) {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
seg.u ZEROPAGE
|
seg.u ZEROPAGE
|
||||||
org $0
|
org $0
|
||||||
|
|
||||||
|
Ptr1 .word ; for temporary pointer storage
|
||||||
|
|
||||||
TrackFrac .byte ; fractional position along track
|
TrackFrac .byte ; fractional position along track
|
||||||
Speed .byte ; speed of car
|
Speed .byte ; speed of car
|
||||||
|
@ -24,9 +26,8 @@ ZOfs .byte ; counter to draw striped center line
|
||||||
Weather .byte ; bitmask for weather
|
Weather .byte ; bitmask for weather
|
||||||
Heading .word ; sky scroll pos.
|
Heading .word ; sky scroll pos.
|
||||||
|
|
||||||
XCenter = 128
|
NumRoadScanlines = 112
|
||||||
NumRoadSegments = 28
|
NumRoadSegments = 56
|
||||||
|
|
||||||
; Preprocessing result: X positions for all track segments
|
; Preprocessing result: X positions for all track segments
|
||||||
RoadX0 ds NumRoadSegments
|
RoadX0 ds NumRoadSegments
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ InitialSpeed equ 10 ; starting speed
|
||||||
|
|
||||||
;;;;; NES CARTRIDGE HEADER
|
;;;;; 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
|
;;;;; START OF CODE
|
||||||
|
|
||||||
|
@ -53,7 +54,6 @@ Start:
|
||||||
jsr ClearRAM ; clear RAM
|
jsr ClearRAM ; clear RAM
|
||||||
jsr WaitSync ; wait for VSYNC (and PPU warmup)
|
jsr WaitSync ; wait for VSYNC (and PPU warmup)
|
||||||
|
|
||||||
jsr SetPalette ; set palette colors
|
|
||||||
jsr FillVRAM ; set PPU video RAM
|
jsr FillVRAM ; set PPU video RAM
|
||||||
|
|
||||||
jsr RoadSetup
|
jsr RoadSetup
|
||||||
|
@ -63,10 +63,10 @@ Start:
|
||||||
sta PPU_ADDR ; PPU addr = $0000
|
sta PPU_ADDR ; PPU addr = $0000
|
||||||
sta PPU_SCROLL
|
sta PPU_SCROLL
|
||||||
sta PPU_SCROLL ; scroll = $0000
|
sta PPU_SCROLL ; scroll = $0000
|
||||||
|
lda #MASK_BG|MASK_SPR|MASK_BG_CLIP
|
||||||
|
sta PPU_MASK ; enable rendering (first!)
|
||||||
lda #CTRL_NMI
|
lda #CTRL_NMI
|
||||||
sta PPU_CTRL ; enable NMI
|
sta PPU_CTRL ; enable NMI
|
||||||
lda #MASK_BG|MASK_SPR
|
|
||||||
sta PPU_MASK ; enable rendering
|
|
||||||
|
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ; endless loop
|
jmp .endless ; endless loop
|
||||||
|
@ -249,43 +249,43 @@ GenTrack subroutine
|
||||||
|
|
||||||
; fill video RAM
|
; fill video RAM
|
||||||
FillVRAM: subroutine
|
FillVRAM: subroutine
|
||||||
txa
|
PPU_SETADDR $2000
|
||||||
ldy #$20
|
lda #<RoadTables
|
||||||
sty PPU_ADDR
|
sta Ptr1
|
||||||
sta PPU_ADDR
|
lda #>RoadTables
|
||||||
ldy #$10
|
sta Ptr1+1
|
||||||
|
ldx #8
|
||||||
|
ldy #0
|
||||||
.loop:
|
.loop:
|
||||||
|
lda (Ptr1),y
|
||||||
sta PPU_DATA
|
sta PPU_DATA
|
||||||
adc #7
|
iny
|
||||||
inx
|
|
||||||
bne .loop
|
bne .loop
|
||||||
dey
|
inc Ptr1+1
|
||||||
|
dex
|
||||||
bne .loop
|
bne .loop
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; set palette colors
|
; set palette colors
|
||||||
SetPalette: subroutine
|
SetPalette: subroutine
|
||||||
ldy #$00
|
PPU_SETADDR $3f00
|
||||||
lda #$3f
|
ldx #16
|
||||||
sta PPU_ADDR
|
|
||||||
sty PPU_ADDR
|
|
||||||
ldx #32
|
|
||||||
.loop:
|
.loop:
|
||||||
lda Palette,y
|
lda Palette,y
|
||||||
sta PPU_DATA
|
sta PPU_DATA
|
||||||
iny
|
iny
|
||||||
dex
|
dex
|
||||||
bne .loop
|
bne .loop
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; set sprite 0
|
; set sprite 0
|
||||||
SetSprite0: subroutine
|
SetSprite0: subroutine
|
||||||
sta $200 ;y
|
sta $200 ;ypos
|
||||||
lda #1 ;code
|
lda #$00 ;code
|
||||||
sta $201
|
sta $201
|
||||||
lda #0 ;flags
|
lda #$20 ;flags
|
||||||
sta $202
|
sta $202
|
||||||
lda #8 ;xpos
|
lda #$fe ;xpos
|
||||||
sta $203
|
sta $203
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
@ -314,18 +314,26 @@ SetSprite0: subroutine
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
NMIHandler: subroutine
|
NMIHandler: subroutine
|
||||||
|
; save registers
|
||||||
SAVE_REGS
|
SAVE_REGS
|
||||||
; setup sky scroll
|
; cycle palette colors
|
||||||
lda Heading+1
|
lda TPos ; track position
|
||||||
sta PPU_SCROLL
|
lsr ; / 2
|
||||||
lda #0
|
and #16 ; now either 0 or 16
|
||||||
sta PPU_SCROLL
|
tay ; Y is palette offset
|
||||||
; load sprites
|
jsr SetPalette ; call SetPalette
|
||||||
lda #112
|
PPU_SETADDR $2000 ; reset PPU address
|
||||||
|
; load sprite zero
|
||||||
|
lda #109
|
||||||
jsr SetSprite0
|
jsr SetSprite0
|
||||||
lda #$02
|
lda #$02
|
||||||
sta PPU_OAM_DMA
|
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 RoadPreSetup
|
||||||
jsr PreprocessCurve
|
jsr PreprocessCurve
|
||||||
jsr RoadPostFrame
|
jsr RoadPostFrame
|
||||||
|
@ -337,30 +345,42 @@ NMIHandler: subroutine
|
||||||
; alter horiz. scroll position for each scanline
|
; alter horiz. scroll position for each scanline
|
||||||
ldy #0
|
ldy #0
|
||||||
.loop
|
.loop
|
||||||
|
; pad out rest of scanline
|
||||||
|
SLEEP 78
|
||||||
|
; change scroll register
|
||||||
tya
|
tya
|
||||||
lsr
|
lsr ; / 2
|
||||||
lsr
|
|
||||||
tax
|
tax
|
||||||
lda RoadX0,x
|
lda RoadX0,x ; get X offset of scanline
|
||||||
|
eor #$80 ; + 128
|
||||||
sta PPU_SCROLL ; horiz byte
|
sta PPU_SCROLL ; horiz byte
|
||||||
lda #0
|
lda #0
|
||||||
sta PPU_SCROLL ; vert byte
|
sta PPU_SCROLL ; vert byte = 0
|
||||||
SLEEP 84
|
; take extra cycle every 4th line
|
||||||
|
tya
|
||||||
|
and #3
|
||||||
|
bne .skipcyc
|
||||||
|
.skipcyc
|
||||||
|
; next loop iteration
|
||||||
iny
|
iny
|
||||||
cpy #112
|
cpy #NumRoadScanlines
|
||||||
bne .loop
|
bne .loop ; do next scanline
|
||||||
|
; restore registers and return from interrupt
|
||||||
RESTORE_REGS
|
RESTORE_REGS
|
||||||
rti
|
rti
|
||||||
|
|
||||||
;;;;; CONSTANT DATA
|
;;;;; CONSTANT DATA
|
||||||
|
|
||||||
align $100
|
;;{pal:"nes",layout:"nes"};;
|
||||||
Palette:
|
Palette:
|
||||||
hex 1f ;background
|
hex 0F3F06300F19063F0F1916063F180801
|
||||||
hex 09092c00 ;bg0
|
hex 0F30163F0F19163F0F1906160F180801
|
||||||
hex 09091900 ;bg1
|
;;
|
||||||
hex 09091500 ;bg2
|
RoadTables:
|
||||||
hex 09092500 ;bg3
|
incbin "road/nametable.dat"
|
||||||
|
incbin "road/attribute.dat"
|
||||||
|
incbin "road/nametable1.dat"
|
||||||
|
incbin "road/attribute1.dat"
|
||||||
|
|
||||||
;;;;; CPU VECTORS
|
;;;;; CPU VECTORS
|
||||||
|
|
||||||
|
@ -369,4 +389,4 @@ Palette:
|
||||||
;;;;; TILE SETS
|
;;;;; TILE SETS
|
||||||
|
|
||||||
org $10000
|
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
|
seg.u ZEROPAGE
|
||||||
org $0
|
org $0
|
||||||
|
|
||||||
|
SkipY ds 1
|
||||||
|
|
||||||
;;;;; OTHER VARIABLES
|
;;;;; OTHER VARIABLES
|
||||||
|
|
||||||
|
@ -34,10 +36,10 @@ Start:
|
||||||
sta PPU_ADDR ; PPU addr = $0000
|
sta PPU_ADDR ; PPU addr = $0000
|
||||||
sta PPU_SCROLL
|
sta PPU_SCROLL
|
||||||
sta PPU_SCROLL ; scroll = $0000
|
sta PPU_SCROLL ; scroll = $0000
|
||||||
lda #CTRL_NMI
|
|
||||||
sta PPU_CTRL ; enable NMI
|
|
||||||
lda #MASK_BG|MASK_SPR
|
lda #MASK_BG|MASK_SPR
|
||||||
sta PPU_MASK ; enable rendering
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ; endless loop
|
jmp .endless ; endless loop
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ SetPalette: subroutine
|
||||||
; set sprite 0
|
; set sprite 0
|
||||||
SetSprite0: subroutine
|
SetSprite0: subroutine
|
||||||
sta $200 ;y
|
sta $200 ;y
|
||||||
lda #$01 ;code
|
lda #$a0 ;code
|
||||||
sta $201
|
sta $201
|
||||||
lda #$20 ;flags
|
lda #$20 ;flags
|
||||||
sta $202
|
sta $202
|
||||||
|
@ -100,6 +102,13 @@ NMIHandler: subroutine
|
||||||
bvc .wait1
|
bvc .wait1
|
||||||
ldy #0
|
ldy #0
|
||||||
.loop
|
.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
|
; alter horiz. scroll position for each scanline
|
||||||
tya
|
tya
|
||||||
sec
|
sec
|
||||||
|
@ -111,10 +120,9 @@ NMIHandler: subroutine
|
||||||
sta PPU_SCROLL ; horiz byte
|
sta PPU_SCROLL ; horiz byte
|
||||||
lda #0
|
lda #0
|
||||||
sta PPU_SCROLL ; vert byte
|
sta PPU_SCROLL ; vert byte
|
||||||
; pad out rest of scanline
|
; next iteration of loop
|
||||||
SLEEP 72
|
|
||||||
iny
|
iny
|
||||||
cpy #224
|
cpy #112
|
||||||
bne .loop
|
bne .loop
|
||||||
RESTORE_REGS
|
RESTORE_REGS
|
||||||
rti
|
rti
|
||||||
|
|
|
@ -1,16 +1,45 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// include NESLIB header
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
|
|
||||||
// link the pattern table into CHR ROM
|
// link the pattern table into CHR ROM
|
||||||
//#link "chr_generic.s"
|
//#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)
|
void main(void)
|
||||||
{
|
{
|
||||||
pal_col(1,0x04);
|
setup_graphics();
|
||||||
pal_col(2,0x20);
|
// draw message
|
||||||
pal_col(3,0x30);
|
|
||||||
vram_adr(NTADR_A(2,2));
|
vram_adr(NTADR_A(2,2));
|
||||||
vram_write("HELLO, WORLD!", 12);
|
vram_write("HELLO, WORLD!", 12);
|
||||||
ppu_on_all();//enable rendering
|
// enable rendering
|
||||||
while(1);//do nothing, infinite loop
|
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_ADDR ; PPU addr = $0000
|
||||||
sta PPU_SCROLL
|
sta PPU_SCROLL
|
||||||
sta PPU_SCROLL ; scroll = $0000
|
sta PPU_SCROLL ; scroll = $0000
|
||||||
lda #CTRL_NMI
|
|
||||||
sta PPU_CTRL ; enable NMI
|
|
||||||
lda #MASK_BG|MASK_SPR
|
lda #MASK_BG|MASK_SPR
|
||||||
sta PPU_MASK ; enable rendering
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #CTRL_NMI
|
||||||
|
sta PPU_CTRL ; enable NMI
|
||||||
.endless
|
.endless
|
||||||
jmp .endless ; endless loop
|
jmp .endless ; endless loop
|
||||||
|
|
||||||
|
@ -93,26 +93,26 @@ NMIHandler: subroutine
|
||||||
; load sprites
|
; load sprites
|
||||||
lda #$02
|
lda #$02
|
||||||
sta PPU_OAM_DMA
|
sta PPU_OAM_DMA
|
||||||
; wait for sprite 0
|
|
||||||
.wait0 bit PPU_STATUS
|
|
||||||
bvs .wait0
|
|
||||||
.wait1 bit PPU_STATUS
|
|
||||||
bvc .wait1
|
|
||||||
; set XY scroll
|
; set XY scroll
|
||||||
; compute first PPU_ADDR write
|
; compute second PPU_ADDR write
|
||||||
lda ScrollX
|
lda ScrollX
|
||||||
tax
|
tax ; ScrollX -> X
|
||||||
lsr
|
lsr
|
||||||
lsr
|
lsr
|
||||||
lsr
|
lsr
|
||||||
sta Temp
|
sta Temp
|
||||||
lda ScrollY
|
lda ScrollY
|
||||||
tay
|
tay ; ScrollY -> Y
|
||||||
and #$f8
|
and #$38
|
||||||
asl
|
asl
|
||||||
asl
|
asl
|
||||||
ora Temp
|
ora Temp ; (ScrollX >> 3) | ((ScrollY & 0x38) << 2)
|
||||||
pha
|
pha ; push onto stack
|
||||||
|
; wait for sprite 0
|
||||||
|
.wait0 bit PPU_STATUS
|
||||||
|
bvs .wait0
|
||||||
|
.wait1 bit PPU_STATUS
|
||||||
|
bvc .wait1
|
||||||
; set PPU_ADDR.1
|
; set PPU_ADDR.1
|
||||||
lda #0
|
lda #0
|
||||||
sta PPU_ADDR
|
sta PPU_ADDR
|
||||||
|
|
|
@ -3,7 +3,7 @@ window['Javatari'].AUTO_START = false;
|
||||||
|
|
||||||
import { PLATFORMS } from "./emu";
|
import { PLATFORMS } from "./emu";
|
||||||
import { Platform } from "./baseplatform";
|
import { Platform } from "./baseplatform";
|
||||||
import { stringToByteArray } from "./util";
|
import { stringToByteArray, getWithBinary } from "./util";
|
||||||
|
|
||||||
export var platform_id : string; // platform ID string
|
export var platform_id : string; // platform ID string
|
||||||
export var platform : Platform; // platform object
|
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) {
|
function startPlatform(qs) {
|
||||||
if (!PLATFORMS[platform_id]) throw Error("Invalid platform '" + platform_id + "'.");
|
if (!PLATFORMS[platform_id]) throw Error("Invalid platform '" + platform_id + "'.");
|
||||||
platform = new PLATFORMS[platform_id]($("#emulator")[0]);
|
platform = new PLATFORMS[platform_id]($("#emulator")[0]);
|
||||||
platform.start();
|
platform.start();
|
||||||
var title = qs['n'] || 'Game';
|
var title = qs['n'] || 'Game';
|
||||||
|
var rom : Uint8Array;
|
||||||
|
var romurl = qs['url'];
|
||||||
var lzgvar = qs['r'];
|
var lzgvar = qs['r'];
|
||||||
var lzgrom = stringToByteArray(atob(lzgvar));
|
if (romurl) {
|
||||||
var rom = new lzgmini().decode(lzgrom);
|
// load rom url remotely
|
||||||
console.log(rom.length + ' bytes');
|
console.log(romurl);
|
||||||
platform.loadROM(title, rom);
|
getWithBinary(romurl, (data) => {
|
||||||
platform.resume();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ const JSNES_PRESETS = [
|
||||||
{id:'metasprites.c', name:'Metasprites'},
|
{id:'metasprites.c', name:'Metasprites'},
|
||||||
{id:'flicker.c', name:'Flickering Sprites'},
|
{id:'flicker.c', name:'Flickering Sprites'},
|
||||||
{id:'metacursor.c', name:'Controllers'},
|
{id:'metacursor.c', name:'Controllers'},
|
||||||
|
{id:'tint.c', name:'Color Emphasis'},
|
||||||
{id:'rletitle.c', name:'Title Screen RLE'},
|
{id:'rletitle.c', name:'Title Screen RLE'},
|
||||||
{id:'statusbar.c', name:'Split Status Bar'},
|
{id:'statusbar.c', name:'Split Status Bar'},
|
||||||
{id:'horizmask.c', name:'Offscreen Scrolling'},
|
{id:'horizmask.c', name:'Offscreen Scrolling'},
|
||||||
|
@ -34,8 +35,9 @@ const JSNES_PRESETS = [
|
||||||
{id:'ex3.asm', name:'Sprite Demo (ASM)'},
|
{id:'ex3.asm', name:'Sprite Demo (ASM)'},
|
||||||
{id:'ex4.asm', name:'Controller Demo (ASM)'},
|
{id:'ex4.asm', name:'Controller Demo (ASM)'},
|
||||||
{id:'musicdemo.asm', name:'Famitone 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:'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
|
/// JSNES
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
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 { getFilenameForPath, getFilenamePrefix, getFolderForPath, isProbablyBinary } from "./util";
|
import { getFilenamePrefix, getFolderForPath, isProbablyBinary } from "./util";
|
||||||
|
|
||||||
type BuildResultCallback = (result:WorkerResult) => void;
|
type BuildResultCallback = (result:WorkerResult) => void;
|
||||||
type BuildStatusCallback = (busy:boolean) => void;
|
type BuildStatusCallback = (busy:boolean) => void;
|
||||||
|
@ -153,7 +153,7 @@ export class CodeProject {
|
||||||
this.preloadWorker(this.mainpath);
|
this.preloadWorker(this.mainpath);
|
||||||
var msg = {updates:[], buildsteps:[]};
|
var msg = {updates:[], buildsteps:[]};
|
||||||
// TODO: add preproc directive for __MAINFILE__
|
// TODO: add preproc directive for __MAINFILE__
|
||||||
var mainfilename = getFilenameForPath(this.mainpath);
|
var mainfilename = this.stripLocalPath(this.mainpath);
|
||||||
var maintext = this.getFile(this.mainpath);
|
var maintext = this.getFile(this.mainpath);
|
||||||
var depfiles = [];
|
var depfiles = [];
|
||||||
msg.updates.push({path:mainfilename, data:maintext});
|
msg.updates.push({path:mainfilename, data:maintext});
|
||||||
|
@ -177,10 +177,10 @@ export class CodeProject {
|
||||||
// TODO: get local file as well as presets?
|
// TODO: get local file as well as presets?
|
||||||
loadFiles(paths:string[], callback:LoadFilesCallback) {
|
loadFiles(paths:string[], callback:LoadFilesCallback) {
|
||||||
var result : Dependency[] = [];
|
var result : Dependency[] = [];
|
||||||
function addResult(path, data) {
|
var addResult = (path, data) => {
|
||||||
result.push({
|
result.push({
|
||||||
path:path,
|
path:path,
|
||||||
filename:getFilenameForPath(path),
|
filename:this.stripLocalPath(path),
|
||||||
link:true,
|
link:true,
|
||||||
data:data
|
data:data
|
||||||
});
|
});
|
||||||
|
@ -319,7 +319,7 @@ export class CodeProject {
|
||||||
|
|
||||||
// returns first listing in format [prefix].lst (TODO: could be better)
|
// returns first listing in format [prefix].lst (TODO: could be better)
|
||||||
getListingForFile(path) : CodeListing {
|
getListingForFile(path) : CodeListing {
|
||||||
var fnprefix = getFilenamePrefix(getFilenameForPath(path));
|
var fnprefix = getFilenamePrefix(this.stripLocalPath(path));
|
||||||
var listings = this.getListings();
|
var listings = this.getListings();
|
||||||
for (var lstfn in listings) {
|
for (var lstfn in listings) {
|
||||||
if (getFilenamePrefix(lstfn) == fnprefix) {
|
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 * 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 } from "./util";
|
byteArrayToUTF8, isProbablyBinary, getWithBinary } from "./util";
|
||||||
import { StateRecorderImpl } from "./recorder";
|
import { StateRecorderImpl } from "./recorder";
|
||||||
|
|
||||||
// external libs (TODO)
|
// 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() {
|
function initProject() {
|
||||||
current_project = new CodeProject(newWorker(), platform_id, platform, store);
|
current_project = new CodeProject(newWorker(), platform_id, platform, store);
|
||||||
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
|
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
|
// check extensions
|
||||||
if (path) {
|
if (path) {
|
||||||
path = path.toUpperCase();
|
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) {
|
for (var ext of BINEXTS) {
|
||||||
if (path.endsWith(ext)) score++;
|
if (path.endsWith(ext)) score++;
|
||||||
}
|
}
|
||||||
|
@ -446,3 +446,25 @@ export function rle_unpack(src : Uint8Array) : Uint8Array {
|
||||||
}
|
}
|
||||||
return new Uint8Array(dest);
|
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;
|
var data = entry.data;
|
||||||
if (options && options.processFn)
|
if (options && options.processFn)
|
||||||
data = options.processFn(data);
|
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.writeFile(path, data, {encoding:entry.encoding});
|
||||||
fs.utime(path, entry.ts, entry.ts);
|
fs.utime(path, entry.ts, entry.ts);
|
||||||
console.log("<<<", path, entry.data.length);
|
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