├── .github └── workflows │ └── codesee-arch-diagram.yml ├── .gitignore ├── .travis.yml ├── COPYING ├── README.md ├── audio.go ├── controller.go ├── main.go ├── nes ├── 6502.go ├── 6502_test.go ├── anrom.go ├── apu.go ├── cnrom.go ├── controller.go ├── disassembler.go ├── event_handler.go ├── gamestate.go ├── machine.go ├── memory.go ├── memory_test.go ├── mmc1.go ├── mmc1_test.go ├── mmc2.go ├── mmc3.go ├── mmc5.go ├── nametable.go ├── nrom.go ├── opcodes.go ├── palette.go ├── ppu.go ├── ppu_test.go ├── rom.go └── unrom.go ├── shaders.go ├── test_roms ├── apu_mixer │ ├── dmc.nes │ ├── noise.nes │ ├── readme.txt │ ├── square.nes │ └── triangle.nes ├── apu_reset │ ├── 4015_cleared.nes │ ├── 4017_timing.nes │ ├── 4017_written.nes │ ├── irq_flag_cleared.nes │ ├── len_ctrs_enabled.nes │ ├── readme.txt │ └── works_immediately.nes ├── apu_test │ ├── apu_test.nes │ ├── readme.txt │ └── rom_singles │ │ ├── 1-len_ctr.nes │ │ ├── 2-len_table.nes │ │ ├── 3-irq_flag.nes │ │ ├── 4-jitter.nes │ │ ├── 5-len_timing.nes │ │ ├── 6-irq_flag_timing.nes │ │ ├── 7-dmc_basics.nes │ │ └── 8-dmc_rates.nes ├── apu_volume_tests │ ├── README.txt │ ├── empty.chr │ ├── makefile │ ├── nes.ini │ ├── obj │ │ └── nes │ │ │ └── khan │ ├── recordings │ │ ├── fceux.ogg │ │ ├── nes-001.ogg │ │ ├── nestopia.ogg │ │ └── nintendulator.ogg │ ├── volumes.nes │ └── zip.in ├── blargg_cpu │ ├── all_instrs.nes │ ├── official_only.nes │ ├── official_only.sav │ ├── readme.txt │ └── rom_singles │ │ ├── 01-implied.nes │ │ ├── 02-immediate.nes │ │ ├── 03-zero_page.nes │ │ ├── 04-zp_xy.nes │ │ ├── 05-absolute.nes │ │ ├── 06-abs_xy.nes │ │ ├── 07-ind_x.nes │ │ ├── 08-ind_y.nes │ │ ├── 09-branches.nes │ │ ├── 10-stack.nes │ │ ├── 11-jmp_jsr.nes │ │ ├── 12-rts.nes │ │ ├── 13-rti.nes │ │ ├── 14-brk.nes │ │ └── 15-special.nes ├── blargg_ppu │ ├── palette_ram.nes │ ├── power_up_palette.nes │ ├── readme.txt │ ├── sprite_ram.nes │ ├── vbl_clear_time.nes │ └── vram_access.nes ├── branch_timing_tests │ ├── 1.Branch_Basics.nes │ ├── 2.Backward_Branch.nes │ ├── 3.Forward_Branch.nes │ └── readme.txt ├── cpu_timing_test6 │ ├── cpu_timing_test.nes │ └── readme.txt ├── mmc3_test_2 │ ├── readme.txt │ └── rom_singles │ │ ├── 1-clocking.nes │ │ ├── 2-details.nes │ │ ├── 3-A12_clocking.nes │ │ ├── 4-scanline_timing.nes │ │ ├── 5-MMC3.nes │ │ └── 6-MMC3_alt.nes ├── nesstress.nes ├── nestest.log ├── nestest.nes ├── nestest.nesproject ├── ppu_vbl_nmi │ ├── ppu_vbl_nmi.nes │ ├── readme.txt │ └── rom_singles │ │ ├── 01-vbl_basics.nes │ │ ├── 02-vbl_set_time.nes │ │ ├── 03-vbl_clear_time.nes │ │ ├── 04-nmi_control.nes │ │ ├── 05-nmi_timing.nes │ │ ├── 06-suppression.nes │ │ ├── 07-nmi_on_timing.nes │ │ ├── 08-nmi_off_timing.nes │ │ ├── 09-even_odd_frames.nes │ │ └── 10-even_odd_timing.nes ├── scanline_scanline.nes ├── scrolltest_scroll.nes ├── sprite_hit_tests_2005.10.05 │ ├── 01.basics.nes │ ├── 02.alignment.nes │ ├── 03.corners.nes │ ├── 04.flip.nes │ ├── 05.left_clip.nes │ ├── 06.right_edge.nes │ ├── 07.screen_bottom.nes │ ├── 08.double_height.nes │ ├── 09.timing_basics.nes │ ├── 10.timing_order.nes │ ├── 11.edge_timing.nes │ └── readme.txt └── sprite_overflow │ ├── sprite_overflow_tests_1.Basics.nes │ ├── sprite_overflow_tests_2.Details.nes │ ├── sprite_overflow_tests_3.Timing.nes │ ├── sprite_overflow_tests_4.Obscure.nes │ └── sprite_overflow_tests_5.Emulator.nes ├── vendor ├── github.com │ ├── go-gl-legacy │ │ └── gl │ │ │ ├── AUTHORS │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── attriblocation.go │ │ │ ├── buffer.go │ │ │ ├── color.go │ │ │ ├── debugoutput.go │ │ │ ├── framebuffer.go │ │ │ ├── gl.go │ │ │ ├── gl.h │ │ │ ├── gl_defs.go │ │ │ ├── matrix.go │ │ │ ├── object.go │ │ │ ├── program.go │ │ │ ├── query.go │ │ │ ├── renderbuffer.go │ │ │ ├── shader.go │ │ │ ├── texture.go │ │ │ ├── transformfeedback.go │ │ │ ├── uniformblockindex.go │ │ │ ├── uniformlocation.go │ │ │ ├── vertex.go │ │ │ └── vertexarray.go │ ├── robertkrimen │ │ └── otto │ │ │ ├── DESIGN.markdown │ │ │ ├── LICENSE │ │ │ ├── Makefile │ │ │ ├── README.markdown │ │ │ ├── ast │ │ │ ├── README.markdown │ │ │ └── node.go │ │ │ ├── builtin.go │ │ │ ├── builtin_array.go │ │ │ ├── builtin_boolean.go │ │ │ ├── builtin_date.go │ │ │ ├── builtin_error.go │ │ │ ├── builtin_function.go │ │ │ ├── builtin_json.go │ │ │ ├── builtin_math.go │ │ │ ├── builtin_number.go │ │ │ ├── builtin_object.go │ │ │ ├── builtin_regexp.go │ │ │ ├── builtin_string.go │ │ │ ├── clone.go │ │ │ ├── cmpl.go │ │ │ ├── cmpl_evaluate.go │ │ │ ├── cmpl_evaluate_expression.go │ │ │ ├── cmpl_evaluate_statement.go │ │ │ ├── cmpl_parse.go │ │ │ ├── console.go │ │ │ ├── dbg.go │ │ │ ├── dbg │ │ │ └── dbg.go │ │ │ ├── error.go │ │ │ ├── evaluate.go │ │ │ ├── file │ │ │ ├── README.markdown │ │ │ └── file.go │ │ │ ├── global.go │ │ │ ├── inline │ │ │ ├── inline.go │ │ │ ├── object.go │ │ │ ├── object_class.go │ │ │ ├── otto.go │ │ │ ├── otto_.go │ │ │ ├── parser │ │ │ ├── Makefile │ │ │ ├── README.markdown │ │ │ ├── dbg.go │ │ │ ├── error.go │ │ │ ├── expression.go │ │ │ ├── lexer.go │ │ │ ├── parser.go │ │ │ ├── regexp.go │ │ │ ├── scope.go │ │ │ └── statement.go │ │ │ ├── property.go │ │ │ ├── registry │ │ │ ├── README.markdown │ │ │ └── registry.go │ │ │ ├── result.go │ │ │ ├── runtime.go │ │ │ ├── scope.go │ │ │ ├── script.go │ │ │ ├── stash.go │ │ │ ├── token │ │ │ ├── Makefile │ │ │ ├── README.markdown │ │ │ ├── token.go │ │ │ ├── token_const.go │ │ │ └── tokenfmt │ │ │ ├── type_arguments.go │ │ │ ├── type_array.go │ │ │ ├── type_boolean.go │ │ │ ├── type_date.go │ │ │ ├── type_error.go │ │ │ ├── type_function.go │ │ │ ├── type_go_array.go │ │ │ ├── type_go_map.go │ │ │ ├── type_go_slice.go │ │ │ ├── type_go_struct.go │ │ │ ├── type_number.go │ │ │ ├── type_reference.go │ │ │ ├── type_regexp.go │ │ │ ├── type_string.go │ │ │ ├── value.go │ │ │ ├── value_boolean.go │ │ │ ├── value_number.go │ │ │ ├── value_primitive.go │ │ │ └── value_string.go │ └── scottferg │ │ └── Go-SDL │ │ ├── gfx │ │ ├── constants.go │ │ └── framerate.go │ │ └── sdl │ │ ├── audio │ │ ├── audio.go │ │ ├── callback.c │ │ └── callback.h │ │ ├── constants.go │ │ ├── event.go │ │ ├── sdl.go │ │ ├── sdl_darwin.go │ │ ├── structs_386.go │ │ ├── structs_amd64.go │ │ └── structs_arm.go └── vendor.json └── video.go /.github/workflows/codesee-arch-diagram.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request_target: 6 | types: [opened, synchronize, reopened] 7 | 8 | name: CodeSee Map 9 | 10 | jobs: 11 | test_map_action: 12 | runs-on: ubuntu-latest 13 | continue-on-error: true 14 | name: Run CodeSee Map Analysis 15 | steps: 16 | - name: checkout 17 | id: checkout 18 | uses: actions/checkout@v2 19 | with: 20 | repository: ${{ github.event.pull_request.head.repo.full_name }} 21 | ref: ${{ github.event.pull_request.head.ref }} 22 | fetch-depth: 0 23 | 24 | # codesee-detect-languages has an output with id languages. 25 | - name: Detect Languages 26 | id: detect-languages 27 | uses: Codesee-io/codesee-detect-languages-action@latest 28 | 29 | - name: Configure JDK 16 30 | uses: actions/setup-java@v2 31 | if: ${{ fromJSON(steps.detect-languages.outputs.languages).java }} 32 | with: 33 | java-version: '16' 34 | distribution: 'zulu' 35 | 36 | # CodeSee Maps Go support uses a static binary so there's no setup step required. 37 | 38 | - name: Configure Node.js 14 39 | uses: actions/setup-node@v2 40 | if: ${{ fromJSON(steps.detect-languages.outputs.languages).javascript }} 41 | with: 42 | node-version: '14' 43 | 44 | - name: Configure Python 3.x 45 | uses: actions/setup-python@v2 46 | if: ${{ fromJSON(steps.detect-languages.outputs.languages).python }} 47 | with: 48 | python-version: '3.10' 49 | architecture: 'x64' 50 | 51 | - name: Configure Ruby '3.x' 52 | uses: ruby/setup-ruby@v1 53 | if: ${{ fromJSON(steps.detect-languages.outputs.languages).ruby }} 54 | with: 55 | ruby-version: '3.0' 56 | 57 | # CodeSee Maps Rust support uses a static binary so there's no setup step required. 58 | 59 | - name: Generate Map 60 | id: generate-map 61 | uses: Codesee-io/codesee-map-action@latest 62 | with: 63 | step: map 64 | github_ref: ${{ github.ref }} 65 | languages: ${{ steps.detect-languages.outputs.languages }} 66 | 67 | - name: Upload Map 68 | id: upload-map 69 | uses: Codesee-io/codesee-map-action@latest 70 | with: 71 | step: mapUpload 72 | api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} 73 | github_ref: ${{ github.ref }} 74 | 75 | - name: Insights 76 | id: insights 77 | uses: Codesee-io/codesee-map-action@latest 78 | with: 79 | step: insights 80 | api_token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} 81 | github_ref: ${{ github.ref }} 82 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.swp 24 | games/* 25 | *.state 26 | *.battery 27 | .DS_Store 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | before_install: 4 | - sudo apt-get update -qq 5 | - sudo apt-get install -qq libsdl1.2-dev libsdl-image1.2-dev libsdl-gfx1.2-dev libglew1.6-dev libxrandr-dev 6 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Scott Ferguson 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the software nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY SCOTT FERGUSON ''AS IS'' AND ANY 16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL SCOTT FERGUSON BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Fergulator 2 | ========== 3 | [![Build Status](https://travis-ci.org/scottferg/Fergulator.png?branch=master)](https://travis-ci.org/scottferg/Fergulator) 4 | 5 | This is an NES emulator, written in Go. It's fairly new and very much a work in progress, so not all games run yet and not all features are implemented. Details are below. 6 | 7 | ![alt text](http://i.imgur.com/QGwdl.png "Metroid") 8 | 9 | ## To build on Linux 10 | 11 | Requires Go 1.1 12 | 13 | From your GOPATH: 14 | 15 | $ sudo apt-get install libsdl1.2-dev libsdl-gfx1.2-dev libsdl-image1.2-dev libglew1.6-dev libxrandr-dev 16 | $ go get github.com/scottferg/Fergulator 17 | 18 | ## To build on OSX 19 | 20 | You'll need to install [XQuartz](http://xquartz.macosforge.org/landing/) in order 21 | to run on OSX. 22 | 23 | Requires Go 1.1 24 | 25 | From your GOPATH: 26 | 27 | $ brew install sdl --with-x11-driver 28 | $ brew install sdl_gfx sdl_image glew 29 | $ go get github.com/scottferg/Fergulator 30 | 31 | ## Run the emulator 32 | 33 | $ Fergulator path/to/game.nes 34 | 35 | ## Controls 36 | 37 | A - Z 38 | B - X 39 | Start - Enter 40 | Select - Right Shift 41 | Up/Down/Left/Right - Arrows 42 | 43 | Save State - S 44 | Load State - L 45 | 46 | Reset - R 47 | 48 | 1:1 aspect ratio - 1 49 | 2:1 aspect ratio - 2 50 | 3:1 aspect ratio - 3 51 | 4:1 aspect ratio - 4 52 | 53 | Emulate overscan - O 54 | Toggle audio - I 55 | 56 | Toggle pause - P 57 | Frame Advance - \ 58 | Reload Debug JS - D 59 | Trigger Mode Event - M 60 | 61 | ## Supported Mappers 62 | 63 | * NROM 64 | * UNROM 65 | * CNROM 66 | * MMC1 67 | * MMC2 68 | * MMC3 69 | * MMC5 70 | * ANROM 71 | 72 | ## Tested games that run well or are playable 73 | 74 | [List is in the wiki](https://github.com/scottferg/Fergulator/wiki/Tested-Games) 75 | -------------------------------------------------------------------------------- /audio.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/scottferg/Go-SDL/sdl" 6 | sdl_audio "github.com/scottferg/Go-SDL/sdl/audio" 7 | "log" 8 | "sync" 9 | ) 10 | 11 | var ( 12 | SampleSize = 2048 13 | as sdl_audio.AudioSpec 14 | ) 15 | 16 | type Audio struct { 17 | samples []int16 18 | sampleIndex int 19 | mutex sync.Mutex 20 | } 21 | 22 | func NewAudio() *Audio { 23 | as = sdl_audio.AudioSpec{ 24 | Freq: 44100, 25 | Format: sdl_audio.AUDIO_S16SYS, 26 | Channels: 1, 27 | Out_Silence: 0, 28 | Samples: uint16(SampleSize), 29 | Out_Size: 0, 30 | } 31 | 32 | if sdl_audio.OpenAudio(&as, nil) < 0 { 33 | log.Fatal(sdl.GetError()) 34 | } 35 | 36 | sdl_audio.PauseAudio(false) 37 | 38 | return &Audio{ 39 | samples: make([]int16, SampleSize), 40 | } 41 | } 42 | 43 | func (a *Audio) AppendSample(s int16) { 44 | a.samples[a.sampleIndex] = s 45 | a.sampleIndex++ 46 | 47 | if a.sampleIndex == SampleSize { 48 | sdl_audio.SendAudio_int16(a.samples) 49 | a.sampleIndex = 0 50 | } 51 | } 52 | 53 | func (a *Audio) Close() { 54 | fmt.Println("Closing!") 55 | sdl_audio.PauseAudio(true) 56 | sdl_audio.CloseAudio() 57 | } 58 | -------------------------------------------------------------------------------- /controller.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/scottferg/Fergulator/nes" 5 | "github.com/scottferg/Go-SDL/sdl" 6 | ) 7 | 8 | func GetKey(ev interface{}) int { 9 | if k, ok := ev.(sdl.KeyboardEvent); ok { 10 | switch k.Keysym.Sym { 11 | case sdl.K_z: // A 12 | return nes.ButtonA 13 | case sdl.K_x: // B 14 | return nes.ButtonB 15 | case sdl.K_RSHIFT: // Select 16 | return nes.ButtonSelect 17 | case sdl.K_RETURN: // Start 18 | return nes.ButtonStart 19 | case sdl.K_UP: // Up 20 | return nes.ButtonUp 21 | case sdl.K_DOWN: // Down 22 | return nes.ButtonDown 23 | case sdl.K_LEFT: // Left 24 | return nes.ButtonLeft 25 | case sdl.K_RIGHT: // Right 26 | return nes.ButtonRight 27 | } 28 | } 29 | 30 | return -1 31 | } 32 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "github.com/scottferg/Fergulator/nes" 7 | "io/ioutil" 8 | "log" 9 | "os" 10 | "runtime" 11 | "runtime/pprof" 12 | "strings" 13 | ) 14 | 15 | var ( 16 | running = true 17 | 18 | videoOut Video 19 | audioOut *Audio 20 | 21 | cpuprofile = flag.String("cprof", "", "write cpu profile to file") 22 | debugfile string 23 | jsHandler *nes.JsEventHandler 24 | ) 25 | 26 | func init() { 27 | flag.StringVar(&debugfile, "debug", "", "JS debugging file") 28 | } 29 | 30 | func main() { 31 | if len(os.Args) < 2 { 32 | fmt.Println("Please specify a ROM file") 33 | return 34 | } 35 | 36 | flag.Parse() 37 | 38 | // TODO: Why don't flags work? Don't want to hardcode this. 39 | debugfile = "debug.js" 40 | 41 | contents, err := ioutil.ReadFile(os.Args[1]) 42 | if err != nil { 43 | fmt.Println(err.Error()) 44 | return 45 | } 46 | 47 | path := strings.Split(os.Args[1], "/") 48 | nes.GameName = strings.Split(path[len(path)-1], ".")[0] 49 | nes.SaveStateFile = fmt.Sprintf(".%s.state", nes.GameName) 50 | nes.BatteryRamFile = fmt.Sprintf(".%s.battery", nes.GameName) 51 | 52 | if debugfile != "" { 53 | jsHandler = nes.NewJsEventHandler(debugfile) 54 | nes.Handler = jsHandler 55 | } else { 56 | nes.Handler = nes.NewNoopEventHandler() 57 | } 58 | 59 | log.Println(nes.GameName, nes.SaveStateFile) 60 | 61 | audioOut = NewAudio() 62 | defer audioOut.Close() 63 | 64 | videoTick, err := nes.Init(contents, audioOut.AppendSample, GetKey) 65 | if err != nil { 66 | fmt.Println(err) 67 | } 68 | 69 | videoOut.Init(videoTick, nes.GameName) 70 | 71 | // Only increase the number of processors we can use after initialization, 72 | // due to an unidentified race condition documented in issue #13. This 73 | // workaround is effective yet unsatisfying. 74 | if *cpuprofile != "" { 75 | f, err := os.Create(*cpuprofile) 76 | if err != nil { 77 | fmt.Println(err) 78 | } 79 | 80 | pprof.StartCPUProfile(f) 81 | defer pprof.StopCPUProfile() 82 | } else { 83 | runtime.GOMAXPROCS(runtime.NumCPU()) 84 | } 85 | 86 | // Main runloop, in a separate goroutine so that 87 | // the video rendering can happen on this one 88 | go nes.RunSystem() 89 | 90 | // This needs to happen on the main thread for OSX 91 | runtime.LockOSThread() 92 | 93 | defer videoOut.Close() 94 | videoOut.Render() 95 | 96 | return 97 | } 98 | -------------------------------------------------------------------------------- /nes/6502_test.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "io/ioutil" 7 | "strconv" 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | type CpuState struct { 13 | A int 14 | X int 15 | Y int 16 | P int 17 | S int 18 | C int 19 | Op uint16 20 | Cyc int 21 | Sl int 22 | } 23 | 24 | func TestGoldLog(test *testing.T) { 25 | ProgramCounter = 0xC000 26 | 27 | Ram.Init() 28 | cpu.Reset() 29 | ppu.Init() 30 | 31 | cpu.P = 0x24 32 | 33 | cpu.Accurate = false 34 | 35 | if contents, err := ioutil.ReadFile("test_roms/nestest.nes"); err == nil { 36 | if rom, err = LoadRom(contents); err != nil { 37 | test.Error(err.Error()) 38 | return 39 | } 40 | } 41 | 42 | logfile, err := ioutil.ReadFile("test_roms/nestest.log") 43 | if err != nil { 44 | test.Error(err.Error()) 45 | return 46 | } 47 | 48 | log := strings.Split(string(logfile), "\n") 49 | 50 | sentinel := 250 51 | //sentinel := 5003 52 | for i := 0; i < sentinel; i++ { 53 | op, _ := hex.DecodeString(log[i][:4]) 54 | 55 | high := op[0] 56 | low := op[1] 57 | 58 | r := log[i][48:] 59 | 60 | registers := strings.Fields(r) 61 | 62 | a, _ := hex.DecodeString(strings.Split(registers[0], ":")[1]) 63 | x, _ := hex.DecodeString(strings.Split(registers[1], ":")[1]) 64 | y, _ := hex.DecodeString(strings.Split(registers[2], ":")[1]) 65 | p, _ := hex.DecodeString(strings.Split(registers[3], ":")[1]) 66 | sp, _ := hex.DecodeString(strings.Split(registers[4], ":")[1]) 67 | sl, _ := strconv.Atoi(strings.Split(registers[len(registers)-1], ":")[1]) 68 | 69 | var cyc int 70 | if len(registers[len(registers)-2]) > 2 { 71 | cyc, _ = strconv.Atoi(strings.Split(registers[len(registers)-2], ":")[1]) 72 | } else { 73 | cyc, _ = strconv.Atoi(registers[len(registers)-2]) 74 | } 75 | 76 | fmt.Printf("PC 0x%X -> Cyc: %s\n", ProgramCounter, registers[len(registers)-2]) 77 | 78 | // CYC is PPU cycle (wraps at 341) 79 | // SL is PPU scanline (wraps at 260) 80 | expectedState := CpuState{ 81 | A: int(a[0]), 82 | X: int(x[0]), 83 | Y: int(y[0]), 84 | P: int(p[0]), 85 | S: int(sp[0]), 86 | Op: (uint16(high) << 8) + uint16(low), 87 | Cyc: cyc, 88 | Sl: sl, 89 | } 90 | 91 | verifyCpuState(ProgramCounter, &cpu, &ppu, expectedState, test) 92 | cycles := cpu.Step() 93 | 94 | // 3 PPU cycles for each CPU cycle 95 | for i := 0; i < 3*cycles; i++ { 96 | ppu.Step() 97 | } 98 | } 99 | } 100 | 101 | func verifyCpuState(pc uint16, c *Cpu, p *Ppu, e CpuState, test *testing.T) { 102 | if true || pc != e.Op { 103 | test.Errorf("PC was 0x%X, expected 0x%X\n", pc, e.Op) 104 | } 105 | 106 | if c.A != Word(e.A) { 107 | test.Errorf("PC: 0x%X Register A was 0x%X, was expecting 0x%X\n", pc, c.A, e.A) 108 | } 109 | 110 | if c.X != Word(e.X) { 111 | test.Errorf("PC: 0x%X Register X was 0x%X, was expecting 0x%X\n", pc, c.X, e.X) 112 | } 113 | 114 | if c.Y != Word(e.Y) { 115 | test.Errorf("PC: 0x%X Register Y was 0x%X, was expecting 0x%X\n", pc, c.Y, e.Y) 116 | } 117 | 118 | if c.P != Word(e.P) { 119 | test.Errorf("PC: 0x%X P register was 0x%X, was expecting 0x%X\n", pc, c.P, e.P) 120 | } 121 | 122 | if c.StackPointer != Word(e.S) { 123 | test.Errorf("PC: 0x%X Stack pointer was 0x%X, was expecting 0x%X\n", pc, c.StackPointer, e.S) 124 | } 125 | 126 | if p.Cycle != e.Cyc { 127 | test.Errorf("PC: 0x%X PPU cycle was %d, was expecting %d\n", pc, p.Cycle, e.Cyc) 128 | } 129 | 130 | if p.Scanline != e.Sl { 131 | test.Errorf("PC: 0x%X PPU scanline was %d, was expecting %d\n", pc, p.Scanline, e.Sl) 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /nes/anrom.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | type Anrom struct { 4 | RomBanks [][]Word 5 | VromBanks [][]Word 6 | 7 | PrgBankCount int 8 | ChrRomCount int 9 | Battery bool 10 | Data []byte 11 | 12 | PrgUpperBank int 13 | PrgLowerBank int 14 | } 15 | 16 | func (m *Anrom) Write(v Word, a int) { 17 | if v&0x10 == 0x10 { 18 | ppu.Nametables.SetMirroring(MirroringSingleUpper) 19 | } else { 20 | ppu.Nametables.SetMirroring(MirroringSingleLower) 21 | } 22 | 23 | bank := int((v & 0x7) * 2) 24 | 25 | m.PrgUpperBank = bank + 1 26 | m.PrgLowerBank = bank 27 | } 28 | 29 | func (m *Anrom) Read(a int) Word { 30 | if a >= 0xC000 { 31 | return m.RomBanks[m.PrgUpperBank][a&0x3FFF] 32 | } 33 | 34 | return m.RomBanks[m.PrgLowerBank][a&0x3FFF] 35 | } 36 | 37 | func (m *Anrom) BatteryBacked() bool { 38 | return m.Battery 39 | } 40 | 41 | func (m *Anrom) WriteVram(v Word, a int) { 42 | if a >= 0x1000 { 43 | m.VromBanks[len(m.VromBanks)-1][a&0xFFF] = v 44 | return 45 | } 46 | 47 | m.VromBanks[0][a&0xFFF] = v 48 | } 49 | 50 | func (m *Anrom) ReadVram(a int) Word { 51 | if a >= 0x1000 { 52 | return m.VromBanks[len(m.VromBanks)-1][a&0xFFF] 53 | } 54 | 55 | return m.VromBanks[0][a&0xFFF] 56 | } 57 | 58 | func (m *Anrom) ReadTile(a int) []Word { 59 | if a >= 0x1000 { 60 | a &= 0xFFF 61 | return m.VromBanks[len(m.VromBanks)-1][a : a+16] 62 | } 63 | 64 | a &= 0xFFF 65 | return m.VromBanks[0][a : a+16] 66 | } 67 | -------------------------------------------------------------------------------- /nes/cnrom.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | type Cnrom struct { 4 | RomBanks [][]Word 5 | VromBanks [][]Word 6 | 7 | PrgBankCount int 8 | ChrRomCount int 9 | Battery bool 10 | Data []byte 11 | 12 | ActiveBank int 13 | } 14 | 15 | func (m *Cnrom) Write(v Word, a int) { 16 | m.ActiveBank = int(v&0x3) * 2 17 | } 18 | 19 | func (m *Cnrom) Read(a int) Word { 20 | if a >= 0xC000 { 21 | return m.RomBanks[len(m.RomBanks)-1][a&0x3FFF] 22 | } 23 | 24 | return m.RomBanks[0][a&0x3FFF] 25 | } 26 | 27 | func (m *Cnrom) WriteVram(v Word, a int) { 28 | if a >= 0x1000 { 29 | m.VromBanks[m.ActiveBank+1][a&0xFFF] = v 30 | return 31 | } 32 | 33 | m.VromBanks[m.ActiveBank][a&0xFFF] = v 34 | } 35 | 36 | func (m *Cnrom) ReadVram(a int) Word { 37 | if a >= 0x1000 { 38 | return m.VromBanks[m.ActiveBank+1][a&0xFFF] 39 | } 40 | 41 | return m.VromBanks[m.ActiveBank][a&0xFFF] 42 | } 43 | 44 | func (m *Cnrom) ReadTile(a int) []Word { 45 | if a >= 0x1000 { 46 | return m.VromBanks[m.ActiveBank+1][a&0xFFF : a+16] 47 | } 48 | 49 | return m.VromBanks[m.ActiveBank][a&0xFFF : a+16] 50 | } 51 | 52 | func (m *Cnrom) BatteryBacked() bool { 53 | return m.Battery 54 | } 55 | -------------------------------------------------------------------------------- /nes/controller.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | const ( 4 | ButtonA = iota 5 | ButtonB 6 | ButtonSelect 7 | ButtonStart 8 | ButtonUp 9 | ButtonDown 10 | ButtonLeft 11 | ButtonRight 12 | ) 13 | 14 | type GetButtonFunc func(interface{}) int 15 | 16 | type Controller struct { 17 | ButtonState [16]Word 18 | StrobeState int 19 | LastWrite Word 20 | LastYAxis [2]int 21 | LastXAxis [2]int 22 | getter GetButtonFunc 23 | } 24 | 25 | func (c *Controller) SetButtonState(button int, v Word, offset int) { 26 | switch button { 27 | case ButtonA: // A 28 | c.ButtonState[0+offset] = v 29 | case ButtonB: // B 30 | c.ButtonState[1+offset] = v 31 | case ButtonSelect: // Select 32 | c.ButtonState[2+offset] = v 33 | case ButtonStart: // Start 34 | c.ButtonState[3+offset] = v 35 | case ButtonUp: // Up 36 | c.ButtonState[4+offset] = v 37 | case ButtonDown: // Down 38 | c.ButtonState[5+offset] = v 39 | case ButtonLeft: // Left 40 | c.ButtonState[6+offset] = v 41 | case ButtonRight: // Right 42 | c.ButtonState[7+offset] = v 43 | } 44 | } 45 | 46 | func (c *Controller) KeyDown(e interface{}, offset int) { 47 | c.SetButtonState(c.getter(e), 0x41, offset) 48 | } 49 | 50 | func (c *Controller) KeyUp(e interface{}, offset int) { 51 | c.SetButtonState(c.getter(e), 0x40, offset) 52 | } 53 | 54 | func (c *Controller) Write(v Word) { 55 | if v == 0 && c.LastWrite == 1 { 56 | // 0x4016 writes manage strobe state for 57 | // both controllers. 0x4017 is reserved for 58 | // APU 59 | Pads[0].StrobeState = 0 60 | Pads[1].StrobeState = 0 61 | } 62 | 63 | c.LastWrite = v 64 | } 65 | 66 | func (c *Controller) Read() (r Word) { 67 | if c.StrobeState < 8 { 68 | r = ((c.ButtonState[c.StrobeState+8] & 1) << 1) | c.ButtonState[c.StrobeState] 69 | } else if c.StrobeState == 18 { 70 | r = 0x0 71 | } else if c.StrobeState == 19 { 72 | r = 0x0 73 | } else { 74 | r = 0x0 75 | } 76 | 77 | c.StrobeState++ 78 | 79 | if c.StrobeState == 24 { 80 | c.StrobeState = 0 81 | } 82 | 83 | return 84 | } 85 | 86 | func NewController(getter GetButtonFunc) *Controller { 87 | c := &Controller{ 88 | getter: getter, 89 | } 90 | 91 | for i := 0; i < len(c.ButtonState); i++ { 92 | c.ButtonState[i] = 0x40 93 | } 94 | 95 | return c 96 | } 97 | -------------------------------------------------------------------------------- /nes/event_handler.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | import ( 4 | "fmt" 5 | "github.com/robertkrimen/otto" 6 | "io/ioutil" 7 | "os" 8 | ) 9 | 10 | type EventHandler interface { 11 | Handle(event string) 12 | } 13 | 14 | type NoopEventHandler struct { 15 | } 16 | 17 | type JsEventHandler struct { 18 | callbacks map[string][]otto.Value 19 | vm *otto.Otto 20 | } 21 | 22 | func (handler *JsEventHandler) ReloadFile(filename string) { 23 | fmt.Println("Reloading", filename) 24 | 25 | js, err := ioutil.ReadFile(filename) 26 | 27 | if err != nil { 28 | fmt.Fprintln(os.Stderr, filename, "not readable, not loaded") 29 | return 30 | } 31 | 32 | // Clear out callbacks so we don't end up with double callbacks. 33 | // Keep variables though, they are useful. 34 | handler.callbacks = map[string][]otto.Value{} 35 | 36 | _, err = handler.vm.Run(js) 37 | 38 | if err != nil { 39 | fmt.Println(err) 40 | } 41 | handler.Handle("reload") 42 | } 43 | 44 | func NewNoopEventHandler() *NoopEventHandler { 45 | return &NoopEventHandler{} 46 | } 47 | 48 | func NewJsEventHandler(filename string) *JsEventHandler { 49 | handler := JsEventHandler{ 50 | callbacks: map[string][]otto.Value{}, 51 | vm: otto.New(), 52 | } 53 | 54 | vm := otto.New() 55 | vm.Set("handle", func(call otto.FunctionCall) otto.Value { 56 | event, err := call.Argument(0).ToString() 57 | if err != nil { 58 | // TODO: Handle this 59 | panic(err) 60 | } 61 | handler.callbacks[event] = append(handler.callbacks[event], call.Argument(1)) 62 | return otto.Value{} 63 | }) 64 | handler.vm = vm 65 | handler.ReloadFile(filename) 66 | handler.Handle("init") 67 | 68 | return &handler 69 | } 70 | 71 | func (handler *JsEventHandler) Handle(event string) { 72 | state := map[string]interface{}{ 73 | "ram": func(call otto.FunctionCall) otto.Value { 74 | ram, _ := handler.vm.ToValue(Ram[0:0x800]) 75 | return ram 76 | }, 77 | "writeRam": func(call otto.FunctionCall) otto.Value { 78 | idx, _ := call.Argument(0).ToInteger() 79 | val, _ := call.Argument(1).ToInteger() 80 | 81 | err := Ram.Write(Word(idx), Word(val)) 82 | if err != nil { 83 | fmt.Println(err) 84 | } 85 | 86 | return otto.Value{} 87 | }, 88 | } 89 | 90 | ottoState, _ := handler.vm.ToValue(state) 91 | for _, x := range handler.callbacks[event] { 92 | _, err := x.Call(otto.Value{}, ottoState) 93 | if err != nil { 94 | fmt.Fprintln(os.Stderr, err) 95 | } 96 | } 97 | } 98 | 99 | func (handler *NoopEventHandler) Handle(event string) { 100 | } 101 | -------------------------------------------------------------------------------- /nes/machine.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | var ( 4 | cpu Cpu 5 | ppu Ppu 6 | apu Apu 7 | rom Mapper 8 | Ram Memory 9 | Pads [2]*Controller 10 | ) 11 | -------------------------------------------------------------------------------- /nes/memory.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | type Word uint8 4 | 5 | type Memory []Word 6 | 7 | type MemoryError struct { 8 | ErrorText string 9 | } 10 | 11 | func (e MemoryError) Error() string { 12 | return e.ErrorText 13 | } 14 | 15 | func fitAddressSize(addr interface{}) (v int, e error) { 16 | switch a := addr.(type) { 17 | case Word: 18 | v = int(a) 19 | case int: 20 | v = int(a) 21 | case uint16: 22 | v = int(a) 23 | default: 24 | e = MemoryError{ErrorText: "Invalid type used"} 25 | } 26 | 27 | return 28 | } 29 | 30 | func NewMemory() Memory { 31 | return make([]Word, 0x10000) 32 | } 33 | 34 | func (m Memory) ReadMirroredRam(a int) Word { 35 | offset := a % 0x8 36 | return m[0x2000+offset] 37 | } 38 | 39 | func (m Memory) WriteMirroredRam(v Word, a int) { 40 | offset := a % 0x8 41 | m[0x2000+offset] = v 42 | } 43 | 44 | func (m Memory) Write(address interface{}, val Word) error { 45 | if a, err := fitAddressSize(address); err == nil { 46 | if a >= 0x2000 && a <= 0x2007 { 47 | ppu.RegWrite(val, a) 48 | // m.WriteMirroredRam(val, a) 49 | } else if a == 0x4014 { 50 | ppu.RegWrite(val, a) 51 | m[a] = val 52 | } else if a == 0x4016 { 53 | Pads[0].Write(val) 54 | m[a] = val 55 | } else if a == 0x4017 { 56 | Pads[1].Write(val) 57 | apu.RegWrite(val, a) 58 | m[a] = val 59 | } else if a&0xF000 == 0x4000 { 60 | apu.RegWrite(val, a) 61 | } else if a >= 0x8000 && a <= 0xFFFF { 62 | rom.Write(val, a) 63 | return nil 64 | } else if a >= 0x5100 && a <= 0x6000 { 65 | if v, ok := rom.(*Mmc5); ok { 66 | // MMC5 register handling 67 | v.Write(val, a) 68 | return nil 69 | } 70 | 71 | m[a] = val 72 | } else { 73 | m[a] = val 74 | } 75 | 76 | return nil 77 | } 78 | 79 | return MemoryError{ErrorText: "Invalid address used"} 80 | } 81 | 82 | func (m Memory) Read(a uint16) (Word, error) { 83 | switch { 84 | case a >= 0x2008 && a < 0x4000: 85 | offset := a % 0x8 86 | return ppu.RegRead(int(0x2000 + offset)) 87 | case a <= 0x2007 && a >= 0x2000: 88 | return ppu.RegRead(int(a)) 89 | case a == 0x4016: 90 | return Pads[0].Read(), nil 91 | case a == 0x4017: 92 | return Pads[1].Read(), nil 93 | case a&0xF000 == 0x4000: 94 | return apu.RegRead(int(a)) 95 | case a >= 0x8000 && a <= 0xFFFF: 96 | return rom.Read(int(a)), nil 97 | case a >= 0x5100 && a <= 0x6000: 98 | if _, ok := rom.(*Mmc5); ok { 99 | // MMC5 register handling 100 | return rom.Read(int(a)), nil 101 | } 102 | } 103 | 104 | return m[a], nil 105 | } 106 | -------------------------------------------------------------------------------- /nes/memory_test.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestMirroring(test *testing.T) { 8 | Ram.Init() 9 | } 10 | -------------------------------------------------------------------------------- /nes/nametable.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | const ( 4 | MirroringVertical = iota 5 | MirroringHorizontal 6 | MirroringSingleUpper 7 | MirroringSingleLower 8 | ) 9 | 10 | type Nametable struct { 11 | Mirroring int 12 | LogicalTables [4]*[0x400]Word 13 | Nametable0 [0x400]Word 14 | Nametable1 [0x400]Word 15 | } 16 | 17 | func (n *Nametable) SetMirroring(m int) { 18 | n.Mirroring = m 19 | 20 | switch n.Mirroring { 21 | case MirroringHorizontal: 22 | n.LogicalTables[0] = &n.Nametable0 23 | n.LogicalTables[1] = &n.Nametable0 24 | n.LogicalTables[2] = &n.Nametable1 25 | n.LogicalTables[3] = &n.Nametable1 26 | case MirroringVertical: 27 | n.LogicalTables[0] = &n.Nametable0 28 | n.LogicalTables[1] = &n.Nametable1 29 | n.LogicalTables[2] = &n.Nametable0 30 | n.LogicalTables[3] = &n.Nametable1 31 | case MirroringSingleUpper: 32 | n.LogicalTables[0] = &n.Nametable0 33 | n.LogicalTables[1] = &n.Nametable0 34 | n.LogicalTables[2] = &n.Nametable0 35 | n.LogicalTables[3] = &n.Nametable0 36 | case MirroringSingleLower: 37 | n.LogicalTables[0] = &n.Nametable1 38 | n.LogicalTables[1] = &n.Nametable1 39 | n.LogicalTables[2] = &n.Nametable1 40 | n.LogicalTables[3] = &n.Nametable1 41 | } 42 | } 43 | 44 | func (n *Nametable) writeNametableData(a int, v Word) { 45 | n.LogicalTables[(a&0xC00)>>10][a&0x3FF] = v 46 | } 47 | 48 | func (n *Nametable) readNametableData(a int) Word { 49 | return n.LogicalTables[(a&0xC00)>>10][a&0x3FF] 50 | } 51 | -------------------------------------------------------------------------------- /nes/nrom.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | // Nrom 4 | type Nrom struct { 5 | RomBanks [][]Word 6 | VromBanks [][]Word 7 | 8 | PrgBankCount int 9 | ChrRomCount int 10 | Battery bool 11 | Data []byte 12 | } 13 | 14 | func (m *Nrom) Load() { 15 | m.RomBanks = make([][]Word, m.PrgBankCount) 16 | for i := 0; i < m.PrgBankCount; i++ { 17 | // Move 16kb chunk to 16kb bank 18 | bank := make([]Word, 0x4000) 19 | for x := 0; x < 0x4000; x++ { 20 | bank[x] = Word(m.Data[(0x4000*i)+x]) 21 | } 22 | 23 | m.RomBanks[i] = bank 24 | } 25 | 26 | // Everything after PRG-ROM 27 | chrRom := m.Data[0x4000*len(m.RomBanks):] 28 | 29 | if m.ChrRomCount > 0 { 30 | m.VromBanks = make([][]Word, m.ChrRomCount*2) 31 | } else { 32 | m.VromBanks = make([][]Word, 2) 33 | } 34 | 35 | for i := 0; i < cap(m.VromBanks); i++ { 36 | // Move 16kb chunk to 16kb bank 37 | m.VromBanks[i] = make([]Word, 0x1000, 0x1000) 38 | 39 | // If the game doesn't have CHR banks we 40 | // just need to allocate VRAM 41 | 42 | for x := 0; x < 0x1000; x++ { 43 | var val Word 44 | if m.ChrRomCount == 0 { 45 | val = 0 46 | } else { 47 | val = Word(chrRom[(0x1000*i)+x]) 48 | } 49 | m.VromBanks[i][x] = val 50 | } 51 | } 52 | } 53 | 54 | func (m *Nrom) Write(v Word, a int) { 55 | // Nothing to do 56 | } 57 | 58 | func (m *Nrom) Read(a int) Word { 59 | if a >= 0xC000 { 60 | return m.RomBanks[len(m.RomBanks)-1][a&0x3FFF] 61 | } 62 | 63 | return m.RomBanks[0][a&0x3FFF] 64 | } 65 | 66 | func (m *Nrom) WriteVram(v Word, a int) { 67 | if a >= 0x1000 { 68 | m.VromBanks[len(m.VromBanks)-1][a&0xFFF] = v 69 | return 70 | } 71 | 72 | m.VromBanks[0][a&0xFFF] = v 73 | } 74 | 75 | func (m *Nrom) ReadVram(a int) Word { 76 | if a >= 0x1000 { 77 | return m.VromBanks[len(m.VromBanks)-1][a&0xFFF] 78 | } 79 | 80 | return m.VromBanks[0][a&0xFFF] 81 | } 82 | 83 | func (m *Nrom) ReadTile(a int) []Word { 84 | if a >= 0x1000 { 85 | return m.VromBanks[len(m.VromBanks)-1][a&0xFFF : a+16] 86 | } 87 | 88 | return m.VromBanks[0][a&0xFFF : a+16] 89 | } 90 | 91 | func (m *Nrom) BatteryBacked() bool { 92 | return m.Battery 93 | } 94 | -------------------------------------------------------------------------------- /nes/palette.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | var ( 4 | PaletteRgb = []uint32{ 5 | 0x666666, 0x002A88, 0x1412A7, 0x3B00A4, 0x5C007E, 6 | 0x6E0040, 0x6C0600, 0x561D00, 0x333500, 0x0B4800, 7 | 0x005200, 0x004F08, 0x00404D, 0x000000, 0x000000, 8 | 0x000000, 0xADADAD, 0x155FD9, 0x4240FF, 0x7527FE, 9 | 0xA01ACC, 0xB71E7B, 0xB53120, 0x994E00, 0x6B6D00, 10 | 0x388700, 0x0C9300, 0x008F32, 0x007C8D, 0x000000, 11 | 0x000000, 0x000000, 0xFFFEFF, 0x64B0FF, 0x9290FF, 12 | 0xC676FF, 0xF36AFF, 0xFE6ECC, 0xFE8170, 0xEA9E22, 13 | 0xBCBE00, 0x88D800, 0x5CE430, 0x45E082, 0x48CDDE, 14 | 0x4F4F4F, 0x000000, 0x000000, 0xFFFEFF, 0xC0DFFF, 15 | 0xD3D2FF, 0xE8C8FF, 0xFBC2FF, 0xFEC4EA, 0xFECCC5, 16 | 0xF7D8A5, 0xE4E594, 0xCFEF96, 0xBDF4AB, 0xB3F3CC, 17 | 0xB5EBF2, 0xB8B8B8, 0x000000, 0x000000, 18 | } 19 | ) 20 | -------------------------------------------------------------------------------- /nes/ppu_test.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var ( 8 | p *Ppu 9 | ) 10 | 11 | func verifyValue(a int, v Word, test *testing.T) { 12 | if p.Nametables.readNametableData(a) != v { 13 | test.Errorf("0x%X was 0x%X, expected 0x%X\n", a, p.Vram[0x2000], v) 14 | } 15 | } 16 | 17 | func TestVerticalNametableMirroring(test *testing.T) { 18 | p = new(Ppu) 19 | p.Init() 20 | 21 | p.Nametables.SetMirroring(MirroringVertical) 22 | 23 | p.VramAddress = 0x2000 24 | p.WriteData(0x11) 25 | p.VramAddress = 0x2110 26 | p.WriteData(0x22) 27 | p.VramAddress = 0x2220 28 | p.WriteData(0x33) 29 | p.VramAddress = 0x2330 30 | p.WriteData(0x44) 31 | p.VramAddress = 0x2338 32 | p.WriteData(0x55) 33 | 34 | verifyValue(0x2000, 0x11, test) 35 | verifyValue(0x2800, 0x11, test) 36 | 37 | verifyValue(0x2110, 0x22, test) 38 | verifyValue(0x2910, 0x22, test) 39 | 40 | verifyValue(0x2220, 0x33, test) 41 | verifyValue(0x2A20, 0x33, test) 42 | 43 | verifyValue(0x2330, 0x44, test) 44 | verifyValue(0x2B30, 0x44, test) 45 | 46 | verifyValue(0x2338, 0x55, test) 47 | verifyValue(0x2B38, 0x55, test) 48 | 49 | p.VramAddress = 0x2400 50 | p.WriteData(0x11) 51 | p.VramAddress = 0x2510 52 | p.WriteData(0x22) 53 | p.VramAddress = 0x2620 54 | p.WriteData(0x33) 55 | p.VramAddress = 0x2730 56 | p.WriteData(0x44) 57 | p.VramAddress = 0x2738 58 | p.WriteData(0x55) 59 | 60 | verifyValue(0x2400, 0x11, test) 61 | verifyValue(0x2C00, 0x11, test) 62 | 63 | verifyValue(0x2510, 0x22, test) 64 | verifyValue(0x2D10, 0x22, test) 65 | 66 | verifyValue(0x2620, 0x33, test) 67 | verifyValue(0x2E20, 0x33, test) 68 | 69 | verifyValue(0x2730, 0x44, test) 70 | verifyValue(0x2F30, 0x44, test) 71 | 72 | verifyValue(0x2738, 0x55, test) 73 | verifyValue(0x2F38, 0x55, test) 74 | } 75 | 76 | func TestHorizontalNametableMirroring(test *testing.T) { 77 | p = new(Ppu) 78 | p.Init() 79 | 80 | p.Nametables.SetMirroring(MirroringHorizontal) 81 | 82 | p.VramAddress = 0x2000 83 | p.WriteData(0x11) 84 | p.VramAddress = 0x2110 85 | p.WriteData(0x22) 86 | p.VramAddress = 0x2220 87 | p.WriteData(0x33) 88 | p.VramAddress = 0x2330 89 | p.WriteData(0x44) 90 | p.VramAddress = 0x2338 91 | p.WriteData(0x55) 92 | 93 | verifyValue(0x2000, 0x11, test) 94 | verifyValue(0x2400, 0x11, test) 95 | 96 | verifyValue(0x2110, 0x22, test) 97 | verifyValue(0x2510, 0x22, test) 98 | 99 | verifyValue(0x2220, 0x33, test) 100 | verifyValue(0x2620, 0x33, test) 101 | 102 | verifyValue(0x2330, 0x44, test) 103 | verifyValue(0x2730, 0x44, test) 104 | 105 | verifyValue(0x2338, 0x55, test) 106 | verifyValue(0x2738, 0x55, test) 107 | 108 | p.VramAddress = 0x2800 109 | p.WriteData(0x11) 110 | p.VramAddress = 0x2910 111 | p.WriteData(0x22) 112 | p.VramAddress = 0x2A20 113 | p.WriteData(0x33) 114 | p.VramAddress = 0x2B30 115 | p.WriteData(0x44) 116 | p.VramAddress = 0x2B38 117 | p.WriteData(0x55) 118 | 119 | verifyValue(0x2800, 0x11, test) 120 | verifyValue(0x2C00, 0x11, test) 121 | 122 | verifyValue(0x2910, 0x22, test) 123 | verifyValue(0x2D10, 0x22, test) 124 | 125 | verifyValue(0x2A20, 0x33, test) 126 | verifyValue(0x2E20, 0x33, test) 127 | 128 | verifyValue(0x2B30, 0x44, test) 129 | verifyValue(0x2F30, 0x44, test) 130 | 131 | verifyValue(0x2B38, 0x55, test) 132 | verifyValue(0x2F38, 0x55, test) 133 | } 134 | -------------------------------------------------------------------------------- /nes/rom.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | type Mapper interface { 9 | Write(v Word, a int) 10 | Read(a int) Word 11 | WriteVram(v Word, a int) 12 | ReadVram(a int) Word 13 | ReadTile(a int) []Word 14 | BatteryBacked() bool 15 | } 16 | 17 | func LoadRom(rom []byte) (m Mapper, e error) { 18 | r := new(Nrom) 19 | 20 | if string(rom[0:3]) != "NES" { 21 | return m, errors.New("Invalid ROM file") 22 | 23 | if rom[3] != 0x1a { 24 | return m, errors.New("Invalid ROM file") 25 | } 26 | } 27 | 28 | r.PrgBankCount = int(rom[4]) 29 | r.ChrRomCount = int(rom[5]) 30 | 31 | fmt.Printf("-----------------\nROM:\n ") 32 | 33 | fmt.Printf("PRG-ROM banks: %d (%d real)\n ", r.PrgBankCount, r.PrgBankCount) 34 | fmt.Printf("CHR-ROM banks: %d (%d real)\n ", 2*r.ChrRomCount, r.ChrRomCount) 35 | 36 | fmt.Printf("Mirroring: ") 37 | switch rom[6] & 0x1 { 38 | case 0x0: 39 | fmt.Printf("Horizontal\n ") 40 | ppu.Nametables.SetMirroring(MirroringHorizontal) 41 | case 0x1: 42 | fmt.Printf("Vertical\n ") 43 | ppu.Nametables.SetMirroring(MirroringVertical) 44 | } 45 | 46 | if (rom[6]>>0x1)&0x1 == 0x1 { 47 | r.Battery = true 48 | } 49 | 50 | r.Data = rom[16:] 51 | 52 | // Check mapper, get the proper type 53 | mapper := (Word(rom[6])>>4 | (Word(rom[7]) & 0xF0)) 54 | fmt.Printf("Mapper: 0x%X -> ", mapper) 55 | switch mapper { 56 | case 0x00: 57 | fallthrough 58 | case 0x40: 59 | fallthrough 60 | case 0x41: 61 | // NROM 62 | fmt.Printf("NROM\n") 63 | r.Load() 64 | return r, nil 65 | case 0x01: 66 | // MMC1 67 | fmt.Printf("MMC1\n") 68 | r.Load() 69 | m = NewMmc1(r) 70 | case 0x42: 71 | fallthrough 72 | case 0x02: 73 | // Unrom 74 | fmt.Printf("UNROM\n") 75 | r.Load() 76 | m = &Unrom{ 77 | RomBanks: r.RomBanks, 78 | VromBanks: r.VromBanks, 79 | PrgBankCount: r.PrgBankCount, 80 | ChrRomCount: r.ChrRomCount, 81 | Battery: r.Battery, 82 | Data: r.Data, 83 | } 84 | case 0x43: 85 | fallthrough 86 | case 0x03: 87 | // Cnrom 88 | fmt.Printf("CNROM\n") 89 | r.Load() 90 | m = &Cnrom{ 91 | RomBanks: r.RomBanks, 92 | VromBanks: r.VromBanks, 93 | PrgBankCount: r.PrgBankCount, 94 | ChrRomCount: r.ChrRomCount, 95 | Battery: r.Battery, 96 | Data: r.Data, 97 | } 98 | case 0x07: 99 | // Anrom 100 | fmt.Printf("ANROM\n") 101 | r.Load() 102 | m = &Anrom{ 103 | RomBanks: r.RomBanks, 104 | VromBanks: r.VromBanks, 105 | PrgBankCount: r.PrgBankCount, 106 | ChrRomCount: r.ChrRomCount, 107 | Battery: r.Battery, 108 | Data: r.Data, 109 | PrgUpperBank: len(r.RomBanks) - 1, 110 | } 111 | case 0x44: 112 | fallthrough 113 | case 0x04: 114 | // MMC3 115 | fmt.Printf("MMC3\n") 116 | m = NewMmc3(r) 117 | case 0x05: 118 | // MMC5 119 | fmt.Printf("MMC5\n") 120 | m = NewMmc5(r) 121 | case 0x09: 122 | // MMC2 123 | fmt.Printf("MMC2\n") 124 | m = NewMmc2(r) 125 | default: 126 | // Unsupported 127 | fmt.Printf("Unsupported\n") 128 | return m, errors.New(fmt.Sprintf("Unsupported memory mapper: 0x%X", mapper)) 129 | } 130 | 131 | fmt.Printf("-----------------\n") 132 | 133 | return 134 | } 135 | -------------------------------------------------------------------------------- /nes/unrom.go: -------------------------------------------------------------------------------- 1 | package nes 2 | 3 | type Unrom struct { 4 | RomBanks [][]Word 5 | VromBanks [][]Word 6 | 7 | PrgBankCount int 8 | ChrRomCount int 9 | Battery bool 10 | Data []byte 11 | 12 | ActiveBank int 13 | } 14 | 15 | func (m *Unrom) Write(v Word, a int) { 16 | m.ActiveBank = int(v & 0x7) 17 | } 18 | 19 | func (m *Unrom) Read(a int) Word { 20 | if a >= 0xC000 { 21 | return m.RomBanks[len(m.RomBanks)-1][a&0x3FFF] 22 | } 23 | 24 | return m.RomBanks[m.ActiveBank][a&0x3FFF] 25 | } 26 | 27 | func (m *Unrom) WriteVram(v Word, a int) { 28 | if a >= 0x1000 { 29 | m.VromBanks[len(m.VromBanks)-1][a&0xFFF] = v 30 | return 31 | } 32 | 33 | m.VromBanks[0][a&0xFFF] = v 34 | } 35 | 36 | func (m *Unrom) ReadVram(a int) Word { 37 | if a >= 0x1000 { 38 | return m.VromBanks[len(m.VromBanks)-1][a&0xFFF] 39 | } 40 | 41 | return m.VromBanks[0][a&0xFFF] 42 | } 43 | 44 | func (m *Unrom) ReadTile(a int) []Word { 45 | if a >= 0x1000 { 46 | a &= 0xFFF 47 | return m.VromBanks[len(m.VromBanks)-1][a : a+16] 48 | } 49 | 50 | a &= 0xFFF 51 | return m.VromBanks[0][a : a+16] 52 | } 53 | 54 | func (m *Unrom) BatteryBacked() bool { 55 | return m.Battery 56 | } 57 | -------------------------------------------------------------------------------- /test_roms/apu_mixer/dmc.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_mixer/dmc.nes -------------------------------------------------------------------------------- /test_roms/apu_mixer/noise.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_mixer/noise.nes -------------------------------------------------------------------------------- /test_roms/apu_mixer/readme.txt: -------------------------------------------------------------------------------- 1 | NES APU Mixer Tests 2 | ------------------- 3 | These tests verify proper operation of the NES APU's sound channel 4 | mixer, including relative volumes of channels and non-linear mixing. 5 | Tests MUST be run from a freshly-powered NES, as this is the only way to 6 | ensure that the triangle wave doesn't interfere. 7 | 8 | All tests beep, play a test sound, then beep again. For all but the 9 | noise test, there should be near silence between the beeps. For the 10 | noise test, noise will fade in and out. There shouldn't be any 11 | noticeable tone when heard through a speaker (through headphones, faint 12 | tones might be audible). 13 | 14 | 15 | Internal operation 16 | ------------------ 17 | The tests have the channel under test generate a tone, then generate the 18 | inverse waveform using the DMC DAC, canceling to (near) silence if 19 | everything is correct. 20 | 21 | The DMC test verifies that non-linearity of the DMC DAC. The noise and 22 | triangle tests verify relative volume of the noise and triangle to the 23 | DMC, and that the DMC DAC affects attenuation of them properly. Finally, 24 | the square test verifies relative volume of the squares to the DMC, 25 | non-linearity of the square DACs, how one square affects the other 26 | (slightly), and that the square DAC non-linearity is separate from the 27 | DMC. 28 | 29 | 30 | Flashes, clicks, other glitches 31 | ------------------------------- 32 | If a test prints "passed", it passed, even if there were some flashes or 33 | odd sounds. Only a test which prints "done" at the end requires that you 34 | watch/listen while it runs in order to determine whether it passed. Such 35 | tests involve things which the CPU cannot directly test. 36 | 37 | 38 | Alternate output 39 | ---------------- 40 | Tests generally print information on screen, but also report the final 41 | result audibly, and output text to memory, in case the PPU doesn't work 42 | or there isn't one, as in an NSF or a NES emulator early in development. 43 | 44 | After the tests are done, the final result is reported as a series of 45 | beeps (see below). For NSF builds, any important diagnostic bytes are 46 | also reported as beeps, before the final result. 47 | 48 | 49 | Output at $6000 50 | --------------- 51 | All text output is written starting at $6004, with a zero-byte 52 | terminator at the end. As more text is written, the terminator is moved 53 | forward, so an emulator can print the current text at any time. 54 | 55 | The test status is written to $6000. $80 means the test is running, $81 56 | means the test needs the reset button pressed, but delayed by at least 57 | 100 msec from now. $00-$7F means the test has completed and given that 58 | result code. 59 | 60 | To allow an emulator to know when one of these tests is running and the 61 | data at $6000+ is valid, as opposed to some other NES program, $DE $B0 62 | $G1 is written to $6001-$6003. 63 | 64 | 65 | Audible output 66 | -------------- 67 | A byte is reported as a series of tones. The code is in binary, with a 68 | low tone for 0 and a high tone for 1, and with leading zeroes skipped. 69 | The first tone is always a zero. A final code of 0 means passed, 1 means 70 | failure, and 2 or higher indicates a specific reason. See the source 71 | code of the test for more information about the meaning of a test code. 72 | They are found after the set_test macro. For example, the cause of test 73 | code 3 would be found in a line containing set_test 3. Examples: 74 | 75 | Tones Binary Decimal Meaning 76 | - - - - - - - - - - - - - - - - - - - - 77 | low 0 0 passed 78 | low high 01 1 failed 79 | low high low 010 2 error 2 80 | 81 | 82 | NSF versions 83 | ------------ 84 | Many NSF-based tests require that the NSF player either not interrupt 85 | the init routine with the play routine, or if it does, not interrupt the 86 | play routine again if it hasn't returned yet. This is because many tests 87 | need to run for a while without returning. 88 | 89 | NSF versions also make periodic clicks to prevent the NSF player from 90 | thinking the track is silent and thus ending the track before it's done 91 | testing. 92 | 93 | -- 94 | Shay Green 95 | -------------------------------------------------------------------------------- /test_roms/apu_mixer/square.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_mixer/square.nes -------------------------------------------------------------------------------- /test_roms/apu_mixer/triangle.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_mixer/triangle.nes -------------------------------------------------------------------------------- /test_roms/apu_reset/4015_cleared.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_reset/4015_cleared.nes -------------------------------------------------------------------------------- /test_roms/apu_reset/4017_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_reset/4017_timing.nes -------------------------------------------------------------------------------- /test_roms/apu_reset/4017_written.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_reset/4017_written.nes -------------------------------------------------------------------------------- /test_roms/apu_reset/irq_flag_cleared.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_reset/irq_flag_cleared.nes -------------------------------------------------------------------------------- /test_roms/apu_reset/len_ctrs_enabled.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_reset/len_ctrs_enabled.nes -------------------------------------------------------------------------------- /test_roms/apu_reset/works_immediately.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_reset/works_immediately.nes -------------------------------------------------------------------------------- /test_roms/apu_test/apu_test.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/apu_test.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/1-len_ctr.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/1-len_ctr.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/2-len_table.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/2-len_table.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/3-irq_flag.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/3-irq_flag.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/4-jitter.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/4-jitter.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/5-len_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/5-len_timing.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/6-irq_flag_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/6-irq_flag_timing.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/7-dmc_basics.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/7-dmc_basics.nes -------------------------------------------------------------------------------- /test_roms/apu_test/rom_singles/8-dmc_rates.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_test/rom_singles/8-dmc_rates.nes -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/README.txt: -------------------------------------------------------------------------------- 1 | Volume tests for NES 2 | 3 | _____________________________________________________________________ 4 | Background 5 | 6 | The NES has four tone generator channels and one digital sample 7 | playback channel: 8 | 9 | 1. Rectangular pulse ("square") wave 10 | 2. Another square wave 11 | 3. 32-step triangle wave 12 | 4. Binary noise generated by a linear feedback shift register 13 | 5. Delta pulse code modulation; also allows writes of raw LPCM to 14 | the counter for use as a generic 7-bit DAC 15 | 16 | Unlike systems such as the GBA, which digitally add all channels 17 | before passing them to a DAC, the NES has a separate DAC for each 18 | channel and mixes them analog. Nonlinearities in this mixing can 19 | cause one channel to affect the volume of another channel. 20 | 21 | The NES uses an unsigned DAC, meaning that each channel can generate 22 | only positive signal values. Such a DAC generates a lot of DC, and 23 | the NES has a high-pass filter on its audio output to block the DC. 24 | Different emulators use different time constants on their DC filters, 25 | which human listeners generally can't perceive. So you can't just 26 | measure the maximum voltage; you have to measure the difference 27 | between the high and low values. 28 | 29 | Different emulators use different amounts of headroom in the 16-bit 30 | range, depending on what Famicom expansion audio chips are present. 31 | So you have to compare relative volumes, not absolute volumes. 32 | 33 | _____________________________________________________________________ 34 | The test pattern 35 | 36 | This program demonstrates the channel balance among implementations 37 | of the NES architecture. 38 | 39 | The pattern consists of a set of 12 tones, as close to 1000 Hz as 40 | the NES allows: 41 | 1. Channel 1, 1/8 duty 42 | 2. Channel 1, 1/4 duty 43 | 3. Channel 1, 1/2 duty 44 | 4. Channel 1, 3/4 duty 45 | 5. Channels 1 and 2, 1/8 duty 46 | 6. Channels 1 and 2, 1/4 duty 47 | 7. Channels 1 and 2, 1/2 duty 48 | 8. Channels 1 and 2, 3/4 duty 49 | 9. Channel 3 50 | 10. Channel 4, long LFSR period 51 | 11. Channel 4, short LFSR period 52 | 12. Channel 5, amplitude 30 53 | 54 | When the user presses A on controller 1, the pattern plays three 55 | times, with channel 5 held steady at 0, 48, and 96. The high point 56 | of tone 12 each time is 30 units above the level for that time, 57 | that is, 30, 78, and 126 respectively. 58 | 59 | _____________________________________________________________________ 60 | Recordings 61 | 62 | The files in the 'recordings' folder are recordings of volumes.nes 63 | run in various environments. They were recorded at 44100 Hz and then 64 | encoded using OggDropXPd 1.90 (libvorbis 1.2.0) at -q 7.00. 65 | 66 | * nes-001.ogg: Nintendo Entertainment System (NTSC U/C) with PowerPak 67 | * nestopia.ogg: Nestopia 1.40 68 | * nintendulator.ogg: Nintendulator snapshot 2009-02-28 69 | * fceux.ogg: FCEUX 2.0.4-interim 2008-11-24 70 | 71 | _____________________________________________________________________ 72 | Legal 73 | 74 | Copyright (c) 2009 Damian Yerrick 75 | 76 | The program and manual are under the following license: 77 | 78 | This work is provided 'as-is', without any express or implied 79 | warranty. In no event will the authors be held liable for any 80 | damages arising from the use of this work. 81 | 82 | Permission is granted to anyone to use this work for any 83 | purpose, including commercial applications, and to alter it and 84 | redistribute it freely, subject to the following restrictions: 85 | 86 | 1. The origin of this work must not be misrepresented; you 87 | must not claim that you wrote the original work. If you use 88 | this work in a product, an acknowledgment in the product 89 | documentation would be appreciated but is not required. 90 | 2. Altered source versions must be plainly marked as such, 91 | and must not be misrepresented as being the original work. 92 | 3. This notice may not be removed or altered from any 93 | source distribution. 94 | 95 | The term "source" refers to the preferred form of a work for making 96 | changes to it. 97 | 98 | -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/makefile: -------------------------------------------------------------------------------- 1 | CC65 = /e/nesdev/cc65/bin 2 | AS65 = $(CC65)/ca65.exe 3 | LD65 = $(CC65)/ld65.exe 4 | #EMU = /e/games/nes/fceu080win/fceu.exe 5 | EMU := /e/games/nes/nintendulator0900bin/Nintendulator.exe 6 | CC = gcc 7 | DOTEXE=.exe 8 | CFLAGS = -std=gnu99 -Wall -DNDEBUG -O 9 | CFLAGS65 = 10 | objdir = obj/nes 11 | srcdir = src 12 | 13 | objlist = hello pads sound 14 | objlistntsc = $(foreach o,$(objlist),$(objdir)/$(o).o) 15 | 16 | .PHONY: run 17 | 18 | run: volumes.nes 19 | $(EMU) $< 20 | 21 | $(objdir)/%.o: $(srcdir)/%.s 22 | $(AS65) $(CFLAGS65) $< -o $@ 23 | 24 | $(objdir)/%.o: $(objdir)/%.s 25 | $(AS65) $(CFLAGS65) $< -o $@ 26 | 27 | map.txt volumes.prg: nes.ini $(objlistntsc) 28 | $(LD65) -C $^ -m map.txt -o volumes.prg 29 | 30 | %.nes: %.prg empty.chr 31 | cat $^ > $@ 32 | -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/nes.ini: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | ZP: start = $10, size = $f0, type = rw; 3 | # use first $10 zeropage locations as locals 4 | HEADER: start = $0000, size = $0010, type = ro, file = %O, fill=yes, fillval=$00; 5 | RAM: start = $0300, size = $0500, type = rw; 6 | ROM: start = $C000, size = $4000, type = ro, file = %O, fill=yes, fillval=$FF; 7 | } 8 | 9 | SEGMENTS { 10 | INESHDR: load = HEADER, type = ro, align = $10; 11 | ZEROPAGE: load = ZP, type = zp; 12 | BSS: load = RAM, type = bss, define = yes, align = $100; 13 | CODE: load = ROM, type = ro, align = $100; 14 | RODATA: load = ROM, type = ro, align = $100; 15 | DMC: load = ROM, type = ro, start = $C000, optional = yes; 16 | VECTORS: load = ROM, type = ro, start = $FFFA; 17 | } 18 | 19 | FILES { 20 | %O: format = bin; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/obj/nes/khan: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_volume_tests/obj/nes/khan -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/recordings/fceux.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_volume_tests/recordings/fceux.ogg -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/recordings/nes-001.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_volume_tests/recordings/nes-001.ogg -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/recordings/nestopia.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_volume_tests/recordings/nestopia.ogg -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/recordings/nintendulator.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_volume_tests/recordings/nintendulator.ogg -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/volumes.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/apu_volume_tests/volumes.nes -------------------------------------------------------------------------------- /test_roms/apu_volume_tests/zip.in: -------------------------------------------------------------------------------- 1 | obj/nes/khan 2 | empty.chr 3 | makefile 4 | nes.ini 5 | volumes.nes 6 | recordings/nes-001.ogg 7 | recordings/nestopia.ogg 8 | recordings/nintendulator.ogg 9 | recordings/fceux.ogg 10 | src/pads.s 11 | src/hello.s 12 | src/sound.s 13 | README.txt 14 | zip.in -------------------------------------------------------------------------------- /test_roms/blargg_cpu/all_instrs.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/all_instrs.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/official_only.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/official_only.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/official_only.sav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/official_only.sav -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/01-implied.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/01-implied.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/02-immediate.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/02-immediate.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/03-zero_page.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/03-zero_page.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/04-zp_xy.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/04-zp_xy.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/05-absolute.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/05-absolute.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/06-abs_xy.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/06-abs_xy.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/07-ind_x.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/07-ind_x.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/08-ind_y.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/08-ind_y.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/09-branches.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/09-branches.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/10-stack.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/10-stack.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/11-jmp_jsr.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/11-jmp_jsr.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/12-rts.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/12-rts.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/13-rti.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/13-rti.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/14-brk.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/14-brk.nes -------------------------------------------------------------------------------- /test_roms/blargg_cpu/rom_singles/15-special.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_cpu/rom_singles/15-special.nes -------------------------------------------------------------------------------- /test_roms/blargg_ppu/palette_ram.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_ppu/palette_ram.nes -------------------------------------------------------------------------------- /test_roms/blargg_ppu/power_up_palette.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_ppu/power_up_palette.nes -------------------------------------------------------------------------------- /test_roms/blargg_ppu/readme.txt: -------------------------------------------------------------------------------- 1 | NTSC NES PPU Tests 2 | ------------------ 3 | These ROMs test a few aspects of the NTSC NES PPU operation. They have been 4 | tested on an actual NES and all give a passing result. I wrote them to verify 5 | that my NES emulator's PPU was working properly. 6 | 7 | Each ROM runs several tests and reports a result code on screen and by beeping 8 | a number of times. A result code of 1 always indicates that all tests were 9 | passed; see below for the meaning of other codes for each test. 10 | 11 | The main source code for each test is included, and most tests are clearly 12 | divided into sections. Some of the common support code is included, but not 13 | all, since it runs on a custom setup. Contact me if you want to assemble the 14 | tests yourself. 15 | 16 | Shay Green (swap to e-mail) 17 | 18 | 19 | palette_ram 20 | ----------- 21 | PPU palette RAM read/write and mirroring test 22 | 23 | 1) Tests passed 24 | 2) Palette read shouldn't be buffered like other VRAM 25 | 3) Palette write/read doesn't work 26 | 4) Palette should be mirrored within $3f00-$3fff 27 | 5) Write to $10 should be mirrored at $00 28 | 6) Write to $00 should be mirrored at $10 29 | 30 | 31 | power_up_palette 32 | ---------------- 33 | Reports whether initial values in palette at power-up match those 34 | that my NES has. These values are probably unique to my NES. 35 | 36 | 1) Palette matches 37 | 2) Palette differs from table 38 | 39 | 40 | sprite_ram 41 | ---------- 42 | Tests sprite RAM access via $2003, $2004, and $4014 43 | 44 | 1) Tests passed 45 | 2) Basic read/write doesn't work 46 | 3) Address should increment on $2004 write 47 | 4) Address should not increment on $2004 read 48 | 5) Third sprite bytes should be masked with $e3 on read 49 | 6) $4014 DMA copy doesn't work at all 50 | 7) $4014 DMA copy should start at value in $2003 and wrap 51 | 8) $4014 DMA copy should leave value in $2003 intact 52 | 53 | 54 | vbl_clear_time 55 | -------------- 56 | The VBL flag ($2002.7) is cleared by the PPU around 2270 CPU clocks 57 | after NMI occurs. 58 | 59 | 1) Tests passed 60 | 2) VBL flag cleared too soon 61 | 3) VBL flag cleared too late 62 | 63 | 64 | vram_access 65 | ----------- 66 | Tests PPU VRAM read/write and internal read buffer operation 67 | 68 | 1) Tests passed 69 | 2) VRAM reads should be delayed in a buffer 70 | 3) Basic Write/read doesn't work 71 | 4) Read buffer shouldn't be affected by VRAM write 72 | 5) Read buffer shouldn't be affected by palette write 73 | 6) Palette read should also read VRAM into read buffer 74 | 7) "Shadow" VRAM read unaffected by palette transparent color mirroring 75 | -------------------------------------------------------------------------------- /test_roms/blargg_ppu/sprite_ram.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_ppu/sprite_ram.nes -------------------------------------------------------------------------------- /test_roms/blargg_ppu/vbl_clear_time.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_ppu/vbl_clear_time.nes -------------------------------------------------------------------------------- /test_roms/blargg_ppu/vram_access.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/blargg_ppu/vram_access.nes -------------------------------------------------------------------------------- /test_roms/branch_timing_tests/1.Branch_Basics.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/branch_timing_tests/1.Branch_Basics.nes -------------------------------------------------------------------------------- /test_roms/branch_timing_tests/2.Backward_Branch.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/branch_timing_tests/2.Backward_Branch.nes -------------------------------------------------------------------------------- /test_roms/branch_timing_tests/3.Forward_Branch.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/branch_timing_tests/3.Forward_Branch.nes -------------------------------------------------------------------------------- /test_roms/branch_timing_tests/readme.txt: -------------------------------------------------------------------------------- 1 | NES 6502 Branch Timing Test ROMs 2 | -------------------------------- 3 | These ROMs test timing of the branch instruction, including edge cases 4 | which an emulator might get wrong. When run on a NES they all give a 5 | passing result. Each ROM runs several tests and reports the result on 6 | screen and by beeping a number of times. See below for the meaning of 7 | failure codes for each test. THE TESTS MUST BE RUN (*AND* *PASS*) IN 8 | ORDER, because some earlier ROMs test things that later ones assume will 9 | work properly. 10 | 11 | Source code for each test is included, and most tests are clearly 12 | divided into sections. Support code is also included, but it runs on a 13 | custom devcart and assembler so it will require some effort to assemble. 14 | Contact me if you'd like assistance porting them to your setup. 15 | 16 | 17 | Branch Timing Summary 18 | --------------------- 19 | An untaken branch takes 2 clocks. A taken branch takes 3 clocks. A taken 20 | branch that crosses a page takes 4 clocks. Page crossing occurs when the 21 | high byte of the branch target address is different than the high byte 22 | of address of the next instruction: 23 | 24 | branch_target: 25 | ... 26 | bne branch_target 27 | next_instruction: 28 | nop 29 | ... 30 | branch_target: 31 | 32 | 33 | 1.Branch_Basics 34 | --------------- 35 | Tests branch timing basics and PPU NMI timing, which is needed for the 36 | tests 37 | 38 | 2) NMI period is too short 39 | 3) NMI period is too too long 40 | 4) Branch not taken is too long 41 | 5) Branch not taken is too short 42 | 6) Branch taken is too long 43 | 7) Branch taken is too short 44 | 45 | 46 | 2.Backward_Branch 47 | ----------------- 48 | Tests backward (negative) branch timing. 49 | 50 | 2) Branch from $E4FD to $E4FC is too long 51 | 3) Branch from $E4FD to $E4FC is too short 52 | 4) Branch from $E5FE to $E5FD is too long 53 | 5) Branch from $E5FE to $E5FD is too short 54 | 6) Branch from $E700 to $E6FF is too long 55 | 7) Branch from $E700 to $E6FF is too short 56 | 8) Branch from $E801 to $E800 is too long 57 | 9) Branch from $E801 to $E800 is too short 58 | 59 | 60 | 3.Forward_Branch 61 | ---------------- 62 | Tests forward (positive) branch timing. 63 | 64 | 2) Branch from $E5FC to $E5FF is too long 65 | 3) Branch from $E5FC to $E5FF is too short 66 | 4) Branch from $E6FD to $E700 is too long 67 | 5) Branch from $E6FD to $E700 is too short 68 | 6) Branch from $E7FE to $E801 is too long 69 | 7) Branch from $E7FE to $E801 is too short 70 | 8) Branch from $E8FF to $E902 is too long 71 | 9) Branch from $E8FF to $E902 is too short 72 | 73 | -- 74 | Shay Green 75 | -------------------------------------------------------------------------------- /test_roms/cpu_timing_test6/cpu_timing_test.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/cpu_timing_test6/cpu_timing_test.nes -------------------------------------------------------------------------------- /test_roms/mmc3_test_2/rom_singles/1-clocking.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/mmc3_test_2/rom_singles/1-clocking.nes -------------------------------------------------------------------------------- /test_roms/mmc3_test_2/rom_singles/2-details.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/mmc3_test_2/rom_singles/2-details.nes -------------------------------------------------------------------------------- /test_roms/mmc3_test_2/rom_singles/3-A12_clocking.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/mmc3_test_2/rom_singles/3-A12_clocking.nes -------------------------------------------------------------------------------- /test_roms/mmc3_test_2/rom_singles/4-scanline_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/mmc3_test_2/rom_singles/4-scanline_timing.nes -------------------------------------------------------------------------------- /test_roms/mmc3_test_2/rom_singles/5-MMC3.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/mmc3_test_2/rom_singles/5-MMC3.nes -------------------------------------------------------------------------------- /test_roms/mmc3_test_2/rom_singles/6-MMC3_alt.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/mmc3_test_2/rom_singles/6-MMC3_alt.nes -------------------------------------------------------------------------------- /test_roms/nesstress.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/nesstress.nes -------------------------------------------------------------------------------- /test_roms/nestest.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/nestest.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/ppu_vbl_nmi.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/ppu_vbl_nmi.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/01-vbl_basics.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/01-vbl_basics.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/02-vbl_set_time.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/02-vbl_set_time.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/03-vbl_clear_time.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/03-vbl_clear_time.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/04-nmi_control.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/04-nmi_control.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/05-nmi_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/05-nmi_timing.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/06-suppression.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/06-suppression.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/07-nmi_on_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/07-nmi_on_timing.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/08-nmi_off_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/08-nmi_off_timing.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/09-even_odd_frames.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/09-even_odd_frames.nes -------------------------------------------------------------------------------- /test_roms/ppu_vbl_nmi/rom_singles/10-even_odd_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/ppu_vbl_nmi/rom_singles/10-even_odd_timing.nes -------------------------------------------------------------------------------- /test_roms/scanline_scanline.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/scanline_scanline.nes -------------------------------------------------------------------------------- /test_roms/scrolltest_scroll.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/scrolltest_scroll.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/01.basics.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/01.basics.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/02.alignment.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/02.alignment.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/03.corners.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/03.corners.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/04.flip.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/04.flip.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/05.left_clip.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/05.left_clip.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/06.right_edge.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/06.right_edge.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/07.screen_bottom.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/07.screen_bottom.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/08.double_height.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/08.double_height.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/09.timing_basics.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/09.timing_basics.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/10.timing_order.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/10.timing_order.nes -------------------------------------------------------------------------------- /test_roms/sprite_hit_tests_2005.10.05/11.edge_timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_hit_tests_2005.10.05/11.edge_timing.nes -------------------------------------------------------------------------------- /test_roms/sprite_overflow/sprite_overflow_tests_1.Basics.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_overflow/sprite_overflow_tests_1.Basics.nes -------------------------------------------------------------------------------- /test_roms/sprite_overflow/sprite_overflow_tests_2.Details.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_overflow/sprite_overflow_tests_2.Details.nes -------------------------------------------------------------------------------- /test_roms/sprite_overflow/sprite_overflow_tests_3.Timing.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_overflow/sprite_overflow_tests_3.Timing.nes -------------------------------------------------------------------------------- /test_roms/sprite_overflow/sprite_overflow_tests_4.Obscure.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_overflow/sprite_overflow_tests_4.Obscure.nes -------------------------------------------------------------------------------- /test_roms/sprite_overflow/sprite_overflow_tests_5.Emulator.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scottferg/Fergulator/18eddd0cdcd145f14b5319db39e1ebde069579c3/test_roms/sprite_overflow/sprite_overflow_tests_5.Emulator.nes -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of go-gl/gl authors for copyright purposes. 2 | 3 | # Seed: $ git shortlog -e | egrep '^\S+' | sed -E 's|(.*<.*>).*|\1|g' 4 | 5 | # Please keep the list sorted. 6 | 7 | # Name (optional github handle) 8 | 9 | Arne Doering 10 | Chris Jones 11 | Christoph Schunk 12 | David Aguilar (davvid) 13 | DeedleFake 14 | Dennis Honeyman 15 | Emil Arfvidsson 16 | Fabian Wickborn 17 | Henry Finucane 18 | Jacob Parker 19 | Jannis 20 | Jim Arnold (jimarnold) 21 | Jim Teeuwen (jteeuwen) 22 | Josh Smith 23 | Jragonmiris 24 | Kirill A. Shutemov (kiryl) 25 | Laurie Clark-Michalek 26 | Lawrence E. Bakst (tildeleb) 27 | Matt Kovars 28 | Miroslav Puda (pakanek) 29 | Niriel 30 | Noel Cower (nilium) 31 | Peter Waller (pwaller) 32 | Piotr Praszmo (banthar) 33 | PolyFloyd (PolyFloyd) 34 | Przemyslaw Szczepaniak 35 | Tom Myers 36 | Vova 37 | Yohann R. Coppel 38 | pkkp 39 | rhencke 40 | shogg 41 | tbruyelle 42 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The go-gl Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of go-gl nor the names of its contributors may be used 14 | to endorse or promote products derived from this software without specific 15 | prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/attriblocation.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | // AttribLocation 11 | 12 | type AttribLocation int 13 | 14 | func (indx AttribLocation) Attrib1f(x float32) { 15 | C.glVertexAttrib1f(C.GLuint(indx), C.GLfloat(x)) 16 | } 17 | 18 | func (indx AttribLocation) Attrib1fv(values *[1]float32) { 19 | C.glVertexAttrib1fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) 20 | } 21 | 22 | func (indx AttribLocation) Attrib2f(x float32, y float32) { 23 | C.glVertexAttrib2f(C.GLuint(indx), C.GLfloat(x), C.GLfloat(y)) 24 | } 25 | 26 | func (indx AttribLocation) Attrib2fv(values *[2]float32) { 27 | C.glVertexAttrib2fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) 28 | } 29 | 30 | func (indx AttribLocation) Attrib3f(x float32, y float32, z float32) { 31 | C.glVertexAttrib3f(C.GLuint(indx), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) 32 | } 33 | 34 | func (indx AttribLocation) Attrib3fv(values *[3]float32) { 35 | C.glVertexAttrib3fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) 36 | } 37 | 38 | func (indx AttribLocation) Attrib4f(x float32, y float32, z float32, w float32) { 39 | C.glVertexAttrib4f(C.GLuint(indx), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z), C.GLfloat(w)) 40 | } 41 | 42 | func (indx AttribLocation) Attrib4fv(values *[4]float32) { 43 | C.glVertexAttrib4fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) 44 | } 45 | 46 | func (indx AttribLocation) AttribPointer(size uint, typ GLenum, normalized bool, stride int, pointer interface{}) { 47 | C.glVertexAttribPointer(C.GLuint(indx), C.GLint(size), C.GLenum(typ), 48 | glBool(normalized), C.GLsizei(stride), ptr(pointer)) 49 | } 50 | 51 | func (indx AttribLocation) EnableArray() { 52 | C.glEnableVertexAttribArray(C.GLuint(indx)) 53 | } 54 | 55 | func (indx AttribLocation) DisableArray() { 56 | C.glDisableVertexAttribArray(C.GLuint(indx)) 57 | } 58 | 59 | func (indx AttribLocation) AttribDivisor(divisor int) { 60 | C.glVertexAttribDivisor(C.GLuint(indx), C.GLuint(divisor)) 61 | } 62 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/buffer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | import "unsafe" 10 | import "reflect" 11 | 12 | // Buffer Objects 13 | 14 | type Buffer Object 15 | 16 | // Create single buffer object 17 | func GenBuffer() Buffer { 18 | var b C.GLuint 19 | C.glGenBuffers(1, &b) 20 | return Buffer(b) 21 | } 22 | 23 | // Fill slice with new buffers 24 | func GenBuffers(buffers []Buffer) { 25 | if len(buffers) > 0 { 26 | C.glGenBuffers(C.GLsizei(len(buffers)), (*C.GLuint)(&buffers[0])) 27 | } 28 | } 29 | 30 | // Delete buffer object 31 | func (buffer Buffer) Delete() { 32 | b := C.GLuint(buffer) 33 | C.glDeleteBuffers(1, &b) 34 | } 35 | 36 | // Delete all buffers in slice 37 | func DeleteBuffers(buffers []Buffer) { 38 | if len(buffers) > 0 { 39 | C.glDeleteBuffers(C.GLsizei(len(buffers)), (*C.GLuint)(&buffers[0])) 40 | } 41 | } 42 | 43 | // Bind this buffer as target 44 | func (buffer Buffer) Bind(target GLenum) { 45 | C.glBindBuffer(C.GLenum(target), C.GLuint(buffer)) 46 | } 47 | 48 | // Remove buffer binding 49 | func (buffer Buffer) Unbind(target GLenum) { 50 | C.glBindBuffer(C.GLenum(target), C.GLuint(0)) 51 | } 52 | 53 | // Bind this buffer as index of target 54 | func (buffer Buffer) BindBufferBase(target GLenum, index uint) { 55 | C.glBindBufferBase(C.GLenum(target), C.GLuint(index), C.GLuint(buffer)) 56 | } 57 | 58 | // Bind this buffer range as index of target 59 | func (buffer Buffer) BindBufferRange(target GLenum, index uint, offset int, size uint) { 60 | C.glBindBufferRange(C.GLenum(target), C.GLuint(index), C.GLuint(buffer), C.GLintptr(offset), C.GLsizeiptr(size)) 61 | } 62 | 63 | // Creates and initializes a buffer object's data store 64 | func BufferData(target GLenum, size int, data interface{}, usage GLenum) { 65 | C.glBufferData(C.GLenum(target), C.GLsizeiptr(size), ptr(data), C.GLenum(usage)) 66 | } 67 | 68 | // Update a subset of a buffer object's data store 69 | func BufferSubData(target GLenum, offset int, size int, data interface{}) { 70 | C.glBufferSubData(C.GLenum(target), C.GLintptr(offset), C.GLsizeiptr(size), 71 | ptr(data)) 72 | } 73 | 74 | // Returns a subset of a buffer object's data store 75 | func GetBufferSubData(target GLenum, offset int, size int, data interface{}) { 76 | C.glGetBufferSubData(C.GLenum(target), C.GLintptr(offset), 77 | C.GLsizeiptr(size), ptr(data)) 78 | } 79 | 80 | // Map a buffer object's data store 81 | func MapBuffer(target GLenum, access GLenum) unsafe.Pointer { 82 | return unsafe.Pointer(C.glMapBuffer(C.GLenum(target), C.GLenum(access))) 83 | } 84 | 85 | // Maps the buffer with MapBuffer() and returns a pointer to the slice pointing 86 | // to the mapped buffer. See also the MapBuffer convenience functions. 87 | // WARNING: This function makes use of reflect.SliceHeader which may reduce 88 | // portability of your application. See the reflect.SliceHeader documentation 89 | // for more information. 90 | func MapBufferSlice(target GLenum, access GLenum, bytesPerElement int) unsafe.Pointer { 91 | rawLength := int(GetBufferParameteriv(target, BUFFER_SIZE)) 92 | return unsafe.Pointer(&reflect.SliceHeader{ 93 | Data: uintptr(MapBuffer(target, access)), 94 | Len: rawLength / bytesPerElement, 95 | Cap: rawLength / bytesPerElement, 96 | }) 97 | } 98 | 99 | // Map a buffer object's data store and return it as a slice 100 | func MapBufferFloat32(target GLenum, access GLenum) []float32 { 101 | return *(*[]float32)(MapBufferSlice(target, access, 4)) 102 | } 103 | 104 | // Map a buffer object's data store and return it as a slice 105 | func MapBufferUint32(target GLenum, access GLenum) []uint32 { 106 | return *(*[]uint32)(MapBufferSlice(target, access, 4)) 107 | } 108 | 109 | // Unmap a buffer object's data store 110 | func UnmapBuffer(target GLenum) bool { 111 | return goBool(C.glUnmapBuffer(C.GLenum(target))) 112 | } 113 | 114 | // Return buffer pointer 115 | func GetBufferPointerv(target GLenum, pname GLenum) unsafe.Pointer { 116 | var ptr unsafe.Pointer 117 | C.glGetBufferPointerv(C.GLenum(target), C.GLenum(pname), &ptr) 118 | return ptr 119 | } 120 | 121 | // Return parameters of a buffer object 122 | func GetBufferParameteriv(target GLenum, pname GLenum) int32 { 123 | var param C.GLint 124 | C.glGetBufferParameteriv(C.GLenum(target), C.GLenum(pname), ¶m) 125 | return int32(param) 126 | } 127 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/debugoutput.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | import "unsafe" 8 | 9 | // #include "gl.h" 10 | // 11 | // void goDebugCB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, char *message); 12 | // 13 | // static inline void debugProcCB(GLenum source, 14 | // GLenum type, 15 | // GLuint id, 16 | // GLenum severity, 17 | // GLsizei length, 18 | // const GLchar* message, 19 | // void* userParam) 20 | // { 21 | // goDebugCB(source, type, id, severity, length, (char *)message); 22 | // } 23 | // 24 | // static inline void glDebugMessageCB(void) 25 | // { 26 | // glDebugMessageCallbackARB(debugProcCB, NULL); 27 | // } 28 | // 29 | // /* 30 | // * Depending on glew version 'message' could be 'GLchar*' or 'char*' which 31 | // * causes problems in more strict Go type system. Let's work it around in C 32 | // */ 33 | // static inline void __glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, 34 | // GLsizei length, const char *message) 35 | // { 36 | // glDebugMessageInsertARB(source, type, id, severity, length, message); 37 | // } 38 | // 39 | // static inline void GetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, 40 | // GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, char *messageLog) 41 | // { 42 | // glGetDebugMessageLogARB(count, bufSize, sources, types, ids, severities, lengths, messageLog); 43 | // } 44 | import "C" 45 | 46 | type debugProc func(source GLenum, typ GLenum, id uint, severity GLenum, message string) 47 | 48 | var debugCB debugProc 49 | 50 | //export goDebugCB 51 | func goDebugCB(source GLenum, typ GLenum, id GLuint, severity GLenum, length GLsizei, message *C.char) { 52 | debugCB(source, typ, uint(id), severity, C.GoStringN(message, C.int(length))) 53 | } 54 | 55 | func DebugMessageCallback(cbfunc debugProc) { 56 | if cbfunc == nil { 57 | C.glDebugMessageCallbackARB(nil, nil) 58 | } else { 59 | debugCB = cbfunc 60 | C.glDebugMessageCB() 61 | } 62 | } 63 | 64 | func DebugMessageControl(source GLenum, typ GLenum, severity GLenum, ids []uint, enabled bool) { 65 | C.glDebugMessageControlARB(C.GLenum(source), C.GLenum(typ), C.GLenum(severity), 66 | C.GLsizei(len(ids)), (*C.GLuint)(unsafe.Pointer(&ids)), glBool(enabled)) 67 | } 68 | 69 | func DebugMessageInsert(source GLenum, typ GLenum, id uint, severity GLenum, message string) { 70 | C.__glDebugMessageInsert(C.GLenum(source), C.GLenum(typ), C.GLuint(id), C.GLenum(severity), 71 | C.GLsizei(len(message)), C.CString(message)) 72 | } 73 | 74 | func GetNextDebugMessage() (msg string, source GLenum, typ GLenum, id uint, severity GLenum) { 75 | length := []int32{0} 76 | GetIntegerv(DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, length) 77 | if length[0] < 1 { 78 | msg = "" 79 | return 80 | } 81 | 82 | buf := C.malloc(C.size_t(length[0])) 83 | defer C.free(buf) 84 | 85 | _id := []GLuint{0} 86 | C.GetDebugMessageLog(C.GLuint(1), C.GLsizei(length[0]), 87 | (*C.GLenum)(&source), (*C.GLenum)(&typ), (*C.GLuint)(&_id[0]), 88 | (*C.GLenum)(&severity), nil, (*C.char)(buf)) 89 | 90 | id = uint(_id[0]) 91 | msg = C.GoString((*C.char)(buf)) 92 | return 93 | } 94 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/framebuffer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | // Framebuffer Objects 11 | // TODO: implement GLsync stuff 12 | type Framebuffer Object 13 | 14 | // void glBindFramebuffer(GLenum target, GLuint framebuffer); 15 | // 16 | // Binds fb to target FRAMEBUFFER. To bind to a specific target, see BindTarget. 17 | func (fb Framebuffer) Bind() { 18 | C.glBindFramebuffer(C.GLenum(FRAMEBUFFER), C.GLuint(fb)) 19 | } 20 | 21 | // Binds fb to the specified target. 22 | // 23 | // See issue at github for why this function exists: 24 | // http://github.com/go-gl/gl/issues/113 25 | func (fb Framebuffer) BindTarget(target GLenum) { 26 | C.glBindFramebuffer(C.GLenum(target), C.GLuint(fb)) 27 | } 28 | 29 | // Unbinds target FRAMEBUFFER. To unbind a a specific target, see UnbindTarget. 30 | func (fb Framebuffer) Unbind() { 31 | C.glBindFramebuffer(C.GLenum(FRAMEBUFFER), 0) 32 | } 33 | 34 | // Unbinds the specified target. 35 | // 36 | // See issue at github for why this function exists: 37 | // http://github.com/go-gl/gl/issues/113 38 | func (fb Framebuffer) UnbindTarget(target GLenum) { 39 | C.glBindFramebuffer(C.GLenum(target), 0) 40 | } 41 | 42 | // void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); 43 | func BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1 int, mask GLbitfield, filter GLenum) { 44 | C.glBlitFramebuffer(C.GLint(srcX0), C.GLint(srcY0), C.GLint(srcX1), C.GLint(srcY1), C.GLint(dstX0), C.GLint(dstY0), C.GLint(dstX1), C.GLint(dstY1), C.GLbitfield(mask), C.GLenum(filter)) 45 | } 46 | 47 | // GLenum glCheckFramebufferStatus(GLenum target); 48 | func CheckFramebufferStatus(target GLenum) GLenum { 49 | return (GLenum)(C.glCheckFramebufferStatus(C.GLenum(target))) 50 | } 51 | 52 | // void glDeleteFramebuffers(GLsizei n, GLuint* framebuffers); 53 | func (fb Framebuffer) Delete() { 54 | C.glDeleteFramebuffers(1, (*C.GLuint)(&fb)) 55 | } 56 | 57 | func DeleteFramebuffers(bufs []Framebuffer) { 58 | if len(bufs) > 0 { 59 | C.glDeleteFramebuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) 60 | } 61 | } 62 | 63 | // void glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); 64 | func FramebufferTexture1D(target, attachment, textarget GLenum, texture Texture, level int) { 65 | C.glFramebufferTexture1D(C.GLenum(target), C.GLenum(attachment), C.GLenum(textarget), C.GLuint(texture), C.GLint(level)) 66 | } 67 | 68 | // void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); 69 | func FramebufferTexture2D(target, attachment, textarget GLenum, texture Texture, level int) { 70 | C.glFramebufferTexture2D(C.GLenum(target), C.GLenum(attachment), C.GLenum(textarget), C.GLuint(texture), C.GLint(level)) 71 | } 72 | 73 | // void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); 74 | func FramebufferTexture3D(target, attachment, textarget GLenum, texture Texture, level int, layer int) { 75 | C.glFramebufferTexture3D(C.GLenum(target), C.GLenum(attachment), C.GLenum(textarget), C.GLuint(texture), C.GLint(level), C.GLint(layer)) 76 | } 77 | 78 | // void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); 79 | func FramebufferTextureLayer(target, attachment GLenum, texture Texture, level, layer int) { 80 | C.glFramebufferTextureLayer(C.GLenum(target), C.GLenum(attachment), C.GLuint(texture), C.GLint(level), C.GLint(layer)) 81 | } 82 | 83 | // void glGenFramebuffers(GLsizei n, GLuint* ids); 84 | func GenFramebuffer() Framebuffer { 85 | var b C.GLuint 86 | C.glGenFramebuffers(1, &b) 87 | return Framebuffer(b) 88 | } 89 | 90 | func GenFramebuffers(bufs []Framebuffer) { 91 | if len(bufs) > 0 { 92 | C.glGenFramebuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/gl.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #undef GLEW_GET_FUN 5 | #define GLEW_GET_FUN(x) (*x) -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/matrix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | //void glFrustum (float64 left, float64 right, float64 bottom, float64 top, float64 zNear, float64 zFar) 11 | func Frustum(left float64, right float64, bottom float64, top float64, zNear float64, zFar float64) { 12 | C.glFrustum(C.GLdouble(left), C.GLdouble(right), C.GLdouble(bottom), C.GLdouble(top), C.GLdouble(zNear), C.GLdouble(zFar)) 13 | } 14 | 15 | //void glLoadIdentity (void) 16 | func LoadIdentity() { 17 | C.glLoadIdentity() 18 | } 19 | 20 | //void glLoadMatrixd (const float64 *m) 21 | func LoadMatrixd(m *[16]float64) { 22 | C.glLoadMatrixd((*C.GLdouble)(&m[0])) 23 | } 24 | 25 | //void glLoadMatrixf (const float32 *m) 26 | func LoadMatrixf(m *[16]float32) { 27 | C.glLoadMatrixf((*C.GLfloat)(&m[0])) 28 | } 29 | 30 | //void glMatrixMode (GLenum mode) 31 | func MatrixMode(mode GLenum) { 32 | C.glMatrixMode(C.GLenum(mode)) 33 | } 34 | 35 | //void glMultMatrixd (const float64 *m) 36 | func MultMatrixd(m *[16]float64) { 37 | C.glMultMatrixd((*C.GLdouble)(&m[0])) 38 | } 39 | 40 | //void glMultMatrixf (const float32 *m) 41 | func MultMatrixf(m *[16]float32) { 42 | C.glMultMatrixf((*C.GLfloat)(&m[0])) 43 | } 44 | 45 | //void glOrtho (float64 left, float64 right, float64 bottom, float64 top, float64 zNear, float64 zFar) 46 | func Ortho(left float64, right float64, bottom float64, top float64, zNear float64, zFar float64) { 47 | C.glOrtho(C.GLdouble(left), C.GLdouble(right), C.GLdouble(bottom), C.GLdouble(top), C.GLdouble(zNear), C.GLdouble(zFar)) 48 | } 49 | 50 | //void glPopMatrix (void) 51 | func PopMatrix() { 52 | C.glPopMatrix() 53 | } 54 | 55 | //void glPushMatrix (void) 56 | func PushMatrix() { 57 | C.glPushMatrix() 58 | } 59 | 60 | //void glRotated (float64 angle, float64 x, float64 y, float64 z) 61 | func Rotated(angle float64, x float64, y float64, z float64) { 62 | C.glRotated(C.GLdouble(angle), C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) 63 | } 64 | 65 | //void glRotatef (float32 angle, float32 x, float32 y, float32 z) 66 | func Rotatef(angle float32, x float32, y float32, z float32) { 67 | C.glRotatef(C.GLfloat(angle), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) 68 | } 69 | 70 | //void glScaled (float64 x, float64 y, float64 z) 71 | func Scaled(x float64, y float64, z float64) { 72 | C.glScaled(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) 73 | } 74 | 75 | //void glScalef (float32 x, float32 y, float32 z) 76 | func Scalef(x float32, y float32, z float32) { 77 | C.glScalef(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) 78 | } 79 | 80 | //void glTranslated (float64 x, float64 y, float64 z) 81 | func Translated(x float64, y float64, z float64) { 82 | C.glTranslated(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) 83 | } 84 | 85 | //void glTranslatef (float32 x, float32 y, float32 z) 86 | func Translatef(x float32, y float32, z float32) { 87 | C.glTranslatef(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/object.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | // Object 11 | 12 | type Object C.GLuint 13 | 14 | func (object Object) IsBuffer() bool { return C.glIsBuffer(C.GLuint(object)) != 0 } 15 | 16 | func (object Object) IsProgram() bool { return C.glIsProgram(C.GLuint(object)) != 0 } 17 | 18 | func (object Object) IsQuery() bool { return C.glIsQuery(C.GLuint(object)) != 0 } 19 | 20 | func (object Object) IsShader() bool { return C.glIsShader(C.GLuint(object)) != 0 } 21 | 22 | func (object Object) IsTexture() bool { return C.glIsTexture(C.GLuint(object)) != 0 } 23 | 24 | func (object Object) IsTransformFeedback() bool { return C.glIsTransformFeedback(C.GLuint(object)) != 0 } 25 | 26 | func (object Object) IsVertexArray() bool { return C.glIsVertexArray(C.GLuint(object)) != 0 } 27 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/query.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | type Query Object 11 | 12 | func GenQuery() (q Query) { 13 | C.glGenQueries(1, (*C.GLuint)(&q)) 14 | return 15 | } 16 | 17 | func GenQueries(queries []Query) { 18 | if len(queries) > 0 { 19 | C.glGenQueries(C.GLsizei(len(queries)), (*C.GLuint)(&queries[0])) 20 | } 21 | } 22 | 23 | func (query Query) Begin(target GLenum) { 24 | C.glBeginQuery(C.GLenum(target), C.GLuint(query)) 25 | } 26 | 27 | func (query Query) BeginIndexed(target GLenum, index uint) { 28 | C.glBeginQueryIndexed(C.GLenum(target), C.GLuint(index), C.GLuint(query)) 29 | } 30 | 31 | func (query Query) Delete() { 32 | C.glDeleteQueries(1, (*C.GLuint)(&query)) 33 | } 34 | 35 | func (query Query) GetObjecti(pname GLenum) (param int32) { 36 | C.glGetQueryObjectiv(C.GLuint(query), C.GLenum(pname), (*C.GLint)(¶m)) 37 | return 38 | } 39 | 40 | func (query Query) GetObjectui(pname GLenum) (param uint32) { 41 | C.glGetQueryObjectuiv(C.GLuint(query), C.GLenum(pname), (*C.GLuint)(¶m)) 42 | return 43 | } 44 | 45 | func (query Query) GetObjecti64(pname GLenum) (param int64) { 46 | C.glGetQueryObjecti64v(C.GLuint(query), C.GLenum(pname), (*C.GLint64)(¶m)) 47 | return 48 | } 49 | 50 | func (query Query) GetObjectui64(pname GLenum) (param uint64) { 51 | C.glGetQueryObjectui64v(C.GLuint(query), C.GLenum(pname), (*C.GLuint64)(¶m)) 52 | return 53 | } 54 | 55 | func (query Query) Counter(target GLenum) { 56 | C.glQueryCounter(C.GLuint(query), C.GLenum(target)) 57 | } 58 | 59 | // Returns whether the passed samples counter is immediately available. If a delay 60 | // would not occur waiting for the query result, true is returned, which also indicates 61 | // that the results of all previous queries are available as well. 62 | func (query Query) ResultAvailable() bool { 63 | return query.GetObjectui(QUERY_RESULT_AVAILABLE) == TRUE 64 | } 65 | 66 | func (query Query) BeginConditionalRender(mode GLenum) { 67 | C.glBeginConditionalRender(C.GLuint(query), C.GLenum(mode)) 68 | } 69 | 70 | func DeleteQueries(queries []Query) { 71 | if len(queries) > 0 { 72 | C.glDeleteQueries(C.GLsizei(len(queries)), (*C.GLuint)(&queries[0])) 73 | } 74 | } 75 | 76 | func EndQuery(target GLenum) { 77 | C.glEndQuery(C.GLenum(target)) 78 | } 79 | 80 | func GetQuery(target GLenum, pname GLenum) (param int32) { 81 | C.glGetQueryiv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶m)) 82 | return 83 | } 84 | 85 | func GetQueryIndexed(target GLenum, index uint, pname GLenum) (param int32) { 86 | C.glGetQueryIndexediv(C.GLenum(target), C.GLuint(index), C.GLenum(pname), (*C.GLint)(¶m)) 87 | return 88 | } 89 | 90 | func (query Query) EndQueryIndexed(target GLenum, index uint) { 91 | C.glEndQueryIndexed(C.GLenum(target), C.GLuint(index)) 92 | } 93 | 94 | func (query Query) EndConditionalRender() { 95 | C.glEndConditionalRender() 96 | } 97 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/renderbuffer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | // Renderbuffer Objects 11 | 12 | type Renderbuffer Object 13 | 14 | // void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) 15 | func GenRenderbuffer() Renderbuffer { 16 | var b C.GLuint 17 | C.glGenRenderbuffers(1, &b) 18 | return Renderbuffer(b) 19 | } 20 | 21 | // Fill slice with new renderbuffers 22 | func GenRenderbuffers(bufs []Renderbuffer) { 23 | if len(bufs) > 0 { 24 | C.glGenRenderbuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) 25 | } 26 | } 27 | 28 | // void glBindRenderbuffer(GLenum target, GLuint renderbuffer); 29 | func (rb Renderbuffer) Bind() { 30 | C.glBindRenderbuffer(C.GLenum(RENDERBUFFER), C.GLuint(rb)) 31 | } 32 | 33 | // Unbind this texture 34 | func (rb Renderbuffer) Unbind() { 35 | C.glBindRenderbuffer(C.GLenum(RENDERBUFFER), 0) 36 | } 37 | 38 | // void glDeleteRenderbuffers(GLsizei n, GLuint* renderbuffers); 39 | func (rb Renderbuffer) Delete() { 40 | C.glDeleteRenderbuffers(1, (*C.GLuint)(&rb)) 41 | } 42 | 43 | func DeleteRenderbuffers(bufs []Renderbuffer) { 44 | if len(bufs) > 0 { 45 | C.glDeleteRenderbuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) 46 | } 47 | } 48 | 49 | // void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params); 50 | func GetRenderbufferParameteriv(target, pname GLenum, params []int32) { 51 | if len(params) == 0 { 52 | panic("Invalid params size") 53 | } 54 | 55 | C.glGetRenderbufferParameteriv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶ms[0])) 56 | } 57 | 58 | // void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 59 | func RenderbufferStorage(target, internalformat GLenum, width int, height int) { 60 | C.glRenderbufferStorage(C.GLenum(target), C.GLenum(internalformat), C.GLsizei(width), C.GLsizei(height)) 61 | } 62 | 63 | // void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); 64 | func RenderbufferStorageMultisample(target GLenum, samples int, internalformat GLenum, width, height int) { 65 | C.glRenderbufferStorageMultisample(C.GLenum(target), C.GLsizei(samples), C.GLenum(internalformat), C.GLsizei(width), C.GLsizei(height)) 66 | } 67 | 68 | // GLsync glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); 69 | func (rb Renderbuffer) FramebufferRenderbuffer(target, attachment, renderbuffertarget GLenum) /* GLsync */ { 70 | // TODO: sync stuff. return (GLsync)(C.glFramebufferRenderbuffer (C.GLenum(target), C.GLenum(attachment), C.GLenum(renderbuffertarget), C.GLuint(rb))) 71 | C.glFramebufferRenderbuffer(C.GLenum(target), C.GLenum(attachment), C.GLenum(renderbuffertarget), C.GLuint(rb)) 72 | } 73 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/shader.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | // 9 | // // Workaround for https://github.com/go-gl/gl/issues/104 10 | // void gogl_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* len, GLchar* source) { 11 | // glGetShaderSource(shader, bufsize, len, source); 12 | // } 13 | // 14 | import "C" 15 | import "unsafe" 16 | 17 | // Shader 18 | 19 | type Shader Object 20 | 21 | func CreateShader(type_ GLenum) Shader { return Shader(C.glCreateShader(C.GLenum(type_))) } 22 | 23 | func (shader Shader) Delete() { C.glDeleteShader(C.GLuint(shader)) } 24 | 25 | func (shader Shader) GetInfoLog() string { 26 | var length C.GLint 27 | C.glGetShaderiv(C.GLuint(shader), C.GLenum(INFO_LOG_LENGTH), &length) 28 | // length is buffer size including null character 29 | 30 | if length > 1 { 31 | log := C.malloc(C.size_t(length)) 32 | defer C.free(log) 33 | C.glGetShaderInfoLog(C.GLuint(shader), C.GLsizei(length), nil, (*C.GLchar)(log)) 34 | return C.GoString((*C.char)(log)) 35 | } 36 | return "" 37 | } 38 | 39 | func (shader Shader) GetSource() string { 40 | var length C.GLint 41 | C.glGetShaderiv(C.GLuint(shader), C.GLenum(SHADER_SOURCE_LENGTH), &length) 42 | 43 | log := C.malloc(C.size_t(length + 1)) 44 | C.gogl_glGetShaderSource(C.GLuint(shader), C.GLsizei(length), nil, (*C.GLchar)(log)) 45 | 46 | defer C.free(log) 47 | 48 | if length > 1 { 49 | log := C.malloc(C.size_t(length + 1)) 50 | defer C.free(log) 51 | C.gogl_glGetShaderSource(C.GLuint(shader), C.GLsizei(length), nil, (*C.GLchar)(log)) 52 | return C.GoString((*C.char)(log)) 53 | } 54 | return "" 55 | } 56 | 57 | func (shader Shader) Source(source ...string) { 58 | count := C.GLsizei(len(source)) 59 | cstrings := make([]*C.GLchar, count) 60 | length := make([]C.GLint, count) 61 | 62 | for i, s := range source { 63 | csource := glString(s) 64 | cstrings[i] = csource 65 | length[i] = C.GLint(len(s)) 66 | defer freeString(csource) 67 | } 68 | 69 | C.glShaderSource(C.GLuint(shader), count, (**_Ctype_GLchar)(unsafe.Pointer(&cstrings[0])), (*_Ctype_GLint)(unsafe.Pointer(&length[0]))) 70 | } 71 | 72 | func (shader Shader) Compile() { C.glCompileShader(C.GLuint(shader)) } 73 | 74 | func (shader Shader) Get(param GLenum) int { 75 | var rv C.GLint 76 | 77 | C.glGetShaderiv(C.GLuint(shader), C.GLenum(param), &rv) 78 | return int(rv) 79 | } 80 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/transformfeedback.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | // Transform Feedback Objects 11 | 12 | type TransformFeedback Object 13 | 14 | // Create a single transform feedback object 15 | func GenTransformFeedback() TransformFeedback { 16 | var t C.GLuint 17 | C.glGenTransformFeedbacks(1, &t) 18 | return TransformFeedback(t) 19 | } 20 | 21 | // Fill slice with new transform feedbacks 22 | func GenTransformFeedbacks(feedbacks []TransformFeedback) { 23 | if len(feedbacks) > 0 { 24 | C.glGenTransformFeedbacks(C.GLsizei(len(feedbacks)), (*C.GLuint)(&feedbacks[0])) 25 | } 26 | } 27 | 28 | // Delete a transform feedback object 29 | func (feedback TransformFeedback) Delete() { 30 | C.glDeleteTransformFeedbacks(1, (*C.GLuint)(&feedback)) 31 | } 32 | 33 | // Draw the results of the last Begin/End cycle from this transform feedback using primitive type 'mode' 34 | func (feedback TransformFeedback) Draw(mode GLenum) { 35 | C.glDrawTransformFeedback(C.GLenum(mode), C.GLuint(feedback)) 36 | } 37 | 38 | // Delete all transform feedbacks in a slice 39 | func DeleteTransformFeedbacks(feedbacks []TransformFeedback) { 40 | if len(feedbacks) > 0 { 41 | C.glDeleteTransformFeedbacks(C.GLsizei(len(feedbacks)), (*C.GLuint)(&feedbacks[0])) 42 | } 43 | } 44 | 45 | // Bind this transform feedback as target 46 | func (feedback TransformFeedback) Bind(target GLenum) { 47 | C.glBindTransformFeedback(C.GLenum(target), C.GLuint(feedback)) 48 | } 49 | 50 | // Begin transform feedback with primitive type 'mode' 51 | func BeginTransformFeedback(mode GLenum) { 52 | C.glBeginTransformFeedback(C.GLenum(mode)) 53 | } 54 | 55 | // Pause transform feedback 56 | func PauseTransformFeedback() { 57 | C.glPauseTransformFeedback() 58 | } 59 | 60 | // End transform feedback 61 | func EndTransformFeedback() { 62 | C.glEndTransformFeedback() 63 | } 64 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/uniformblockindex.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | type UniformBlockIndex uint 8 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/vertex.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | //void glVertex2d (float64 x, float64 y) 11 | func Vertex2d(x float64, y float64) { 12 | C.glVertex2d(C.GLdouble(x), C.GLdouble(y)) 13 | } 14 | 15 | //void glVertex2dv (const float64 *v) 16 | func Vertex2dv(v *[2]float64) { 17 | C.glVertex2dv((*C.GLdouble)(&v[0])) 18 | } 19 | 20 | //void glVertex2f (float32 x, float32 y) 21 | func Vertex2f(x float32, y float32) { 22 | C.glVertex2f(C.GLfloat(x), C.GLfloat(y)) 23 | } 24 | 25 | //void glVertex2fv (const float *v) 26 | func Vertex2fv(v *[2]float32) { 27 | C.glVertex2fv((*C.GLfloat)(&v[0])) 28 | } 29 | 30 | //void glVertex2i (int x, int y) 31 | func Vertex2i(x int, y int) { 32 | C.glVertex2i(C.GLint(x), C.GLint(y)) 33 | } 34 | 35 | //void glVertex2iv (const int *v) 36 | func Vertex2iv(v *[2]int32) { 37 | C.glVertex2iv((*C.GLint)(&v[0])) 38 | } 39 | 40 | //void glVertex2s (int16 x, int16 y) 41 | func Vertex2s(x int16, y int16) { 42 | C.glVertex2s(C.GLshort(x), C.GLshort(y)) 43 | } 44 | 45 | //void glVertex2sv (const int16 *v) 46 | func Vertex2sv(v *[2]int16) { 47 | C.glVertex2sv((*C.GLshort)(&v[0])) 48 | } 49 | 50 | //void glVertex3d (float64 x, float64 y, float64 z) 51 | func Vertex3d(x float64, y float64, z float64) { 52 | C.glVertex3d(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) 53 | } 54 | 55 | //void glVertex3dv (const float64 *v) 56 | func Vertex3dv(v *[3]float64) { 57 | C.glVertex3dv((*C.GLdouble)(&v[0])) 58 | } 59 | 60 | //void glVertex3f (float32 x, float32 y, float32 z) 61 | func Vertex3f(x float32, y float32, z float32) { 62 | C.glVertex3f(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) 63 | } 64 | 65 | //void glVertex3fv (const float *v) 66 | func Vertex3fv(v *[3]float32) { 67 | C.glVertex3fv((*C.GLfloat)(&v[0])) 68 | } 69 | 70 | //void glVertex3i (int x, int y, int z) 71 | func Vertex3i(x int, y int, z int) { 72 | C.glVertex3i(C.GLint(x), C.GLint(y), C.GLint(z)) 73 | } 74 | 75 | //void glVertex3iv (const int *v) 76 | func Vertex3iv(v *[3]int32) { 77 | C.glVertex3iv((*C.GLint)(&v[0])) 78 | } 79 | 80 | //void glVertex3s (int16 x, int16 y, int16 z) 81 | func Vertex3s(x int16, y int16, z int16) { 82 | C.glVertex3s(C.GLshort(x), C.GLshort(y), C.GLshort(z)) 83 | } 84 | 85 | //void glVertex3sv (const int16 *v) 86 | func Vertex3sv(v *[3]int16) { 87 | C.glVertex3sv((*C.GLshort)(&v[0])) 88 | } 89 | 90 | //void glVertex4d (float64 x, float64 y, float64 z, float64 w) 91 | func Vertex4d(x float64, y float64, z float64, w float64) { 92 | C.glVertex4d(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z), C.GLdouble(w)) 93 | } 94 | 95 | //void glVertex4dv (const float64 *v) 96 | func Vertex4dv(v *[4]float64) { 97 | C.glVertex4dv((*C.GLdouble)(&v[0])) 98 | } 99 | 100 | //void glVertex4f (float32 x, float32 y, float32 z, float32 w) 101 | func Vertex4f(x float32, y float32, z float32, w float32) { 102 | C.glVertex4f(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z), C.GLfloat(w)) 103 | } 104 | 105 | //void glVertex4fv (const float *v) 106 | func Vertex4fv(v *[4]float32) { 107 | C.glVertex4fv((*C.GLfloat)(&v[0])) 108 | } 109 | 110 | //void glVertex4i (int x, int y, int z, int w) 111 | func Vertex4i(x int, y int, z int, w int) { 112 | C.glVertex4i(C.GLint(x), C.GLint(y), C.GLint(z), C.GLint(w)) 113 | } 114 | 115 | //void glVertex4iv (const int *v) 116 | func Vertex4iv(v *[4]int32) { 117 | C.glVertex4iv((*C.GLint)(&v[0])) 118 | } 119 | 120 | //void glVertex4s (int16 x, int16 y, int16 z, int16 w) 121 | func Vertex4s(x int16, y int16, z int16, w int16) { 122 | C.glVertex4s(C.GLshort(x), C.GLshort(y), C.GLshort(z), C.GLshort(w)) 123 | } 124 | 125 | //void glVertex4sv (const int16 *v) 126 | func Vertex4sv(v *[4]int16) { 127 | C.glVertex4sv((*C.GLshort)(&v[0])) 128 | } 129 | 130 | //void glVertexPointer (int size, GLenum type, int stride, const GLvoid *pointer) 131 | func VertexPointer(size int, typ GLenum, stride int, pointer interface{}) { 132 | C.glVertexPointer(C.GLint(size), C.GLenum(typ), C.GLsizei(stride), ptr(pointer)) 133 | } 134 | -------------------------------------------------------------------------------- /vendor/github.com/go-gl-legacy/gl/vertexarray.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The go-gl Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gl 6 | 7 | // #include "gl.h" 8 | import "C" 9 | 10 | // Vertex Arrays 11 | type VertexArray Object 12 | 13 | func GenVertexArray() VertexArray { 14 | var a C.GLuint 15 | C.glGenVertexArrays(1, &a) 16 | return VertexArray(a) 17 | } 18 | 19 | func GenVertexArrays(arrays []VertexArray) { 20 | if len(arrays) > 0 { 21 | C.glGenVertexArrays(C.GLsizei(len(arrays)), (*C.GLuint)(&arrays[0])) 22 | } 23 | } 24 | 25 | func (array VertexArray) Delete() { 26 | C.glDeleteVertexArrays(1, (*C.GLuint)(&array)) 27 | } 28 | 29 | func DeleteVertexArrays(arrays []VertexArray) { 30 | if len(arrays) > 0 { 31 | C.glDeleteVertexArrays(C.GLsizei(len(arrays)), (*C.GLuint)(&arrays[0])) 32 | } 33 | } 34 | 35 | func (array VertexArray) Bind() { 36 | C.glBindVertexArray(C.GLuint(array)) 37 | } 38 | 39 | func (array VertexArray) Unbind() { 40 | C.glBindVertexArray(C.GLuint(0)) 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/DESIGN.markdown: -------------------------------------------------------------------------------- 1 | * Designate the filename of "anonymous" source code by the hash (md5/sha1, etc.) 2 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Robert Krimen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test test-race test-release release release-check test-262 2 | .PHONY: parser 3 | .PHONY: otto assets underscore 4 | 5 | TESTS := \ 6 | ~ 7 | 8 | TEST := -v --run 9 | TEST := -v 10 | TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\) 11 | TEST := . 12 | 13 | test: parser inline.go 14 | go test -i 15 | go test $(TEST) 16 | @echo PASS 17 | 18 | parser: 19 | $(MAKE) -C parser 20 | 21 | inline.go: inline 22 | ./$< > $@ 23 | 24 | ################# 25 | # release, test # 26 | ################# 27 | 28 | release: test-race test-release 29 | for package in . parser token ast file underscore registry; do (cd $$package && godocdown --signature > README.markdown); done 30 | @echo \*\*\* make release-check 31 | @echo PASS 32 | 33 | release-check: .test 34 | $(MAKE) -C test build test 35 | $(MAKE) -C .test/test262 build test 36 | @echo PASS 37 | 38 | test-262: .test 39 | $(MAKE) -C .test/test262 build test 40 | @echo PASS 41 | 42 | test-release: 43 | go test -i 44 | go test 45 | 46 | test-race: 47 | go test -race -i 48 | go test -race 49 | 50 | ################################# 51 | # otto, assets, underscore, ... # 52 | ################################# 53 | 54 | otto: 55 | $(MAKE) -C otto 56 | 57 | assets: 58 | mkdir -p .assets 59 | for file in underscore/test/*.js; do tr "\`" "_" < $$file > .assets/`basename $$file`; done 60 | 61 | underscore: 62 | $(MAKE) -C $@ 63 | 64 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/builtin_boolean.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | // Boolean 4 | 5 | func builtinBoolean(call FunctionCall) Value { 6 | return toValue_bool(call.Argument(0).bool()) 7 | } 8 | 9 | func builtinNewBoolean(self *_object, argumentList []Value) Value { 10 | return toValue_object(self.runtime.newBoolean(valueOfArrayIndex(argumentList, 0))) 11 | } 12 | 13 | func builtinBoolean_toString(call FunctionCall) Value { 14 | value := call.This 15 | if !value.IsBoolean() { 16 | // Will throw a TypeError if ThisObject is not a Boolean 17 | value = call.thisClassObject("Boolean").primitiveValue() 18 | } 19 | return toValue_string(value.string()) 20 | } 21 | 22 | func builtinBoolean_valueOf(call FunctionCall) Value { 23 | value := call.This 24 | if !value.IsBoolean() { 25 | value = call.thisClassObject("Boolean").primitiveValue() 26 | } 27 | return value 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/builtin_error.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func builtinError(call FunctionCall) Value { 8 | return toValue_object(call.runtime.newError("", call.Argument(0))) 9 | } 10 | 11 | func builtinNewError(self *_object, argumentList []Value) Value { 12 | return toValue_object(self.runtime.newError("", valueOfArrayIndex(argumentList, 0))) 13 | } 14 | 15 | func builtinError_toString(call FunctionCall) Value { 16 | thisObject := call.thisObject() 17 | if thisObject == nil { 18 | panic(call.runtime.panicTypeError()) 19 | } 20 | 21 | name := "Error" 22 | nameValue := thisObject.get("name") 23 | if nameValue.IsDefined() { 24 | name = nameValue.string() 25 | } 26 | 27 | message := "" 28 | messageValue := thisObject.get("message") 29 | if messageValue.IsDefined() { 30 | message = messageValue.string() 31 | } 32 | 33 | if len(name) == 0 { 34 | return toValue_string(message) 35 | } 36 | 37 | if len(message) == 0 { 38 | return toValue_string(name) 39 | } 40 | 41 | return toValue_string(fmt.Sprintf("%s: %s", name, message)) 42 | } 43 | 44 | func (runtime *_runtime) newEvalError(message Value) *_object { 45 | self := runtime.newErrorObject("EvalError", message) 46 | self.prototype = runtime.global.EvalErrorPrototype 47 | return self 48 | } 49 | 50 | func builtinEvalError(call FunctionCall) Value { 51 | return toValue_object(call.runtime.newEvalError(call.Argument(0))) 52 | } 53 | 54 | func builtinNewEvalError(self *_object, argumentList []Value) Value { 55 | return toValue_object(self.runtime.newEvalError(valueOfArrayIndex(argumentList, 0))) 56 | } 57 | 58 | func (runtime *_runtime) newTypeError(message Value) *_object { 59 | self := runtime.newErrorObject("TypeError", message) 60 | self.prototype = runtime.global.TypeErrorPrototype 61 | return self 62 | } 63 | 64 | func builtinTypeError(call FunctionCall) Value { 65 | return toValue_object(call.runtime.newTypeError(call.Argument(0))) 66 | } 67 | 68 | func builtinNewTypeError(self *_object, argumentList []Value) Value { 69 | return toValue_object(self.runtime.newTypeError(valueOfArrayIndex(argumentList, 0))) 70 | } 71 | 72 | func (runtime *_runtime) newRangeError(message Value) *_object { 73 | self := runtime.newErrorObject("RangeError", message) 74 | self.prototype = runtime.global.RangeErrorPrototype 75 | return self 76 | } 77 | 78 | func builtinRangeError(call FunctionCall) Value { 79 | return toValue_object(call.runtime.newRangeError(call.Argument(0))) 80 | } 81 | 82 | func builtinNewRangeError(self *_object, argumentList []Value) Value { 83 | return toValue_object(self.runtime.newRangeError(valueOfArrayIndex(argumentList, 0))) 84 | } 85 | 86 | func (runtime *_runtime) newURIError(message Value) *_object { 87 | self := runtime.newErrorObject("URIError", message) 88 | self.prototype = runtime.global.URIErrorPrototype 89 | return self 90 | } 91 | 92 | func (runtime *_runtime) newReferenceError(message Value) *_object { 93 | self := runtime.newErrorObject("ReferenceError", message) 94 | self.prototype = runtime.global.ReferenceErrorPrototype 95 | return self 96 | } 97 | 98 | func builtinReferenceError(call FunctionCall) Value { 99 | return toValue_object(call.runtime.newReferenceError(call.Argument(0))) 100 | } 101 | 102 | func builtinNewReferenceError(self *_object, argumentList []Value) Value { 103 | return toValue_object(self.runtime.newReferenceError(valueOfArrayIndex(argumentList, 0))) 104 | } 105 | 106 | func (runtime *_runtime) newSyntaxError(message Value) *_object { 107 | self := runtime.newErrorObject("SyntaxError", message) 108 | self.prototype = runtime.global.SyntaxErrorPrototype 109 | return self 110 | } 111 | 112 | func builtinSyntaxError(call FunctionCall) Value { 113 | return toValue_object(call.runtime.newSyntaxError(call.Argument(0))) 114 | } 115 | 116 | func builtinNewSyntaxError(self *_object, argumentList []Value) Value { 117 | return toValue_object(self.runtime.newSyntaxError(valueOfArrayIndex(argumentList, 0))) 118 | } 119 | 120 | func builtinURIError(call FunctionCall) Value { 121 | return toValue_object(call.runtime.newURIError(call.Argument(0))) 122 | } 123 | 124 | func builtinNewURIError(self *_object, argumentList []Value) Value { 125 | return toValue_object(self.runtime.newURIError(valueOfArrayIndex(argumentList, 0))) 126 | } 127 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/builtin_function.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "strings" 7 | "unicode" 8 | 9 | "github.com/robertkrimen/otto/parser" 10 | ) 11 | 12 | // Function 13 | 14 | func builtinFunction(call FunctionCall) Value { 15 | return toValue_object(builtinNewFunctionNative(call.runtime, call.ArgumentList)) 16 | } 17 | 18 | func builtinNewFunction(self *_object, argumentList []Value) Value { 19 | return toValue_object(builtinNewFunctionNative(self.runtime, argumentList)) 20 | } 21 | 22 | func argumentList2parameterList(argumentList []Value) []string { 23 | parameterList := make([]string, 0, len(argumentList)) 24 | for _, value := range argumentList { 25 | tmp := strings.FieldsFunc(value.string(), func(chr rune) bool { 26 | return chr == ',' || unicode.IsSpace(chr) 27 | }) 28 | parameterList = append(parameterList, tmp...) 29 | } 30 | return parameterList 31 | } 32 | 33 | var matchIdentifier = regexp.MustCompile(`^[$_\p{L}][$_\p{L}\d}]*$`) 34 | 35 | func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object { 36 | var parameterList, body string 37 | count := len(argumentList) 38 | if count > 0 { 39 | tmp := make([]string, 0, count-1) 40 | for _, value := range argumentList[0 : count-1] { 41 | tmp = append(tmp, value.string()) 42 | } 43 | parameterList = strings.Join(tmp, ",") 44 | body = argumentList[count-1].string() 45 | } 46 | 47 | // FIXME 48 | function, err := parser.ParseFunction(parameterList, body) 49 | runtime.parseThrow(err) // Will panic/throw appropriately 50 | cmpl := _compiler{} 51 | cmpl_function := cmpl.parseExpression(function) 52 | 53 | return runtime.newNodeFunction(cmpl_function.(*_nodeFunctionLiteral), runtime.globalStash) 54 | } 55 | 56 | func builtinFunction_toString(call FunctionCall) Value { 57 | object := call.thisClassObject("Function") // Should throw a TypeError unless Function 58 | switch fn := object.value.(type) { 59 | case _nativeFunctionObject: 60 | return toValue_string(fmt.Sprintf("function %s() { [native code] }", fn.name)) 61 | case _nodeFunctionObject: 62 | return toValue_string(fn.node.source) 63 | case _bindFunctionObject: 64 | return toValue_string("function () { [native code] }") 65 | } 66 | 67 | panic(call.runtime.panicTypeError("Function.toString()")) 68 | } 69 | 70 | func builtinFunction_apply(call FunctionCall) Value { 71 | if !call.This.isCallable() { 72 | panic(call.runtime.panicTypeError()) 73 | } 74 | this := call.Argument(0) 75 | if this.IsUndefined() { 76 | // FIXME Not ECMA5 77 | this = toValue_object(call.runtime.globalObject) 78 | } 79 | argumentList := call.Argument(1) 80 | switch argumentList.kind { 81 | case valueUndefined, valueNull: 82 | return call.thisObject().call(this, nil, false, nativeFrame) 83 | case valueObject: 84 | default: 85 | panic(call.runtime.panicTypeError()) 86 | } 87 | 88 | arrayObject := argumentList._object() 89 | thisObject := call.thisObject() 90 | length := int64(toUint32(arrayObject.get("length"))) 91 | valueArray := make([]Value, length) 92 | for index := int64(0); index < length; index++ { 93 | valueArray[index] = arrayObject.get(arrayIndexToString(index)) 94 | } 95 | return thisObject.call(this, valueArray, false, nativeFrame) 96 | } 97 | 98 | func builtinFunction_call(call FunctionCall) Value { 99 | if !call.This.isCallable() { 100 | panic(call.runtime.panicTypeError()) 101 | } 102 | thisObject := call.thisObject() 103 | this := call.Argument(0) 104 | if this.IsUndefined() { 105 | // FIXME Not ECMA5 106 | this = toValue_object(call.runtime.globalObject) 107 | } 108 | if len(call.ArgumentList) >= 1 { 109 | return thisObject.call(this, call.ArgumentList[1:], false, nativeFrame) 110 | } 111 | return thisObject.call(this, nil, false, nativeFrame) 112 | } 113 | 114 | func builtinFunction_bind(call FunctionCall) Value { 115 | target := call.This 116 | if !target.isCallable() { 117 | panic(call.runtime.panicTypeError()) 118 | } 119 | targetObject := target._object() 120 | 121 | this := call.Argument(0) 122 | argumentList := call.slice(1) 123 | if this.IsUndefined() { 124 | // FIXME Do this elsewhere? 125 | this = toValue_object(call.runtime.globalObject) 126 | } 127 | 128 | return toValue_object(call.runtime.newBoundFunction(targetObject, this, argumentList)) 129 | } 130 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/builtin_math.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "math" 5 | "math/rand" 6 | ) 7 | 8 | // Math 9 | 10 | func builtinMath_abs(call FunctionCall) Value { 11 | number := call.Argument(0).float64() 12 | return toValue_float64(math.Abs(number)) 13 | } 14 | 15 | func builtinMath_acos(call FunctionCall) Value { 16 | number := call.Argument(0).float64() 17 | return toValue_float64(math.Acos(number)) 18 | } 19 | 20 | func builtinMath_asin(call FunctionCall) Value { 21 | number := call.Argument(0).float64() 22 | return toValue_float64(math.Asin(number)) 23 | } 24 | 25 | func builtinMath_atan(call FunctionCall) Value { 26 | number := call.Argument(0).float64() 27 | return toValue_float64(math.Atan(number)) 28 | } 29 | 30 | func builtinMath_atan2(call FunctionCall) Value { 31 | y := call.Argument(0).float64() 32 | if math.IsNaN(y) { 33 | return NaNValue() 34 | } 35 | x := call.Argument(1).float64() 36 | if math.IsNaN(x) { 37 | return NaNValue() 38 | } 39 | return toValue_float64(math.Atan2(y, x)) 40 | } 41 | 42 | func builtinMath_cos(call FunctionCall) Value { 43 | number := call.Argument(0).float64() 44 | return toValue_float64(math.Cos(number)) 45 | } 46 | 47 | func builtinMath_ceil(call FunctionCall) Value { 48 | number := call.Argument(0).float64() 49 | return toValue_float64(math.Ceil(number)) 50 | } 51 | 52 | func builtinMath_exp(call FunctionCall) Value { 53 | number := call.Argument(0).float64() 54 | return toValue_float64(math.Exp(number)) 55 | } 56 | 57 | func builtinMath_floor(call FunctionCall) Value { 58 | number := call.Argument(0).float64() 59 | return toValue_float64(math.Floor(number)) 60 | } 61 | 62 | func builtinMath_log(call FunctionCall) Value { 63 | number := call.Argument(0).float64() 64 | return toValue_float64(math.Log(number)) 65 | } 66 | 67 | func builtinMath_max(call FunctionCall) Value { 68 | switch len(call.ArgumentList) { 69 | case 0: 70 | return negativeInfinityValue() 71 | case 1: 72 | return toValue_float64(call.ArgumentList[0].float64()) 73 | } 74 | result := call.ArgumentList[0].float64() 75 | if math.IsNaN(result) { 76 | return NaNValue() 77 | } 78 | for _, value := range call.ArgumentList[1:] { 79 | value := value.float64() 80 | if math.IsNaN(value) { 81 | return NaNValue() 82 | } 83 | result = math.Max(result, value) 84 | } 85 | return toValue_float64(result) 86 | } 87 | 88 | func builtinMath_min(call FunctionCall) Value { 89 | switch len(call.ArgumentList) { 90 | case 0: 91 | return positiveInfinityValue() 92 | case 1: 93 | return toValue_float64(call.ArgumentList[0].float64()) 94 | } 95 | result := call.ArgumentList[0].float64() 96 | if math.IsNaN(result) { 97 | return NaNValue() 98 | } 99 | for _, value := range call.ArgumentList[1:] { 100 | value := value.float64() 101 | if math.IsNaN(value) { 102 | return NaNValue() 103 | } 104 | result = math.Min(result, value) 105 | } 106 | return toValue_float64(result) 107 | } 108 | 109 | func builtinMath_pow(call FunctionCall) Value { 110 | // TODO Make sure this works according to the specification (15.8.2.13) 111 | x := call.Argument(0).float64() 112 | y := call.Argument(1).float64() 113 | if math.Abs(x) == 1 && math.IsInf(y, 0) { 114 | return NaNValue() 115 | } 116 | return toValue_float64(math.Pow(x, y)) 117 | } 118 | 119 | func builtinMath_random(call FunctionCall) Value { 120 | return toValue_float64(rand.Float64()) 121 | } 122 | 123 | func builtinMath_round(call FunctionCall) Value { 124 | number := call.Argument(0).float64() 125 | value := math.Floor(number + 0.5) 126 | if value == 0 { 127 | value = math.Copysign(0, number) 128 | } 129 | return toValue_float64(value) 130 | } 131 | 132 | func builtinMath_sin(call FunctionCall) Value { 133 | number := call.Argument(0).float64() 134 | return toValue_float64(math.Sin(number)) 135 | } 136 | 137 | func builtinMath_sqrt(call FunctionCall) Value { 138 | number := call.Argument(0).float64() 139 | return toValue_float64(math.Sqrt(number)) 140 | } 141 | 142 | func builtinMath_tan(call FunctionCall) Value { 143 | number := call.Argument(0).float64() 144 | return toValue_float64(math.Tan(number)) 145 | } 146 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/builtin_number.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "math" 5 | "strconv" 6 | ) 7 | 8 | // Number 9 | 10 | func numberValueFromNumberArgumentList(argumentList []Value) Value { 11 | if len(argumentList) > 0 { 12 | return argumentList[0].numberValue() 13 | } 14 | return toValue_int(0) 15 | } 16 | 17 | func builtinNumber(call FunctionCall) Value { 18 | return numberValueFromNumberArgumentList(call.ArgumentList) 19 | } 20 | 21 | func builtinNewNumber(self *_object, argumentList []Value) Value { 22 | return toValue_object(self.runtime.newNumber(numberValueFromNumberArgumentList(argumentList))) 23 | } 24 | 25 | func builtinNumber_toString(call FunctionCall) Value { 26 | // Will throw a TypeError if ThisObject is not a Number 27 | value := call.thisClassObject("Number").primitiveValue() 28 | radix := 10 29 | radixArgument := call.Argument(0) 30 | if radixArgument.IsDefined() { 31 | integer := toIntegerFloat(radixArgument) 32 | if integer < 2 || integer > 36 { 33 | panic(call.runtime.panicRangeError("RangeError: toString() radix must be between 2 and 36")) 34 | } 35 | radix = int(integer) 36 | } 37 | if radix == 10 { 38 | return toValue_string(value.string()) 39 | } 40 | return toValue_string(numberToStringRadix(value, radix)) 41 | } 42 | 43 | func builtinNumber_valueOf(call FunctionCall) Value { 44 | return call.thisClassObject("Number").primitiveValue() 45 | } 46 | 47 | func builtinNumber_toFixed(call FunctionCall) Value { 48 | precision := toIntegerFloat(call.Argument(0)) 49 | if 20 < precision || 0 > precision { 50 | panic(call.runtime.panicRangeError("toFixed() precision must be between 0 and 20")) 51 | } 52 | if call.This.IsNaN() { 53 | return toValue_string("NaN") 54 | } 55 | value := call.This.float64() 56 | if math.Abs(value) >= 1e21 { 57 | return toValue_string(floatToString(value, 64)) 58 | } 59 | return toValue_string(strconv.FormatFloat(call.This.float64(), 'f', int(precision), 64)) 60 | } 61 | 62 | func builtinNumber_toExponential(call FunctionCall) Value { 63 | if call.This.IsNaN() { 64 | return toValue_string("NaN") 65 | } 66 | precision := float64(-1) 67 | if value := call.Argument(0); value.IsDefined() { 68 | precision = toIntegerFloat(value) 69 | if 0 > precision { 70 | panic(call.runtime.panicRangeError("RangeError: toString() radix must be between 2 and 36")) 71 | } 72 | } 73 | return toValue_string(strconv.FormatFloat(call.This.float64(), 'e', int(precision), 64)) 74 | } 75 | 76 | func builtinNumber_toPrecision(call FunctionCall) Value { 77 | if call.This.IsNaN() { 78 | return toValue_string("NaN") 79 | } 80 | value := call.Argument(0) 81 | if value.IsUndefined() { 82 | return toValue_string(call.This.string()) 83 | } 84 | precision := toIntegerFloat(value) 85 | if 1 > precision { 86 | panic(call.runtime.panicRangeError("RangeError: toPrecision() precision must be greater than 1")) 87 | } 88 | return toValue_string(strconv.FormatFloat(call.This.float64(), 'g', int(precision), 64)) 89 | } 90 | 91 | func builtinNumber_toLocaleString(call FunctionCall) Value { 92 | return builtinNumber_toString(call) 93 | } 94 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/builtin_regexp.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // RegExp 8 | 9 | func builtinRegExp(call FunctionCall) Value { 10 | pattern := call.Argument(0) 11 | flags := call.Argument(1) 12 | if object := pattern._object(); object != nil { 13 | if object.class == "RegExp" && flags.IsUndefined() { 14 | return pattern 15 | } 16 | } 17 | return toValue_object(call.runtime.newRegExp(pattern, flags)) 18 | } 19 | 20 | func builtinNewRegExp(self *_object, argumentList []Value) Value { 21 | return toValue_object(self.runtime.newRegExp( 22 | valueOfArrayIndex(argumentList, 0), 23 | valueOfArrayIndex(argumentList, 1), 24 | )) 25 | } 26 | 27 | func builtinRegExp_toString(call FunctionCall) Value { 28 | thisObject := call.thisObject() 29 | source := thisObject.get("source").string() 30 | flags := []byte{} 31 | if thisObject.get("global").bool() { 32 | flags = append(flags, 'g') 33 | } 34 | if thisObject.get("ignoreCase").bool() { 35 | flags = append(flags, 'i') 36 | } 37 | if thisObject.get("multiline").bool() { 38 | flags = append(flags, 'm') 39 | } 40 | return toValue_string(fmt.Sprintf("/%s/%s", source, flags)) 41 | } 42 | 43 | func builtinRegExp_exec(call FunctionCall) Value { 44 | thisObject := call.thisObject() 45 | target := call.Argument(0).string() 46 | match, result := execRegExp(thisObject, target) 47 | if !match { 48 | return nullValue 49 | } 50 | return toValue_object(execResultToArray(call.runtime, target, result)) 51 | } 52 | 53 | func builtinRegExp_test(call FunctionCall) Value { 54 | thisObject := call.thisObject() 55 | target := call.Argument(0).string() 56 | match, _ := execRegExp(thisObject, target) 57 | return toValue_bool(match) 58 | } 59 | 60 | func builtinRegExp_compile(call FunctionCall) Value { 61 | // This (useless) function is deprecated, but is here to provide some 62 | // semblance of compatibility. 63 | // Caveat emptor: it may not be around for long. 64 | return Value{} 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/cmpl.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "github.com/robertkrimen/otto/ast" 5 | "github.com/robertkrimen/otto/file" 6 | ) 7 | 8 | type _file struct { 9 | name string 10 | src string 11 | base int // This will always be 1 or greater 12 | } 13 | 14 | type _compiler struct { 15 | file *file.File 16 | program *ast.Program 17 | } 18 | 19 | func (cmpl *_compiler) parse() *_nodeProgram { 20 | if cmpl.program != nil { 21 | cmpl.file = cmpl.program.File 22 | } 23 | return cmpl._parse(cmpl.program) 24 | } 25 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/cmpl_evaluate.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "strconv" 5 | ) 6 | 7 | func (self *_runtime) cmpl_evaluate_nodeProgram(node *_nodeProgram, eval bool) Value { 8 | if !eval { 9 | self.enterGlobalScope() 10 | defer func() { 11 | self.leaveScope() 12 | }() 13 | } 14 | self.cmpl_functionDeclaration(node.functionList) 15 | self.cmpl_variableDeclaration(node.varList) 16 | self.scope.frame.file = node.file 17 | return self.cmpl_evaluate_nodeStatementList(node.body) 18 | } 19 | 20 | func (self *_runtime) cmpl_call_nodeFunction(function *_object, stash *_fnStash, node *_nodeFunctionLiteral, this Value, argumentList []Value) Value { 21 | 22 | indexOfParameterName := make([]string, len(argumentList)) 23 | // function(abc, def, ghi) 24 | // indexOfParameterName[0] = "abc" 25 | // indexOfParameterName[1] = "def" 26 | // indexOfParameterName[2] = "ghi" 27 | // ... 28 | 29 | argumentsFound := false 30 | for index, name := range node.parameterList { 31 | if name == "arguments" { 32 | argumentsFound = true 33 | } 34 | value := Value{} 35 | if index < len(argumentList) { 36 | value = argumentList[index] 37 | indexOfParameterName[index] = name 38 | } 39 | // strict = false 40 | self.scope.lexical.setValue(name, value, false) 41 | } 42 | 43 | if !argumentsFound { 44 | arguments := self.newArgumentsObject(indexOfParameterName, stash, len(argumentList)) 45 | arguments.defineProperty("callee", toValue_object(function), 0101, false) 46 | stash.arguments = arguments 47 | // strict = false 48 | self.scope.lexical.setValue("arguments", toValue_object(arguments), false) 49 | for index, _ := range argumentList { 50 | if index < len(node.parameterList) { 51 | continue 52 | } 53 | indexAsString := strconv.FormatInt(int64(index), 10) 54 | arguments.defineProperty(indexAsString, argumentList[index], 0111, false) 55 | } 56 | } 57 | 58 | self.cmpl_functionDeclaration(node.functionList) 59 | self.cmpl_variableDeclaration(node.varList) 60 | 61 | result := self.cmpl_evaluate_nodeStatement(node.body) 62 | if result.kind == valueResult { 63 | return result 64 | } 65 | 66 | return Value{} 67 | } 68 | 69 | func (self *_runtime) cmpl_functionDeclaration(list []*_nodeFunctionLiteral) { 70 | executionContext := self.scope 71 | eval := executionContext.eval 72 | stash := executionContext.variable 73 | 74 | for _, function := range list { 75 | name := function.name 76 | value := self.cmpl_evaluate_nodeExpression(function) 77 | if !stash.hasBinding(name) { 78 | stash.createBinding(name, eval == true, value) 79 | } else { 80 | // TODO 10.5.5.e 81 | stash.setBinding(name, value, false) // TODO strict 82 | } 83 | } 84 | } 85 | 86 | func (self *_runtime) cmpl_variableDeclaration(list []string) { 87 | executionContext := self.scope 88 | eval := executionContext.eval 89 | stash := executionContext.variable 90 | 91 | for _, name := range list { 92 | if !stash.hasBinding(name) { 93 | stash.createBinding(name, eval == true, Value{}) // TODO strict? 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/console.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | ) 8 | 9 | func formatForConsole(argumentList []Value) string { 10 | output := []string{} 11 | for _, argument := range argumentList { 12 | output = append(output, fmt.Sprintf("%v", argument)) 13 | } 14 | return strings.Join(output, " ") 15 | } 16 | 17 | func builtinConsole_log(call FunctionCall) Value { 18 | fmt.Fprintln(os.Stdout, formatForConsole(call.ArgumentList)) 19 | return Value{} 20 | } 21 | 22 | func builtinConsole_error(call FunctionCall) Value { 23 | fmt.Fprintln(os.Stdout, formatForConsole(call.ArgumentList)) 24 | return Value{} 25 | } 26 | 27 | // Nothing happens. 28 | func builtinConsole_dir(call FunctionCall) Value { 29 | return Value{} 30 | } 31 | 32 | func builtinConsole_time(call FunctionCall) Value { 33 | return Value{} 34 | } 35 | 36 | func builtinConsole_timeEnd(call FunctionCall) Value { 37 | return Value{} 38 | } 39 | 40 | func builtinConsole_trace(call FunctionCall) Value { 41 | return Value{} 42 | } 43 | 44 | func builtinConsole_assert(call FunctionCall) Value { 45 | return Value{} 46 | } 47 | 48 | func (runtime *_runtime) newConsole() *_object { 49 | 50 | return newConsoleObject(runtime) 51 | } 52 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/dbg.go: -------------------------------------------------------------------------------- 1 | // This file was AUTOMATICALLY GENERATED by dbg-import (smuggol) for github.com/robertkrimen/dbg 2 | 3 | package otto 4 | 5 | import ( 6 | Dbg "github.com/robertkrimen/otto/dbg" 7 | ) 8 | 9 | var dbg, dbgf = Dbg.New() 10 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/file/README.markdown: -------------------------------------------------------------------------------- 1 | # file 2 | -- 3 | import "github.com/robertkrimen/otto/file" 4 | 5 | Package file encapsulates the file abstractions used by the ast & parser. 6 | 7 | ## Usage 8 | 9 | #### type File 10 | 11 | ```go 12 | type File struct { 13 | } 14 | ``` 15 | 16 | 17 | #### func NewFile 18 | 19 | ```go 20 | func NewFile(filename, src string, base int) *File 21 | ``` 22 | 23 | #### func (*File) Base 24 | 25 | ```go 26 | func (fl *File) Base() int 27 | ``` 28 | 29 | #### func (*File) Name 30 | 31 | ```go 32 | func (fl *File) Name() string 33 | ``` 34 | 35 | #### func (*File) Source 36 | 37 | ```go 38 | func (fl *File) Source() string 39 | ``` 40 | 41 | #### type FileSet 42 | 43 | ```go 44 | type FileSet struct { 45 | } 46 | ``` 47 | 48 | A FileSet represents a set of source files. 49 | 50 | #### func (*FileSet) AddFile 51 | 52 | ```go 53 | func (self *FileSet) AddFile(filename, src string) int 54 | ``` 55 | AddFile adds a new file with the given filename and src. 56 | 57 | This an internal method, but exported for cross-package use. 58 | 59 | #### func (*FileSet) File 60 | 61 | ```go 62 | func (self *FileSet) File(idx Idx) *File 63 | ``` 64 | 65 | #### func (*FileSet) Position 66 | 67 | ```go 68 | func (self *FileSet) Position(idx Idx) *Position 69 | ``` 70 | Position converts an Idx in the FileSet into a Position. 71 | 72 | #### type Idx 73 | 74 | ```go 75 | type Idx int 76 | ``` 77 | 78 | Idx is a compact encoding of a source position within a file set. It can be 79 | converted into a Position for a more convenient, but much larger, 80 | representation. 81 | 82 | #### type Position 83 | 84 | ```go 85 | type Position struct { 86 | Filename string // The filename where the error occurred, if any 87 | Offset int // The src offset 88 | Line int // The line number, starting at 1 89 | Column int // The column number, starting at 1 (The character count) 90 | 91 | } 92 | ``` 93 | 94 | Position describes an arbitrary source position including the filename, line, 95 | and column location. 96 | 97 | #### func (*Position) String 98 | 99 | ```go 100 | func (self *Position) String() string 101 | ``` 102 | String returns a string in one of several forms: 103 | 104 | file:line:column A valid position with filename 105 | line:column A valid position without filename 106 | file An invalid position with filename 107 | - An invalid position without filename 108 | 109 | -- 110 | **godocdown** http://github.com/robertkrimen/godocdown 111 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/file/file.go: -------------------------------------------------------------------------------- 1 | // Package file encapsulates the file abstractions used by the ast & parser. 2 | // 3 | package file 4 | 5 | import ( 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | // Idx is a compact encoding of a source position within a file set. 11 | // It can be converted into a Position for a more convenient, but much 12 | // larger, representation. 13 | type Idx int 14 | 15 | // Position describes an arbitrary source position 16 | // including the filename, line, and column location. 17 | type Position struct { 18 | Filename string // The filename where the error occurred, if any 19 | Offset int // The src offset 20 | Line int // The line number, starting at 1 21 | Column int // The column number, starting at 1 (The character count) 22 | 23 | } 24 | 25 | // A Position is valid if the line number is > 0. 26 | 27 | func (self *Position) isValid() bool { 28 | return self.Line > 0 29 | } 30 | 31 | // String returns a string in one of several forms: 32 | // 33 | // file:line:column A valid position with filename 34 | // line:column A valid position without filename 35 | // file An invalid position with filename 36 | // - An invalid position without filename 37 | // 38 | func (self *Position) String() string { 39 | str := self.Filename 40 | if self.isValid() { 41 | if str != "" { 42 | str += ":" 43 | } 44 | str += fmt.Sprintf("%d:%d", self.Line, self.Column) 45 | } 46 | if str == "" { 47 | str = "-" 48 | } 49 | return str 50 | } 51 | 52 | // FileSet 53 | 54 | // A FileSet represents a set of source files. 55 | type FileSet struct { 56 | files []*File 57 | last *File 58 | } 59 | 60 | // AddFile adds a new file with the given filename and src. 61 | // 62 | // This an internal method, but exported for cross-package use. 63 | func (self *FileSet) AddFile(filename, src string) int { 64 | base := self.nextBase() 65 | file := &File{ 66 | name: filename, 67 | src: src, 68 | base: base, 69 | } 70 | self.files = append(self.files, file) 71 | self.last = file 72 | return base 73 | } 74 | 75 | func (self *FileSet) nextBase() int { 76 | if self.last == nil { 77 | return 1 78 | } 79 | return self.last.base + len(self.last.src) + 1 80 | } 81 | 82 | func (self *FileSet) File(idx Idx) *File { 83 | for _, file := range self.files { 84 | if idx <= Idx(file.base+len(file.src)) { 85 | return file 86 | } 87 | } 88 | return nil 89 | } 90 | 91 | // Position converts an Idx in the FileSet into a Position. 92 | func (self *FileSet) Position(idx Idx) *Position { 93 | position := &Position{} 94 | for _, file := range self.files { 95 | if idx <= Idx(file.base+len(file.src)) { 96 | offset := int(idx) - file.base 97 | src := file.src[:offset] 98 | position.Filename = file.name 99 | position.Offset = offset 100 | position.Line = 1 + strings.Count(src, "\n") 101 | if index := strings.LastIndex(src, "\n"); index >= 0 { 102 | position.Column = offset - index 103 | } else { 104 | position.Column = 1 + len(src) 105 | } 106 | } 107 | } 108 | return position 109 | } 110 | 111 | type File struct { 112 | name string 113 | src string 114 | base int // This will always be 1 or greater 115 | } 116 | 117 | func NewFile(filename, src string, base int) *File { 118 | return &File{ 119 | name: filename, 120 | src: src, 121 | base: base, 122 | } 123 | } 124 | 125 | func (fl *File) Name() string { 126 | return fl.name 127 | } 128 | 129 | func (fl *File) Source() string { 130 | return fl.src 131 | } 132 | 133 | func (fl *File) Base() int { 134 | return fl.base 135 | } 136 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/object.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | type _object struct { 4 | runtime *_runtime 5 | 6 | class string 7 | objectClass *_objectClass 8 | value interface{} 9 | 10 | prototype *_object 11 | extensible bool 12 | 13 | property map[string]_property 14 | propertyOrder []string 15 | } 16 | 17 | func newObject(runtime *_runtime, class string) *_object { 18 | self := &_object{ 19 | runtime: runtime, 20 | class: class, 21 | objectClass: _classObject, 22 | property: make(map[string]_property), 23 | extensible: true, 24 | } 25 | return self 26 | } 27 | 28 | // 8.12 29 | 30 | // 8.12.1 31 | func (self *_object) getOwnProperty(name string) *_property { 32 | return self.objectClass.getOwnProperty(self, name) 33 | } 34 | 35 | // 8.12.2 36 | func (self *_object) getProperty(name string) *_property { 37 | return self.objectClass.getProperty(self, name) 38 | } 39 | 40 | // 8.12.3 41 | func (self *_object) get(name string) Value { 42 | return self.objectClass.get(self, name) 43 | } 44 | 45 | // 8.12.4 46 | func (self *_object) canPut(name string) bool { 47 | return self.objectClass.canPut(self, name) 48 | } 49 | 50 | // 8.12.5 51 | func (self *_object) put(name string, value Value, throw bool) { 52 | self.objectClass.put(self, name, value, throw) 53 | } 54 | 55 | // 8.12.6 56 | func (self *_object) hasProperty(name string) bool { 57 | return self.objectClass.hasProperty(self, name) 58 | } 59 | 60 | func (self *_object) hasOwnProperty(name string) bool { 61 | return self.objectClass.hasOwnProperty(self, name) 62 | } 63 | 64 | type _defaultValueHint int 65 | 66 | const ( 67 | defaultValueNoHint _defaultValueHint = iota 68 | defaultValueHintString 69 | defaultValueHintNumber 70 | ) 71 | 72 | // 8.12.8 73 | func (self *_object) DefaultValue(hint _defaultValueHint) Value { 74 | if hint == defaultValueNoHint { 75 | if self.class == "Date" { 76 | // Date exception 77 | hint = defaultValueHintString 78 | } else { 79 | hint = defaultValueHintNumber 80 | } 81 | } 82 | methodSequence := []string{"valueOf", "toString"} 83 | if hint == defaultValueHintString { 84 | methodSequence = []string{"toString", "valueOf"} 85 | } 86 | for _, methodName := range methodSequence { 87 | method := self.get(methodName) 88 | // FIXME This is redundant... 89 | if method.isCallable() { 90 | result := method._object().call(toValue_object(self), nil, false, nativeFrame) 91 | if result.IsPrimitive() { 92 | return result 93 | } 94 | } 95 | } 96 | 97 | panic(self.runtime.panicTypeError()) 98 | } 99 | 100 | func (self *_object) String() string { 101 | return self.DefaultValue(defaultValueHintString).string() 102 | } 103 | 104 | func (self *_object) defineProperty(name string, value Value, mode _propertyMode, throw bool) bool { 105 | return self.defineOwnProperty(name, _property{value, mode}, throw) 106 | } 107 | 108 | // 8.12.9 109 | func (self *_object) defineOwnProperty(name string, descriptor _property, throw bool) bool { 110 | return self.objectClass.defineOwnProperty(self, name, descriptor, throw) 111 | } 112 | 113 | func (self *_object) delete(name string, throw bool) bool { 114 | return self.objectClass.delete(self, name, throw) 115 | } 116 | 117 | func (self *_object) enumerate(all bool, each func(string) bool) { 118 | self.objectClass.enumerate(self, all, each) 119 | } 120 | 121 | func (self *_object) _exists(name string) bool { 122 | _, exists := self.property[name] 123 | return exists 124 | } 125 | 126 | func (self *_object) _read(name string) (_property, bool) { 127 | property, exists := self.property[name] 128 | return property, exists 129 | } 130 | 131 | func (self *_object) _write(name string, value interface{}, mode _propertyMode) { 132 | if value == nil { 133 | value = Value{} 134 | } 135 | _, exists := self.property[name] 136 | self.property[name] = _property{value, mode} 137 | if !exists { 138 | self.propertyOrder = append(self.propertyOrder, name) 139 | } 140 | } 141 | 142 | func (self *_object) _delete(name string) { 143 | _, exists := self.property[name] 144 | delete(self.property, name) 145 | if exists { 146 | for index, property := range self.propertyOrder { 147 | if name == property { 148 | if index == len(self.propertyOrder)-1 { 149 | self.propertyOrder = self.propertyOrder[:index] 150 | } else { 151 | self.propertyOrder = append(self.propertyOrder[:index], self.propertyOrder[index+1:]...) 152 | } 153 | } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/parser/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test 2 | 3 | test: 4 | go test 5 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/parser/dbg.go: -------------------------------------------------------------------------------- 1 | // This file was AUTOMATICALLY GENERATED by dbg-import (smuggol) for github.com/robertkrimen/dbg 2 | 3 | package parser 4 | 5 | import ( 6 | Dbg "github.com/robertkrimen/otto/dbg" 7 | ) 8 | 9 | var dbg, dbgf = Dbg.New() 10 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/parser/scope.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "github.com/robertkrimen/otto/ast" 5 | ) 6 | 7 | type _scope struct { 8 | outer *_scope 9 | allowIn bool 10 | inIteration bool 11 | inSwitch bool 12 | inFunction bool 13 | declarationList []ast.Declaration 14 | 15 | labels []string 16 | } 17 | 18 | func (self *_parser) openScope() { 19 | self.scope = &_scope{ 20 | outer: self.scope, 21 | allowIn: true, 22 | } 23 | } 24 | 25 | func (self *_parser) closeScope() { 26 | self.scope = self.scope.outer 27 | } 28 | 29 | func (self *_scope) declare(declaration ast.Declaration) { 30 | self.declarationList = append(self.declarationList, declaration) 31 | } 32 | 33 | func (self *_scope) hasLabel(name string) bool { 34 | for _, label := range self.labels { 35 | if label == name { 36 | return true 37 | } 38 | } 39 | if self.outer != nil && !self.inFunction { 40 | // Crossing a function boundary to look for a label is verboten 41 | return self.outer.hasLabel(name) 42 | } 43 | return false 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/registry/README.markdown: -------------------------------------------------------------------------------- 1 | # registry 2 | -- 3 | import "github.com/robertkrimen/otto/registry" 4 | 5 | Package registry is an expirmental package to facillitate altering the otto 6 | runtime via import. 7 | 8 | This interface can change at any time. 9 | 10 | ## Usage 11 | 12 | #### func Apply 13 | 14 | ```go 15 | func Apply(callback func(Entry)) 16 | ``` 17 | 18 | #### type Entry 19 | 20 | ```go 21 | type Entry struct { 22 | } 23 | ``` 24 | 25 | 26 | #### func Register 27 | 28 | ```go 29 | func Register(source func() string) *Entry 30 | ``` 31 | 32 | #### func (*Entry) Disable 33 | 34 | ```go 35 | func (self *Entry) Disable() 36 | ``` 37 | 38 | #### func (*Entry) Enable 39 | 40 | ```go 41 | func (self *Entry) Enable() 42 | ``` 43 | 44 | #### func (Entry) Source 45 | 46 | ```go 47 | func (self Entry) Source() string 48 | ``` 49 | 50 | -- 51 | **godocdown** http://github.com/robertkrimen/godocdown 52 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/registry/registry.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package registry is an expirmental package to facillitate altering the otto runtime via import. 3 | 4 | This interface can change at any time. 5 | */ 6 | package registry 7 | 8 | var registry []*Entry = make([]*Entry, 0) 9 | 10 | type Entry struct { 11 | active bool 12 | source func() string 13 | } 14 | 15 | func newEntry(source func() string) *Entry { 16 | return &Entry{ 17 | active: true, 18 | source: source, 19 | } 20 | } 21 | 22 | func (self *Entry) Enable() { 23 | self.active = true 24 | } 25 | 26 | func (self *Entry) Disable() { 27 | self.active = false 28 | } 29 | 30 | func (self Entry) Source() string { 31 | return self.source() 32 | } 33 | 34 | func Apply(callback func(Entry)) { 35 | for _, entry := range registry { 36 | if !entry.active { 37 | continue 38 | } 39 | callback(*entry) 40 | } 41 | } 42 | 43 | func Register(source func() string) *Entry { 44 | entry := newEntry(source) 45 | registry = append(registry, entry) 46 | return entry 47 | } 48 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/result.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import () 4 | 5 | type _resultKind int 6 | 7 | const ( 8 | resultNormal _resultKind = iota 9 | resultReturn 10 | resultBreak 11 | resultContinue 12 | ) 13 | 14 | type _result struct { 15 | kind _resultKind 16 | value Value 17 | target string 18 | } 19 | 20 | func newReturnResult(value Value) _result { 21 | return _result{resultReturn, value, ""} 22 | } 23 | 24 | func newContinueResult(target string) _result { 25 | return _result{resultContinue, emptyValue, target} 26 | } 27 | 28 | func newBreakResult(target string) _result { 29 | return _result{resultBreak, emptyValue, target} 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/scope.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | // _scope: 4 | // entryFile 5 | // entryIdx 6 | // top? 7 | // outer => nil 8 | 9 | // _stash: 10 | // lexical 11 | // variable 12 | // 13 | // _thisStash (ObjectEnvironment) 14 | // _fnStash 15 | // _dclStash 16 | 17 | // An ECMA-262 ExecutionContext 18 | type _scope struct { 19 | lexical _stash 20 | variable _stash 21 | this *_object 22 | eval bool // Replace this with kind? 23 | outer *_scope 24 | 25 | frame _frame 26 | } 27 | 28 | func newScope(lexical _stash, variable _stash, this *_object) *_scope { 29 | return &_scope{ 30 | lexical: lexical, 31 | variable: variable, 32 | this: this, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/script.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "bytes" 5 | "encoding/gob" 6 | "errors" 7 | 8 | "github.com/robertkrimen/otto/parser" 9 | ) 10 | 11 | var ErrVersion = errors.New("version mismatch") 12 | 13 | var scriptVersion = "2014-04-13/1" 14 | 15 | // Script is a handle for some (reusable) JavaScript. 16 | // Passing a Script value to a run method will evaluate the JavaScript. 17 | // 18 | type Script struct { 19 | version string 20 | program *_nodeProgram 21 | filename string 22 | src string 23 | } 24 | 25 | // Compile will parse the given source and return a Script value or nil and 26 | // an error if there was a problem during compilation. 27 | // 28 | // script, err := vm.Compile("", `var abc; if (!abc) abc = 0; abc += 2; abc;`) 29 | // vm.Run(script) 30 | // 31 | func (self *Otto) Compile(filename string, src interface{}) (*Script, error) { 32 | { 33 | src, err := parser.ReadSource(filename, src) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | program, err := self.runtime.parse(filename, src) 39 | if err != nil { 40 | return nil, err 41 | } 42 | 43 | cmpl_program := cmpl_parse(program) 44 | 45 | script := &Script{ 46 | version: scriptVersion, 47 | program: cmpl_program, 48 | filename: filename, 49 | src: string(src), 50 | } 51 | 52 | return script, nil 53 | } 54 | } 55 | 56 | func (self *Script) String() string { 57 | return "// " + self.filename + "\n" + self.src 58 | } 59 | 60 | // MarshalBinary will marshal a script into a binary form. A marshalled script 61 | // that is later unmarshalled can be executed on the same version of the otto runtime. 62 | // 63 | // The binary format can change at any time and should be considered unspecified and opaque. 64 | // 65 | func (self *Script) marshalBinary() ([]byte, error) { 66 | var bfr bytes.Buffer 67 | encoder := gob.NewEncoder(&bfr) 68 | err := encoder.Encode(self.version) 69 | if err != nil { 70 | return nil, err 71 | } 72 | err = encoder.Encode(self.program) 73 | if err != nil { 74 | return nil, err 75 | } 76 | err = encoder.Encode(self.filename) 77 | if err != nil { 78 | return nil, err 79 | } 80 | err = encoder.Encode(self.src) 81 | if err != nil { 82 | return nil, err 83 | } 84 | return bfr.Bytes(), nil 85 | } 86 | 87 | // UnmarshalBinary will vivify a marshalled script into something usable. If the script was 88 | // originally marshalled on a different version of the otto runtime, then this method 89 | // will return an error. 90 | // 91 | // The binary format can change at any time and should be considered unspecified and opaque. 92 | // 93 | func (self *Script) unmarshalBinary(data []byte) error { 94 | decoder := gob.NewDecoder(bytes.NewReader(data)) 95 | err := decoder.Decode(&self.version) 96 | if err != nil { 97 | goto error 98 | } 99 | if self.version != scriptVersion { 100 | err = ErrVersion 101 | goto error 102 | } 103 | err = decoder.Decode(&self.program) 104 | if err != nil { 105 | goto error 106 | } 107 | err = decoder.Decode(&self.filename) 108 | if err != nil { 109 | goto error 110 | } 111 | err = decoder.Decode(&self.src) 112 | if err != nil { 113 | goto error 114 | } 115 | return nil 116 | error: 117 | self.version = "" 118 | self.program = nil 119 | self.filename = "" 120 | self.src = "" 121 | return err 122 | } 123 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/token/Makefile: -------------------------------------------------------------------------------- 1 | token_const.go: tokenfmt 2 | ./$^ | gofmt > $@ 3 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/token/README.markdown: -------------------------------------------------------------------------------- 1 | # token 2 | -- 3 | import "github.com/robertkrimen/otto/token" 4 | 5 | Package token defines constants representing the lexical tokens of JavaScript 6 | (ECMA5). 7 | 8 | ## Usage 9 | 10 | ```go 11 | const ( 12 | ILLEGAL 13 | EOF 14 | COMMENT 15 | KEYWORD 16 | 17 | STRING 18 | BOOLEAN 19 | NULL 20 | NUMBER 21 | IDENTIFIER 22 | 23 | PLUS // + 24 | MINUS // - 25 | MULTIPLY // * 26 | SLASH // / 27 | REMAINDER // % 28 | 29 | AND // & 30 | OR // | 31 | EXCLUSIVE_OR // ^ 32 | SHIFT_LEFT // << 33 | SHIFT_RIGHT // >> 34 | UNSIGNED_SHIFT_RIGHT // >>> 35 | AND_NOT // &^ 36 | 37 | ADD_ASSIGN // += 38 | SUBTRACT_ASSIGN // -= 39 | MULTIPLY_ASSIGN // *= 40 | QUOTIENT_ASSIGN // /= 41 | REMAINDER_ASSIGN // %= 42 | 43 | AND_ASSIGN // &= 44 | OR_ASSIGN // |= 45 | EXCLUSIVE_OR_ASSIGN // ^= 46 | SHIFT_LEFT_ASSIGN // <<= 47 | SHIFT_RIGHT_ASSIGN // >>= 48 | UNSIGNED_SHIFT_RIGHT_ASSIGN // >>>= 49 | AND_NOT_ASSIGN // &^= 50 | 51 | LOGICAL_AND // && 52 | LOGICAL_OR // || 53 | INCREMENT // ++ 54 | DECREMENT // -- 55 | 56 | EQUAL // == 57 | STRICT_EQUAL // === 58 | LESS // < 59 | GREATER // > 60 | ASSIGN // = 61 | NOT // ! 62 | 63 | BITWISE_NOT // ~ 64 | 65 | NOT_EQUAL // != 66 | STRICT_NOT_EQUAL // !== 67 | LESS_OR_EQUAL // <= 68 | GREATER_OR_EQUAL // >= 69 | 70 | LEFT_PARENTHESIS // ( 71 | LEFT_BRACKET // [ 72 | LEFT_BRACE // { 73 | COMMA // , 74 | PERIOD // . 75 | 76 | RIGHT_PARENTHESIS // ) 77 | RIGHT_BRACKET // ] 78 | RIGHT_BRACE // } 79 | SEMICOLON // ; 80 | COLON // : 81 | QUESTION_MARK // ? 82 | 83 | IF 84 | IN 85 | DO 86 | 87 | VAR 88 | FOR 89 | NEW 90 | TRY 91 | 92 | THIS 93 | ELSE 94 | CASE 95 | VOID 96 | WITH 97 | 98 | WHILE 99 | BREAK 100 | CATCH 101 | THROW 102 | 103 | RETURN 104 | TYPEOF 105 | DELETE 106 | SWITCH 107 | 108 | DEFAULT 109 | FINALLY 110 | 111 | FUNCTION 112 | CONTINUE 113 | DEBUGGER 114 | 115 | INSTANCEOF 116 | ) 117 | ``` 118 | 119 | #### type Token 120 | 121 | ```go 122 | type Token int 123 | ``` 124 | 125 | Token is the set of lexical tokens in JavaScript (ECMA5). 126 | 127 | #### func IsKeyword 128 | 129 | ```go 130 | func IsKeyword(literal string) (Token, bool) 131 | ``` 132 | IsKeyword returns the keyword token if literal is a keyword, a KEYWORD token if 133 | the literal is a future keyword (const, let, class, super, ...), or 0 if the 134 | literal is not a keyword. 135 | 136 | If the literal is a keyword, IsKeyword returns a second value indicating if the 137 | literal is considered a future keyword in strict-mode only. 138 | 139 | 7.6.1.2 Future Reserved Words: 140 | 141 | const 142 | class 143 | enum 144 | export 145 | extends 146 | import 147 | super 148 | 149 | 7.6.1.2 Future Reserved Words (strict): 150 | 151 | implements 152 | interface 153 | let 154 | package 155 | private 156 | protected 157 | public 158 | static 159 | 160 | #### func (Token) String 161 | 162 | ```go 163 | func (tkn Token) String() string 164 | ``` 165 | String returns the string corresponding to the token. For operators, delimiters, 166 | and keywords the string is the actual token string (e.g., for the token PLUS, 167 | the String() is "+"). For all other tokens the string corresponds to the token 168 | name (e.g. for the token IDENTIFIER, the string is "IDENTIFIER"). 169 | 170 | -- 171 | **godocdown** http://github.com/robertkrimen/godocdown 172 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/token/token.go: -------------------------------------------------------------------------------- 1 | // Package token defines constants representing the lexical tokens of JavaScript (ECMA5). 2 | package token 3 | 4 | import ( 5 | "strconv" 6 | ) 7 | 8 | // Token is the set of lexical tokens in JavaScript (ECMA5). 9 | type Token int 10 | 11 | // String returns the string corresponding to the token. 12 | // For operators, delimiters, and keywords the string is the actual 13 | // token string (e.g., for the token PLUS, the String() is 14 | // "+"). For all other tokens the string corresponds to the token 15 | // name (e.g. for the token IDENTIFIER, the string is "IDENTIFIER"). 16 | // 17 | func (tkn Token) String() string { 18 | if 0 == tkn { 19 | return "UNKNOWN" 20 | } 21 | if tkn < Token(len(token2string)) { 22 | return token2string[tkn] 23 | } 24 | return "token(" + strconv.Itoa(int(tkn)) + ")" 25 | } 26 | 27 | // This is not used for anything 28 | func (tkn Token) precedence(in bool) int { 29 | 30 | switch tkn { 31 | case LOGICAL_OR: 32 | return 1 33 | 34 | case LOGICAL_AND: 35 | return 2 36 | 37 | case OR, OR_ASSIGN: 38 | return 3 39 | 40 | case EXCLUSIVE_OR: 41 | return 4 42 | 43 | case AND, AND_ASSIGN, AND_NOT, AND_NOT_ASSIGN: 44 | return 5 45 | 46 | case EQUAL, 47 | NOT_EQUAL, 48 | STRICT_EQUAL, 49 | STRICT_NOT_EQUAL: 50 | return 6 51 | 52 | case LESS, GREATER, LESS_OR_EQUAL, GREATER_OR_EQUAL, INSTANCEOF: 53 | return 7 54 | 55 | case IN: 56 | if in { 57 | return 7 58 | } 59 | return 0 60 | 61 | case SHIFT_LEFT, SHIFT_RIGHT, UNSIGNED_SHIFT_RIGHT: 62 | fallthrough 63 | case SHIFT_LEFT_ASSIGN, SHIFT_RIGHT_ASSIGN, UNSIGNED_SHIFT_RIGHT_ASSIGN: 64 | return 8 65 | 66 | case PLUS, MINUS, ADD_ASSIGN, SUBTRACT_ASSIGN: 67 | return 9 68 | 69 | case MULTIPLY, SLASH, REMAINDER, MULTIPLY_ASSIGN, QUOTIENT_ASSIGN, REMAINDER_ASSIGN: 70 | return 11 71 | } 72 | return 0 73 | } 74 | 75 | type _keyword struct { 76 | token Token 77 | futureKeyword bool 78 | strict bool 79 | } 80 | 81 | // IsKeyword returns the keyword token if literal is a keyword, a KEYWORD token 82 | // if the literal is a future keyword (const, let, class, super, ...), or 0 if the literal is not a keyword. 83 | // 84 | // If the literal is a keyword, IsKeyword returns a second value indicating if the literal 85 | // is considered a future keyword in strict-mode only. 86 | // 87 | // 7.6.1.2 Future Reserved Words: 88 | // 89 | // const 90 | // class 91 | // enum 92 | // export 93 | // extends 94 | // import 95 | // super 96 | // 97 | // 7.6.1.2 Future Reserved Words (strict): 98 | // 99 | // implements 100 | // interface 101 | // let 102 | // package 103 | // private 104 | // protected 105 | // public 106 | // static 107 | // 108 | func IsKeyword(literal string) (Token, bool) { 109 | if keyword, exists := keywordTable[literal]; exists { 110 | if keyword.futureKeyword { 111 | return KEYWORD, keyword.strict 112 | } 113 | return keyword.token, false 114 | } 115 | return 0, false 116 | } 117 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_arguments.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "strconv" 5 | ) 6 | 7 | func (runtime *_runtime) newArgumentsObject(indexOfParameterName []string, stash _stash, length int) *_object { 8 | self := runtime.newClassObject("Arguments") 9 | 10 | for index, _ := range indexOfParameterName { 11 | name := strconv.FormatInt(int64(index), 10) 12 | objectDefineOwnProperty(self, name, _property{Value{}, 0111}, false) 13 | } 14 | 15 | self.objectClass = _classArguments 16 | self.value = _argumentsObject{ 17 | indexOfParameterName: indexOfParameterName, 18 | stash: stash, 19 | } 20 | 21 | self.prototype = runtime.global.ObjectPrototype 22 | 23 | self.defineProperty("length", toValue_int(length), 0101, false) 24 | 25 | return self 26 | } 27 | 28 | type _argumentsObject struct { 29 | indexOfParameterName []string 30 | // function(abc, def, ghi) 31 | // indexOfParameterName[0] = "abc" 32 | // indexOfParameterName[1] = "def" 33 | // indexOfParameterName[2] = "ghi" 34 | // ... 35 | stash _stash 36 | } 37 | 38 | func (in _argumentsObject) clone(clone *_clone) _argumentsObject { 39 | indexOfParameterName := make([]string, len(in.indexOfParameterName)) 40 | copy(indexOfParameterName, in.indexOfParameterName) 41 | return _argumentsObject{ 42 | indexOfParameterName, 43 | clone.stash(in.stash), 44 | } 45 | } 46 | 47 | func (self _argumentsObject) get(name string) (Value, bool) { 48 | index := stringToArrayIndex(name) 49 | if index >= 0 && index < int64(len(self.indexOfParameterName)) { 50 | name := self.indexOfParameterName[index] 51 | if name == "" { 52 | return Value{}, false 53 | } 54 | return self.stash.getBinding(name, false), true 55 | } 56 | return Value{}, false 57 | } 58 | 59 | func (self _argumentsObject) put(name string, value Value) { 60 | index := stringToArrayIndex(name) 61 | name = self.indexOfParameterName[index] 62 | self.stash.setBinding(name, value, false) 63 | } 64 | 65 | func (self _argumentsObject) delete(name string) { 66 | index := stringToArrayIndex(name) 67 | self.indexOfParameterName[index] = "" 68 | } 69 | 70 | func argumentsGet(self *_object, name string) Value { 71 | if value, exists := self.value.(_argumentsObject).get(name); exists { 72 | return value 73 | } 74 | return objectGet(self, name) 75 | } 76 | 77 | func argumentsGetOwnProperty(self *_object, name string) *_property { 78 | property := objectGetOwnProperty(self, name) 79 | if value, exists := self.value.(_argumentsObject).get(name); exists { 80 | property.value = value 81 | } 82 | return property 83 | } 84 | 85 | func argumentsDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { 86 | if _, exists := self.value.(_argumentsObject).get(name); exists { 87 | if !objectDefineOwnProperty(self, name, descriptor, false) { 88 | return self.runtime.typeErrorResult(throw) 89 | } 90 | if value, valid := descriptor.value.(Value); valid { 91 | self.value.(_argumentsObject).put(name, value) 92 | } 93 | return true 94 | } 95 | return objectDefineOwnProperty(self, name, descriptor, throw) 96 | } 97 | 98 | func argumentsDelete(self *_object, name string, throw bool) bool { 99 | if !objectDelete(self, name, throw) { 100 | return false 101 | } 102 | if _, exists := self.value.(_argumentsObject).get(name); exists { 103 | self.value.(_argumentsObject).delete(name) 104 | } 105 | return true 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_array.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "strconv" 5 | ) 6 | 7 | func (runtime *_runtime) newArrayObject(length uint32) *_object { 8 | self := runtime.newObject() 9 | self.class = "Array" 10 | self.defineProperty("length", toValue_uint32(length), 0100, false) 11 | self.objectClass = _classArray 12 | return self 13 | } 14 | 15 | func isArray(object *_object) bool { 16 | return object != nil && (object.class == "Array" || object.class == "GoArray") 17 | } 18 | 19 | func objectLength(object *_object) uint32 { 20 | if object == nil { 21 | return 0 22 | } 23 | switch object.class { 24 | case "Array": 25 | return object.get("length").value.(uint32) 26 | case "String": 27 | return uint32(object.get("length").value.(int)) 28 | case "GoArray": 29 | return uint32(object.get("length").value.(int)) 30 | } 31 | return 0 32 | } 33 | 34 | func arrayUint32(rt *_runtime, value Value) uint32 { 35 | nm := value.number() 36 | if nm.kind != numberInteger || !isUint32(nm.int64) { 37 | // FIXME 38 | panic(rt.panicRangeError()) 39 | } 40 | return uint32(nm.int64) 41 | } 42 | 43 | func arrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { 44 | lengthProperty := self.getOwnProperty("length") 45 | lengthValue, valid := lengthProperty.value.(Value) 46 | if !valid { 47 | panic("Array.length != Value{}") 48 | } 49 | length := lengthValue.value.(uint32) 50 | if name == "length" { 51 | if descriptor.value == nil { 52 | return objectDefineOwnProperty(self, name, descriptor, throw) 53 | } 54 | newLengthValue, isValue := descriptor.value.(Value) 55 | if !isValue { 56 | panic(self.runtime.panicTypeError()) 57 | } 58 | newLength := arrayUint32(self.runtime, newLengthValue) 59 | descriptor.value = toValue_uint32(newLength) 60 | if newLength > length { 61 | return objectDefineOwnProperty(self, name, descriptor, throw) 62 | } 63 | if !lengthProperty.writable() { 64 | goto Reject 65 | } 66 | newWritable := true 67 | if descriptor.mode&0700 == 0 { 68 | // If writable is off 69 | newWritable = false 70 | descriptor.mode |= 0100 71 | } 72 | if !objectDefineOwnProperty(self, name, descriptor, throw) { 73 | return false 74 | } 75 | for newLength < length { 76 | length -= 1 77 | if !self.delete(strconv.FormatInt(int64(length), 10), false) { 78 | descriptor.value = toValue_uint32(length + 1) 79 | if !newWritable { 80 | descriptor.mode &= 0077 81 | } 82 | objectDefineOwnProperty(self, name, descriptor, false) 83 | goto Reject 84 | } 85 | } 86 | if !newWritable { 87 | descriptor.mode &= 0077 88 | objectDefineOwnProperty(self, name, descriptor, false) 89 | } 90 | } else if index := stringToArrayIndex(name); index >= 0 { 91 | if index >= int64(length) && !lengthProperty.writable() { 92 | goto Reject 93 | } 94 | if !objectDefineOwnProperty(self, strconv.FormatInt(index, 10), descriptor, false) { 95 | goto Reject 96 | } 97 | if index >= int64(length) { 98 | lengthProperty.value = toValue_uint32(uint32(index + 1)) 99 | objectDefineOwnProperty(self, "length", *lengthProperty, false) 100 | return true 101 | } 102 | } 103 | return objectDefineOwnProperty(self, name, descriptor, throw) 104 | Reject: 105 | if throw { 106 | panic(self.runtime.panicTypeError()) 107 | } 108 | return false 109 | } 110 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_boolean.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "strconv" 5 | ) 6 | 7 | func (runtime *_runtime) newBooleanObject(value Value) *_object { 8 | return runtime.newPrimitiveObject("Boolean", toValue_bool(value.bool())) 9 | } 10 | 11 | func booleanToString(value bool) string { 12 | return strconv.FormatBool(value) 13 | } 14 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_error.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | func (rt *_runtime) newErrorObject(name string, message Value) *_object { 4 | self := rt.newClassObject("Error") 5 | if message.IsDefined() { 6 | msg := message.string() 7 | self.defineProperty("message", toValue_string(msg), 0111, false) 8 | self.value = newError(rt, name, msg) 9 | } else { 10 | self.value = newError(rt, name) 11 | } 12 | return self 13 | } 14 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_go_array.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "reflect" 5 | "strconv" 6 | ) 7 | 8 | func (runtime *_runtime) newGoArrayObject(value reflect.Value) *_object { 9 | self := runtime.newObject() 10 | self.class = "GoArray" 11 | self.objectClass = _classGoArray 12 | self.value = _newGoArrayObject(value) 13 | return self 14 | } 15 | 16 | type _goArrayObject struct { 17 | value reflect.Value 18 | writable bool 19 | propertyMode _propertyMode 20 | } 21 | 22 | func _newGoArrayObject(value reflect.Value) *_goArrayObject { 23 | writable := value.Kind() == reflect.Ptr // The Array is addressable (like a Slice) 24 | mode := _propertyMode(0010) 25 | if writable { 26 | mode = 0110 27 | } 28 | self := &_goArrayObject{ 29 | value: value, 30 | writable: writable, 31 | propertyMode: mode, 32 | } 33 | return self 34 | } 35 | 36 | func (self _goArrayObject) getValue(index int64) (reflect.Value, bool) { 37 | value := reflect.Indirect(self.value) 38 | if index < int64(value.Len()) { 39 | return value.Index(int(index)), true 40 | } 41 | return reflect.Value{}, false 42 | } 43 | 44 | func (self _goArrayObject) setValue(index int64, value Value) bool { 45 | indexValue, exists := self.getValue(index) 46 | if !exists { 47 | return false 48 | } 49 | reflectValue, err := value.toReflectValue(reflect.Indirect(self.value).Type().Elem().Kind()) 50 | if err != nil { 51 | panic(err) 52 | } 53 | indexValue.Set(reflectValue) 54 | return true 55 | } 56 | 57 | func goArrayGetOwnProperty(self *_object, name string) *_property { 58 | // length 59 | if name == "length" { 60 | return &_property{ 61 | value: toValue(reflect.Indirect(self.value.(*_goArrayObject).value).Len()), 62 | mode: 0, 63 | } 64 | } 65 | 66 | // .0, .1, .2, ... 67 | index := stringToArrayIndex(name) 68 | if index >= 0 { 69 | object := self.value.(*_goArrayObject) 70 | value := Value{} 71 | reflectValue, exists := object.getValue(index) 72 | if exists { 73 | value = self.runtime.toValue(reflectValue.Interface()) 74 | } 75 | return &_property{ 76 | value: value, 77 | mode: object.propertyMode, 78 | } 79 | } 80 | 81 | return objectGetOwnProperty(self, name) 82 | } 83 | 84 | func goArrayEnumerate(self *_object, all bool, each func(string) bool) { 85 | object := self.value.(*_goArrayObject) 86 | // .0, .1, .2, ... 87 | 88 | for index, length := 0, object.value.Len(); index < length; index++ { 89 | name := strconv.FormatInt(int64(index), 10) 90 | if !each(name) { 91 | return 92 | } 93 | } 94 | 95 | objectEnumerate(self, all, each) 96 | } 97 | 98 | func goArrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { 99 | if name == "length" { 100 | return self.runtime.typeErrorResult(throw) 101 | } else if index := stringToArrayIndex(name); index >= 0 { 102 | object := self.value.(*_goArrayObject) 103 | if object.writable { 104 | if self.value.(*_goArrayObject).setValue(index, descriptor.value.(Value)) { 105 | return true 106 | } 107 | } 108 | return self.runtime.typeErrorResult(throw) 109 | } 110 | return objectDefineOwnProperty(self, name, descriptor, throw) 111 | } 112 | 113 | func goArrayDelete(self *_object, name string, throw bool) bool { 114 | // length 115 | if name == "length" { 116 | return self.runtime.typeErrorResult(throw) 117 | } 118 | 119 | // .0, .1, .2, ... 120 | index := stringToArrayIndex(name) 121 | if index >= 0 { 122 | object := self.value.(*_goArrayObject) 123 | if object.writable { 124 | indexValue, exists := object.getValue(index) 125 | if exists { 126 | indexValue.Set(reflect.Zero(reflect.Indirect(object.value).Type().Elem())) 127 | return true 128 | } 129 | } 130 | return self.runtime.typeErrorResult(throw) 131 | } 132 | 133 | return self.delete(name, throw) 134 | } 135 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_go_map.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | func (runtime *_runtime) newGoMapObject(value reflect.Value) *_object { 8 | self := runtime.newObject() 9 | self.class = "Object" // TODO Should this be something else? 10 | self.objectClass = _classGoMap 11 | self.value = _newGoMapObject(value) 12 | return self 13 | } 14 | 15 | type _goMapObject struct { 16 | value reflect.Value 17 | keyKind reflect.Kind 18 | valueKind reflect.Kind 19 | } 20 | 21 | func _newGoMapObject(value reflect.Value) *_goMapObject { 22 | if value.Kind() != reflect.Map { 23 | dbgf("%/panic//%@: %v != reflect.Map", value.Kind()) 24 | } 25 | self := &_goMapObject{ 26 | value: value, 27 | keyKind: value.Type().Key().Kind(), 28 | valueKind: value.Type().Elem().Kind(), 29 | } 30 | return self 31 | } 32 | 33 | func (self _goMapObject) toKey(name string) reflect.Value { 34 | reflectValue, err := stringToReflectValue(name, self.keyKind) 35 | if err != nil { 36 | panic(err) 37 | } 38 | return reflectValue 39 | } 40 | 41 | func (self _goMapObject) toValue(value Value) reflect.Value { 42 | reflectValue, err := value.toReflectValue(self.valueKind) 43 | if err != nil { 44 | panic(err) 45 | } 46 | return reflectValue 47 | } 48 | 49 | func goMapGetOwnProperty(self *_object, name string) *_property { 50 | object := self.value.(*_goMapObject) 51 | value := object.value.MapIndex(object.toKey(name)) 52 | if value.IsValid() { 53 | return &_property{self.runtime.toValue(value.Interface()), 0111} 54 | } 55 | 56 | return nil 57 | } 58 | 59 | func goMapEnumerate(self *_object, all bool, each func(string) bool) { 60 | object := self.value.(*_goMapObject) 61 | keys := object.value.MapKeys() 62 | for _, key := range keys { 63 | if !each(key.String()) { 64 | return 65 | } 66 | } 67 | } 68 | 69 | func goMapDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { 70 | object := self.value.(*_goMapObject) 71 | // TODO ...or 0222 72 | if descriptor.mode != 0111 { 73 | return self.runtime.typeErrorResult(throw) 74 | } 75 | if !descriptor.isDataDescriptor() { 76 | return self.runtime.typeErrorResult(throw) 77 | } 78 | object.value.SetMapIndex(object.toKey(name), object.toValue(descriptor.value.(Value))) 79 | return true 80 | } 81 | 82 | func goMapDelete(self *_object, name string, throw bool) bool { 83 | object := self.value.(*_goMapObject) 84 | object.value.SetMapIndex(object.toKey(name), reflect.Value{}) 85 | // FIXME 86 | return true 87 | } 88 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_go_slice.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "reflect" 5 | "strconv" 6 | ) 7 | 8 | func (runtime *_runtime) newGoSliceObject(value reflect.Value) *_object { 9 | self := runtime.newObject() 10 | self.class = "GoArray" // TODO GoSlice? 11 | self.objectClass = _classGoSlice 12 | self.value = _newGoSliceObject(value) 13 | return self 14 | } 15 | 16 | type _goSliceObject struct { 17 | value reflect.Value 18 | } 19 | 20 | func _newGoSliceObject(value reflect.Value) *_goSliceObject { 21 | self := &_goSliceObject{ 22 | value: value, 23 | } 24 | return self 25 | } 26 | 27 | func (self _goSliceObject) getValue(index int64) (reflect.Value, bool) { 28 | if index < int64(self.value.Len()) { 29 | return self.value.Index(int(index)), true 30 | } 31 | return reflect.Value{}, false 32 | } 33 | 34 | func (self _goSliceObject) setValue(index int64, value Value) bool { 35 | indexValue, exists := self.getValue(index) 36 | if !exists { 37 | return false 38 | } 39 | reflectValue, err := value.toReflectValue(self.value.Type().Elem().Kind()) 40 | if err != nil { 41 | panic(err) 42 | } 43 | indexValue.Set(reflectValue) 44 | return true 45 | } 46 | 47 | func goSliceGetOwnProperty(self *_object, name string) *_property { 48 | // length 49 | if name == "length" { 50 | return &_property{ 51 | value: toValue(self.value.(*_goSliceObject).value.Len()), 52 | mode: 0, 53 | } 54 | } 55 | 56 | // .0, .1, .2, ... 57 | index := stringToArrayIndex(name) 58 | if index >= 0 { 59 | value := Value{} 60 | reflectValue, exists := self.value.(*_goSliceObject).getValue(index) 61 | if exists { 62 | value = self.runtime.toValue(reflectValue.Interface()) 63 | } 64 | return &_property{ 65 | value: value, 66 | mode: 0110, 67 | } 68 | } 69 | 70 | return objectGetOwnProperty(self, name) 71 | } 72 | 73 | func goSliceEnumerate(self *_object, all bool, each func(string) bool) { 74 | object := self.value.(*_goSliceObject) 75 | // .0, .1, .2, ... 76 | 77 | for index, length := 0, object.value.Len(); index < length; index++ { 78 | name := strconv.FormatInt(int64(index), 10) 79 | if !each(name) { 80 | return 81 | } 82 | } 83 | 84 | objectEnumerate(self, all, each) 85 | } 86 | 87 | func goSliceDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { 88 | if name == "length" { 89 | return self.runtime.typeErrorResult(throw) 90 | } else if index := stringToArrayIndex(name); index >= 0 { 91 | if self.value.(*_goSliceObject).setValue(index, descriptor.value.(Value)) { 92 | return true 93 | } 94 | return self.runtime.typeErrorResult(throw) 95 | } 96 | return objectDefineOwnProperty(self, name, descriptor, throw) 97 | } 98 | 99 | func goSliceDelete(self *_object, name string, throw bool) bool { 100 | // length 101 | if name == "length" { 102 | return self.runtime.typeErrorResult(throw) 103 | } 104 | 105 | // .0, .1, .2, ... 106 | index := stringToArrayIndex(name) 107 | if index >= 0 { 108 | object := self.value.(*_goSliceObject) 109 | indexValue, exists := object.getValue(index) 110 | if exists { 111 | indexValue.Set(reflect.Zero(object.value.Type().Elem())) 112 | return true 113 | } 114 | return self.runtime.typeErrorResult(throw) 115 | } 116 | 117 | return self.delete(name, throw) 118 | } 119 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_go_struct.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "encoding/json" 5 | "reflect" 6 | ) 7 | 8 | // FIXME Make a note about not being able to modify a struct unless it was 9 | // passed as a pointer-to: &struct{ ... } 10 | // This seems to be a limitation of the reflect package. 11 | // This goes for the other Go constructs too. 12 | // I guess we could get around it by either: 13 | // 1. Creating a new struct every time 14 | // 2. Creating an addressable? struct in the constructor 15 | 16 | func (runtime *_runtime) newGoStructObject(value reflect.Value) *_object { 17 | self := runtime.newObject() 18 | self.class = "Object" // TODO Should this be something else? 19 | self.objectClass = _classGoStruct 20 | self.value = _newGoStructObject(value) 21 | return self 22 | } 23 | 24 | type _goStructObject struct { 25 | value reflect.Value 26 | } 27 | 28 | func _newGoStructObject(value reflect.Value) *_goStructObject { 29 | if reflect.Indirect(value).Kind() != reflect.Struct { 30 | dbgf("%/panic//%@: %v != reflect.Struct", value.Kind()) 31 | } 32 | self := &_goStructObject{ 33 | value: value, 34 | } 35 | return self 36 | } 37 | 38 | func (self _goStructObject) getValue(name string) reflect.Value { 39 | if validGoStructName(name) { 40 | // Do not reveal hidden or unexported fields 41 | if field := reflect.Indirect(self.value).FieldByName(name); (field != reflect.Value{}) { 42 | return field 43 | } 44 | 45 | if method := self.value.MethodByName(name); (method != reflect.Value{}) { 46 | return method 47 | } 48 | } 49 | 50 | return reflect.Value{} 51 | } 52 | 53 | func (self _goStructObject) field(name string) (reflect.StructField, bool) { 54 | return reflect.Indirect(self.value).Type().FieldByName(name) 55 | } 56 | 57 | func (self _goStructObject) method(name string) (reflect.Method, bool) { 58 | return reflect.Indirect(self.value).Type().MethodByName(name) 59 | } 60 | 61 | func (self _goStructObject) setValue(name string, value Value) bool { 62 | field, exists := self.field(name) 63 | if !exists { 64 | return false 65 | } 66 | fieldValue := self.getValue(name) 67 | reflectValue, err := value.toReflectValue(field.Type.Kind()) 68 | if err != nil { 69 | panic(err) 70 | } 71 | fieldValue.Set(reflectValue) 72 | 73 | return true 74 | } 75 | 76 | func goStructGetOwnProperty(self *_object, name string) *_property { 77 | object := self.value.(*_goStructObject) 78 | value := object.getValue(name) 79 | if value.IsValid() { 80 | return &_property{self.runtime.toValue(value.Interface()), 0110} 81 | } 82 | 83 | return objectGetOwnProperty(self, name) 84 | } 85 | 86 | func validGoStructName(name string) bool { 87 | if name == "" { 88 | return false 89 | } 90 | return 'A' <= name[0] && name[0] <= 'Z' // TODO What about Unicode? 91 | } 92 | 93 | func goStructEnumerate(self *_object, all bool, each func(string) bool) { 94 | object := self.value.(*_goStructObject) 95 | 96 | // Enumerate fields 97 | for index := 0; index < reflect.Indirect(object.value).NumField(); index++ { 98 | name := reflect.Indirect(object.value).Type().Field(index).Name 99 | if validGoStructName(name) { 100 | if !each(name) { 101 | return 102 | } 103 | } 104 | } 105 | 106 | // Enumerate methods 107 | for index := 0; index < object.value.NumMethod(); index++ { 108 | name := object.value.Type().Method(index).Name 109 | if validGoStructName(name) { 110 | if !each(name) { 111 | return 112 | } 113 | } 114 | } 115 | 116 | objectEnumerate(self, all, each) 117 | } 118 | 119 | func goStructCanPut(self *_object, name string) bool { 120 | object := self.value.(*_goStructObject) 121 | value := object.getValue(name) 122 | if value.IsValid() { 123 | return true 124 | } 125 | 126 | return objectCanPut(self, name) 127 | } 128 | 129 | func goStructPut(self *_object, name string, value Value, throw bool) { 130 | object := self.value.(*_goStructObject) 131 | if object.setValue(name, value) { 132 | return 133 | } 134 | 135 | objectPut(self, name, value, throw) 136 | } 137 | 138 | func goStructMarshalJSON(self *_object) json.Marshaler { 139 | object := self.value.(*_goStructObject) 140 | goValue := reflect.Indirect(object.value).Interface() 141 | switch marshaler := goValue.(type) { 142 | case json.Marshaler: 143 | return marshaler 144 | } 145 | return nil 146 | } 147 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_number.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | func (runtime *_runtime) newNumberObject(value Value) *_object { 4 | return runtime.newPrimitiveObject("Number", value.numberValue()) 5 | } 6 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_reference.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | type _reference interface { 4 | invalid() bool // IsUnresolvableReference 5 | getValue() Value // getValue 6 | putValue(Value) string // PutValue 7 | delete() bool 8 | } 9 | 10 | // PropertyReference 11 | 12 | type _propertyReference struct { 13 | name string 14 | strict bool 15 | base *_object 16 | runtime *_runtime 17 | at _at 18 | } 19 | 20 | func newPropertyReference(rt *_runtime, base *_object, name string, strict bool, at _at) *_propertyReference { 21 | return &_propertyReference{ 22 | runtime: rt, 23 | name: name, 24 | strict: strict, 25 | base: base, 26 | at: at, 27 | } 28 | } 29 | 30 | func (self *_propertyReference) invalid() bool { 31 | return self.base == nil 32 | } 33 | 34 | func (self *_propertyReference) getValue() Value { 35 | if self.base == nil { 36 | panic(self.runtime.panicReferenceError("'%s' is not defined", self.name, self.at)) 37 | } 38 | return self.base.get(self.name) 39 | } 40 | 41 | func (self *_propertyReference) putValue(value Value) string { 42 | if self.base == nil { 43 | return self.name 44 | } 45 | self.base.put(self.name, value, self.strict) 46 | return "" 47 | } 48 | 49 | func (self *_propertyReference) delete() bool { 50 | if self.base == nil { 51 | // TODO Throw an error if strict 52 | return true 53 | } 54 | return self.base.delete(self.name, self.strict) 55 | } 56 | 57 | // ArgumentReference 58 | 59 | func newArgumentReference(runtime *_runtime, base *_object, name string, strict bool, at _at) *_propertyReference { 60 | if base == nil { 61 | panic(hereBeDragons()) 62 | } 63 | return newPropertyReference(runtime, base, name, strict, at) 64 | } 65 | 66 | type _stashReference struct { 67 | name string 68 | strict bool 69 | base _stash 70 | } 71 | 72 | func (self *_stashReference) invalid() bool { 73 | return false // The base (an environment) will never be nil 74 | } 75 | 76 | func (self *_stashReference) getValue() Value { 77 | return self.base.getBinding(self.name, self.strict) 78 | } 79 | 80 | func (self *_stashReference) putValue(value Value) string { 81 | self.base.setValue(self.name, value, self.strict) 82 | return "" 83 | } 84 | 85 | func (self *_stashReference) delete() bool { 86 | if self.base == nil { 87 | // This should never be reached, but just in case 88 | return false 89 | } 90 | return self.base.deleteBinding(self.name) 91 | } 92 | 93 | // getIdentifierReference 94 | 95 | func getIdentifierReference(runtime *_runtime, stash _stash, name string, strict bool, at _at) _reference { 96 | if stash == nil { 97 | return newPropertyReference(runtime, nil, name, strict, at) 98 | } 99 | if stash.hasBinding(name) { 100 | return stash.newReference(name, strict, at) 101 | } 102 | return getIdentifierReference(runtime, stash.outer(), name, strict, at) 103 | } 104 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/type_string.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "strconv" 5 | "unicode/utf8" 6 | ) 7 | 8 | type _stringObject interface { 9 | Length() int 10 | At(int) rune 11 | String() string 12 | } 13 | 14 | type _stringASCII string 15 | 16 | func (str _stringASCII) Length() int { 17 | return len(str) 18 | } 19 | 20 | func (str _stringASCII) At(at int) rune { 21 | return rune(str[at]) 22 | } 23 | 24 | func (str _stringASCII) String() string { 25 | return string(str) 26 | } 27 | 28 | type _stringWide struct { 29 | string string 30 | length int 31 | runes []rune 32 | } 33 | 34 | func (str _stringWide) Length() int { 35 | return str.length 36 | } 37 | 38 | func (str _stringWide) At(at int) rune { 39 | if str.runes == nil { 40 | str.runes = []rune(str.string) 41 | } 42 | return str.runes[at] 43 | } 44 | 45 | func (str _stringWide) String() string { 46 | return str.string 47 | } 48 | 49 | func _newStringObject(str string) _stringObject { 50 | for i := 0; i < len(str); i++ { 51 | if str[i] >= utf8.RuneSelf { 52 | goto wide 53 | } 54 | } 55 | 56 | return _stringASCII(str) 57 | 58 | wide: 59 | return &_stringWide{ 60 | string: str, 61 | length: utf8.RuneCountInString(str), 62 | } 63 | } 64 | 65 | func stringAt(str _stringObject, index int) rune { 66 | if 0 <= index && index < str.Length() { 67 | return str.At(index) 68 | } 69 | return utf8.RuneError 70 | } 71 | 72 | func (runtime *_runtime) newStringObject(value Value) *_object { 73 | str := _newStringObject(value.string()) 74 | 75 | self := runtime.newClassObject("String") 76 | self.defineProperty("length", toValue_int(str.Length()), 0, false) 77 | self.objectClass = _classString 78 | self.value = str 79 | return self 80 | } 81 | 82 | func (self *_object) stringValue() _stringObject { 83 | if str, ok := self.value.(_stringObject); ok { 84 | return str 85 | } 86 | return nil 87 | } 88 | 89 | func stringEnumerate(self *_object, all bool, each func(string) bool) { 90 | if str := self.stringValue(); str != nil { 91 | length := str.Length() 92 | for index := 0; index < length; index++ { 93 | if !each(strconv.FormatInt(int64(index), 10)) { 94 | return 95 | } 96 | } 97 | } 98 | objectEnumerate(self, all, each) 99 | } 100 | 101 | func stringGetOwnProperty(self *_object, name string) *_property { 102 | if property := objectGetOwnProperty(self, name); property != nil { 103 | return property 104 | } 105 | // TODO Test a string of length >= +int32 + 1? 106 | if index := stringToArrayIndex(name); index >= 0 { 107 | if chr := stringAt(self.stringValue(), int(index)); chr != utf8.RuneError { 108 | return &_property{toValue_string(string(chr)), 0} 109 | } 110 | } 111 | return nil 112 | } 113 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/value_boolean.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "reflect" 7 | ) 8 | 9 | func (value Value) bool() bool { 10 | if value.kind == valueBoolean { 11 | return value.value.(bool) 12 | } 13 | if value.IsUndefined() { 14 | return false 15 | } 16 | if value.IsNull() { 17 | return false 18 | } 19 | switch value := value.value.(type) { 20 | case bool: 21 | return value 22 | case int, int8, int16, int32, int64: 23 | return 0 != reflect.ValueOf(value).Int() 24 | case uint, uint8, uint16, uint32, uint64: 25 | return 0 != reflect.ValueOf(value).Uint() 26 | case float32: 27 | return 0 != value 28 | case float64: 29 | if math.IsNaN(value) || value == 0 { 30 | return false 31 | } 32 | return true 33 | case string: 34 | return 0 != len(value) 35 | } 36 | if value.IsObject() { 37 | return true 38 | } 39 | panic(fmt.Errorf("toBoolean(%T)", value.value)) 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/value_primitive.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | func toStringPrimitive(value Value) Value { 4 | return _toPrimitive(value, defaultValueHintString) 5 | } 6 | 7 | func toNumberPrimitive(value Value) Value { 8 | return _toPrimitive(value, defaultValueHintNumber) 9 | } 10 | 11 | func toPrimitive(value Value) Value { 12 | return _toPrimitive(value, defaultValueNoHint) 13 | } 14 | 15 | func _toPrimitive(value Value, hint _defaultValueHint) Value { 16 | switch value.kind { 17 | case valueNull, valueUndefined, valueNumber, valueString, valueBoolean: 18 | return value 19 | case valueObject: 20 | return value._object().DefaultValue(hint) 21 | } 22 | panic(hereBeDragons(value.kind, value)) 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/robertkrimen/otto/value_string.go: -------------------------------------------------------------------------------- 1 | package otto 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "regexp" 7 | "strconv" 8 | "unicode/utf16" 9 | ) 10 | 11 | var matchLeading0Exponent = regexp.MustCompile(`([eE][\+\-])0+([1-9])`) // 1e-07 => 1e-7 12 | 13 | // FIXME 14 | // https://code.google.com/p/v8/source/browse/branches/bleeding_edge/src/conversions.cc?spec=svn18082&r=18082 15 | func floatToString(value float64, bitsize int) string { 16 | // TODO Fit to ECMA-262 9.8.1 specification 17 | if math.IsNaN(value) { 18 | return "NaN" 19 | } else if math.IsInf(value, 0) { 20 | if math.Signbit(value) { 21 | return "-Infinity" 22 | } 23 | return "Infinity" 24 | } 25 | exponent := math.Log10(math.Abs(value)) 26 | if exponent >= 21 || exponent < -6 { 27 | return matchLeading0Exponent.ReplaceAllString(strconv.FormatFloat(value, 'g', -1, bitsize), "$1$2") 28 | } 29 | return strconv.FormatFloat(value, 'f', -1, bitsize) 30 | } 31 | 32 | func numberToStringRadix(value Value, radix int) string { 33 | float := value.float64() 34 | if math.IsNaN(float) { 35 | return "NaN" 36 | } else if math.IsInf(float, 1) { 37 | return "Infinity" 38 | } else if math.IsInf(float, -1) { 39 | return "-Infinity" 40 | } 41 | // FIXME This is very broken 42 | // Need to do proper radix conversion for floats, ... 43 | // This truncates large floats (so bad). 44 | return strconv.FormatInt(int64(float), radix) 45 | } 46 | 47 | func (value Value) string() string { 48 | if value.kind == valueString { 49 | switch value := value.value.(type) { 50 | case string: 51 | return value 52 | case []uint16: 53 | return string(utf16.Decode(value)) 54 | } 55 | } 56 | if value.IsUndefined() { 57 | return "undefined" 58 | } 59 | if value.IsNull() { 60 | return "null" 61 | } 62 | switch value := value.value.(type) { 63 | case bool: 64 | return strconv.FormatBool(value) 65 | case int: 66 | return strconv.FormatInt(int64(value), 10) 67 | case int8: 68 | return strconv.FormatInt(int64(value), 10) 69 | case int16: 70 | return strconv.FormatInt(int64(value), 10) 71 | case int32: 72 | return strconv.FormatInt(int64(value), 10) 73 | case int64: 74 | return strconv.FormatInt(value, 10) 75 | case uint: 76 | return strconv.FormatUint(uint64(value), 10) 77 | case uint8: 78 | return strconv.FormatUint(uint64(value), 10) 79 | case uint16: 80 | return strconv.FormatUint(uint64(value), 10) 81 | case uint32: 82 | return strconv.FormatUint(uint64(value), 10) 83 | case uint64: 84 | return strconv.FormatUint(value, 10) 85 | case float32: 86 | if value == 0 { 87 | return "0" // Take care not to return -0 88 | } 89 | return floatToString(float64(value), 32) 90 | case float64: 91 | if value == 0 { 92 | return "0" // Take care not to return -0 93 | } 94 | return floatToString(value, 64) 95 | case []uint16: 96 | return string(utf16.Decode(value)) 97 | case string: 98 | return value 99 | case *_object: 100 | return value.DefaultValue(defaultValueHintString).string() 101 | } 102 | panic(fmt.Errorf("%v.string( %T)", value.value, value.value)) 103 | } 104 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/gfx/constants.go: -------------------------------------------------------------------------------- 1 | package gfx 2 | 3 | const ( 4 | FPS_UPPER_LIMIT = 200 5 | FPS_LOWER_LIMIT = 1 6 | FPS_DEFAULT = 30 7 | ) 8 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/gfx/framerate.go: -------------------------------------------------------------------------------- 1 | /* 2 | A pure Go version of SDL_framerate 3 | */ 4 | 5 | package gfx 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | type FPSmanager struct { 12 | framecount uint32 13 | rateticks float64 14 | lastticks uint64 15 | rate uint32 16 | } 17 | 18 | func NewFramerate() *FPSmanager { 19 | return &FPSmanager{ 20 | framecount: 0, 21 | rate: FPS_DEFAULT, 22 | rateticks: (1000.0 / float64(FPS_DEFAULT)), 23 | lastticks: uint64(time.Now().UnixNano()) / 1e6, 24 | } 25 | } 26 | 27 | func (manager *FPSmanager) SetFramerate(rate uint32) { 28 | if rate >= FPS_LOWER_LIMIT && rate <= FPS_UPPER_LIMIT { 29 | manager.framecount = 0 30 | manager.rate = rate 31 | manager.rateticks = 1000.0 / float64(rate) 32 | } else { 33 | } 34 | } 35 | 36 | func (manager *FPSmanager) GetFramerate() uint32 { 37 | return manager.rate 38 | } 39 | 40 | func (manager *FPSmanager) FramerateDelay() { 41 | var current_ticks, target_ticks, the_delay uint64 42 | 43 | // next frame 44 | manager.framecount++ 45 | 46 | // get/calc ticks 47 | current_ticks = uint64(time.Now().UnixNano()) / 1e6 48 | target_ticks = manager.lastticks + uint64(float64(manager.framecount)*manager.rateticks) 49 | 50 | if current_ticks <= target_ticks { 51 | the_delay = target_ticks - current_ticks 52 | time.Sleep(time.Duration(the_delay * 1e6)) 53 | } else { 54 | manager.framecount = 0 55 | manager.lastticks = uint64(time.Now().UnixNano()) / 1e6 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/sdl/audio/callback.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright: ⚛ <0xe2.0x9a.0x9b@gmail.com> 2010 3 | * 4 | * The contents of this file can be used freely, 5 | * except for usages in immoral contexts. 6 | */ 7 | 8 | #include 9 | 10 | typedef void (SDLCALL *callback_t)(void *userdata, Uint8 *stream, int len); 11 | 12 | extern callback_t callback_getCallback(); 13 | extern void callback_fillBuffer(Uint8 *data, size_t numBytes); 14 | extern void callback_unblock(); 15 | 16 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/sdl/event.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | import "time" 4 | 5 | var events chan interface{} = make(chan interface{}) 6 | 7 | // This channel delivers SDL events. Each object received from this channel 8 | // has one of the following types: sdl.QuitEvent, sdl.KeyboardEvent, 9 | // sdl.MouseButtonEvent, sdl.MouseMotionEvent, sdl.ActiveEvent, 10 | // sdl.ResizeEvent, sdl.JoyAxisEvent, sdl.JoyButtonEvent, sdl.JoyHatEvent, 11 | // sdl.JoyBallEvent 12 | var Events <-chan interface{} = events 13 | 14 | // Polling interval, in milliseconds 15 | const poll_interval_ms = 10 16 | 17 | // Polls SDL events in periodic intervals. 18 | // This function does not return. 19 | func pollEvents() { 20 | // It is more efficient to create the event-object here once, 21 | // rather than multiple times within the loop 22 | event := &Event{} 23 | 24 | for { 25 | for event.poll() { 26 | switch event.Type { 27 | case QUIT: 28 | events <- *(*QuitEvent)(cast(event)) 29 | 30 | case KEYDOWN, KEYUP: 31 | events <- *(*KeyboardEvent)(cast(event)) 32 | 33 | case MOUSEBUTTONDOWN, MOUSEBUTTONUP: 34 | events <- *(*MouseButtonEvent)(cast(event)) 35 | 36 | case MOUSEMOTION: 37 | events <- *(*MouseMotionEvent)(cast(event)) 38 | 39 | case JOYAXISMOTION: 40 | events <- *(*JoyAxisEvent)(cast(event)) 41 | 42 | case JOYBUTTONDOWN, JOYBUTTONUP: 43 | events <- *(*JoyButtonEvent)(cast(event)) 44 | 45 | case JOYHATMOTION: 46 | events <- *(*JoyHatEvent)(cast(event)) 47 | 48 | case JOYBALLMOTION: 49 | events <- *(*JoyBallEvent)(cast(event)) 50 | 51 | case ACTIVEEVENT: 52 | events <- *(*ActiveEvent)(cast(event)) 53 | 54 | case VIDEORESIZE: 55 | events <- *(*ResizeEvent)(cast(event)) 56 | } 57 | } 58 | 59 | time.Sleep(poll_interval_ms * 1e6) 60 | } 61 | } 62 | 63 | func init() { 64 | go pollEvents() 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/sdl/sdl_darwin.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | func init() { 8 | if os.Getenv("SDL_VIDEODRIVER") == "" { 9 | os.Setenv("SDL_VIDEODRIVER", "x11") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/sdl/structs_386.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | type PixelFormat struct { 4 | Palette *Palette 5 | BitsPerPixel uint8 6 | BytesPerPixel uint8 7 | Rloss uint8 8 | Gloss uint8 9 | Bloss uint8 10 | Aloss uint8 11 | Rshift uint8 12 | Gshift uint8 13 | Bshift uint8 14 | Ashift uint8 15 | Pad0 [2]byte 16 | Rmask uint32 17 | Gmask uint32 18 | Bmask uint32 19 | Amask uint32 20 | Colorkey uint32 21 | Alpha uint8 22 | Pad1 [3]byte 23 | } 24 | 25 | type Rect struct { 26 | X int16 27 | Y int16 28 | W uint16 29 | H uint16 30 | } 31 | 32 | type Color struct { 33 | R uint8 34 | G uint8 35 | B uint8 36 | Unused uint8 37 | } 38 | 39 | type Palette struct { 40 | Ncolors int32 41 | Colors *Color 42 | } 43 | 44 | type internalVideoInfo struct { 45 | Flags uint32 46 | Video_mem uint32 47 | Vfmt *PixelFormat 48 | Current_w int32 49 | Current_h int32 50 | } 51 | 52 | type Overlay struct { 53 | Format uint32 54 | W int32 55 | H int32 56 | Planes int32 57 | Pitches *uint16 58 | Pixels **uint8 59 | Hwfuncs *[0]byte /* sprivate_yuvhwfuncs */ 60 | Hwdata *[0]byte /* sprivate_yuvhwdata */ 61 | Pad0 [4]byte 62 | } 63 | 64 | type ActiveEvent struct { 65 | Type uint8 66 | Gain uint8 67 | State uint8 68 | } 69 | 70 | type KeyboardEvent struct { 71 | Type uint8 72 | Which uint8 73 | State uint8 74 | Pad0 [1]byte 75 | Keysym Keysym 76 | } 77 | 78 | type MouseMotionEvent struct { 79 | Type uint8 80 | Which uint8 81 | State uint8 82 | Pad0 [1]byte 83 | X uint16 84 | Y uint16 85 | Xrel int16 86 | Yrel int16 87 | } 88 | 89 | type MouseButtonEvent struct { 90 | Type uint8 91 | Which uint8 92 | Button uint8 93 | State uint8 94 | X uint16 95 | Y uint16 96 | } 97 | 98 | type JoyAxisEvent struct { 99 | Type uint8 100 | Which uint8 101 | Axis uint8 102 | Pad0 [1]byte 103 | Value int16 104 | } 105 | 106 | type JoyBallEvent struct { 107 | Type uint8 108 | Which uint8 109 | Ball uint8 110 | Pad0 [1]byte 111 | Xrel int16 112 | Yrel int16 113 | } 114 | 115 | type JoyHatEvent struct { 116 | Type uint8 117 | Which uint8 118 | Hat uint8 119 | Value uint8 120 | } 121 | 122 | type JoyButtonEvent struct { 123 | Type uint8 124 | Which uint8 125 | Button uint8 126 | State uint8 127 | } 128 | 129 | type ResizeEvent struct { 130 | Type uint8 131 | Pad0 [3]byte 132 | W int32 133 | H int32 134 | } 135 | 136 | type ExposeEvent struct { 137 | Type uint8 138 | } 139 | 140 | type QuitEvent struct { 141 | Type uint8 142 | } 143 | 144 | type UserEvent struct { 145 | Type uint8 146 | Pad0 [3]byte 147 | Code int32 148 | Data1 *byte 149 | Data2 *byte 150 | } 151 | 152 | type SysWMmsg struct{} 153 | 154 | type SysWMEvent struct { 155 | Type uint8 156 | Pad0 [3]byte 157 | Msg *SysWMmsg 158 | } 159 | 160 | type Event struct { 161 | Type uint8 162 | Pad0 [19]byte 163 | } 164 | 165 | type Keysym struct { 166 | Scancode uint8 167 | Pad0 [3]byte 168 | Sym uint32 169 | Mod uint32 170 | Unicode uint16 171 | } 172 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/sdl/structs_amd64.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | type PixelFormat struct { 4 | Palette *Palette 5 | BitsPerPixel uint8 6 | BytesPerPixel uint8 7 | Rloss uint8 8 | Gloss uint8 9 | Bloss uint8 10 | Aloss uint8 11 | Rshift uint8 12 | Gshift uint8 13 | Bshift uint8 14 | Ashift uint8 15 | Pad0 [2]byte 16 | Rmask uint32 17 | Gmask uint32 18 | Bmask uint32 19 | Amask uint32 20 | Colorkey uint32 21 | Alpha uint8 22 | Pad1 [7]byte 23 | } 24 | 25 | type Rect struct { 26 | X int16 27 | Y int16 28 | W uint16 29 | H uint16 30 | } 31 | 32 | type Color struct { 33 | R uint8 34 | G uint8 35 | B uint8 36 | Unused uint8 37 | } 38 | 39 | type Palette struct { 40 | Ncolors int32 41 | Pad0 [4]byte 42 | Colors *Color 43 | } 44 | 45 | type internalVideoInfo struct { 46 | Flags uint32 47 | Video_mem uint32 48 | Vfmt *PixelFormat 49 | Current_w int32 50 | Current_h int32 51 | } 52 | 53 | type Overlay struct { 54 | Format uint32 55 | W int32 56 | H int32 57 | Planes int32 58 | Pitches *uint16 59 | Pixels **uint8 60 | Hwfuncs *[0]byte /* sprivate_yuvhwfuncs */ 61 | Hwdata *[0]byte /* sprivate_yuvhwdata */ 62 | Pad0 [8]byte 63 | } 64 | 65 | type ActiveEvent struct { 66 | Type uint8 67 | Gain uint8 68 | State uint8 69 | } 70 | 71 | type KeyboardEvent struct { 72 | Type uint8 73 | Which uint8 74 | State uint8 75 | Pad0 [1]byte 76 | Keysym Keysym 77 | } 78 | 79 | type MouseMotionEvent struct { 80 | Type uint8 81 | Which uint8 82 | State uint8 83 | Pad0 [1]byte 84 | X uint16 85 | Y uint16 86 | Xrel int16 87 | Yrel int16 88 | } 89 | 90 | type MouseButtonEvent struct { 91 | Type uint8 92 | Which uint8 93 | Button uint8 94 | State uint8 95 | X uint16 96 | Y uint16 97 | } 98 | 99 | type JoyAxisEvent struct { 100 | Type uint8 101 | Which uint8 102 | Axis uint8 103 | Pad0 [1]byte 104 | Value int16 105 | } 106 | 107 | type JoyBallEvent struct { 108 | Type uint8 109 | Which uint8 110 | Ball uint8 111 | Pad0 [1]byte 112 | Xrel int16 113 | Yrel int16 114 | } 115 | 116 | type JoyHatEvent struct { 117 | Type uint8 118 | Which uint8 119 | Hat uint8 120 | Value uint8 121 | } 122 | 123 | type JoyButtonEvent struct { 124 | Type uint8 125 | Which uint8 126 | Button uint8 127 | State uint8 128 | } 129 | 130 | type ResizeEvent struct { 131 | Type uint8 132 | Pad0 [3]byte 133 | W int32 134 | H int32 135 | } 136 | 137 | type ExposeEvent struct { 138 | Type uint8 139 | } 140 | 141 | type QuitEvent struct { 142 | Type uint8 143 | } 144 | 145 | type UserEvent struct { 146 | Type uint8 147 | Pad0 [3]byte 148 | Code int32 149 | Data1 *byte 150 | Data2 *byte 151 | } 152 | 153 | type SysWMmsg struct{} 154 | 155 | type SysWMEvent struct { 156 | Type uint8 157 | Pad0 [7]byte 158 | Msg *SysWMmsg 159 | } 160 | 161 | type Event struct { 162 | Type uint8 163 | Pad0 [23]byte 164 | } 165 | 166 | type Keysym struct { 167 | Scancode uint8 168 | Pad0 [3]byte 169 | Sym uint32 170 | Mod uint32 171 | Unicode uint16 172 | } 173 | -------------------------------------------------------------------------------- /vendor/github.com/scottferg/Go-SDL/sdl/structs_arm.go: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | type PixelFormat struct { 4 | Palette *Palette 5 | BitsPerPixel uint8 6 | BytesPerPixel uint8 7 | Rloss uint8 8 | Gloss uint8 9 | Bloss uint8 10 | Aloss uint8 11 | Rshift uint8 12 | Gshift uint8 13 | Bshift uint8 14 | Ashift uint8 15 | Pad0 [2]byte 16 | Rmask uint32 17 | Gmask uint32 18 | Bmask uint32 19 | Amask uint32 20 | Colorkey uint32 21 | Alpha uint8 22 | Pad1 [3]byte 23 | } 24 | 25 | type Rect struct { 26 | X int16 27 | Y int16 28 | W uint16 29 | H uint16 30 | } 31 | 32 | type Color struct { 33 | R uint8 34 | G uint8 35 | B uint8 36 | Unused uint8 37 | } 38 | 39 | type Palette struct { 40 | Ncolors int32 41 | Colors *Color 42 | } 43 | 44 | type internalVideoInfo struct { 45 | Flags uint32 46 | Video_mem uint32 47 | Vfmt *PixelFormat 48 | Current_w int32 49 | Current_h int32 50 | } 51 | 52 | type Overlay struct { 53 | Format uint32 54 | W int32 55 | H int32 56 | Planes int32 57 | Pitches *uint16 58 | Pixels **uint8 59 | Hwfuncs *[0]byte /* sprivate_yuvhwfuncs */ 60 | Hwdata *[0]byte /* sprivate_yuvhwdata */ 61 | Pad0 [4]byte 62 | } 63 | 64 | type ActiveEvent struct { 65 | Type uint8 66 | Gain uint8 67 | State uint8 68 | } 69 | 70 | type KeyboardEvent struct { 71 | Type uint8 72 | Which uint8 73 | State uint8 74 | Pad0 [1]byte 75 | Keysym Keysym 76 | } 77 | 78 | type MouseMotionEvent struct { 79 | Type uint8 80 | Which uint8 81 | State uint8 82 | Pad0 [1]byte 83 | X uint16 84 | Y uint16 85 | Xrel int16 86 | Yrel int16 87 | } 88 | 89 | type MouseButtonEvent struct { 90 | Type uint8 91 | Which uint8 92 | Button uint8 93 | State uint8 94 | X uint16 95 | Y uint16 96 | } 97 | 98 | type JoyAxisEvent struct { 99 | Type uint8 100 | Which uint8 101 | Axis uint8 102 | Pad0 [1]byte 103 | Value int16 104 | } 105 | 106 | type JoyBallEvent struct { 107 | Type uint8 108 | Which uint8 109 | Ball uint8 110 | Pad0 [1]byte 111 | Xrel int16 112 | Yrel int16 113 | } 114 | 115 | type JoyHatEvent struct { 116 | Type uint8 117 | Which uint8 118 | Hat uint8 119 | Value uint8 120 | } 121 | 122 | type JoyButtonEvent struct { 123 | Type uint8 124 | Which uint8 125 | Button uint8 126 | State uint8 127 | } 128 | 129 | type ResizeEvent struct { 130 | Type uint8 131 | Pad0 [3]byte 132 | W int32 133 | H int32 134 | } 135 | 136 | type ExposeEvent struct { 137 | Type uint8 138 | } 139 | 140 | type QuitEvent struct { 141 | Type uint8 142 | } 143 | 144 | type UserEvent struct { 145 | Type uint8 146 | Pad0 [3]byte 147 | Code int32 148 | Data1 *byte 149 | Data2 *byte 150 | } 151 | 152 | type SysWMmsg struct{} 153 | 154 | type SysWMEvent struct { 155 | Type uint8 156 | Pad0 [3]byte 157 | Msg *SysWMmsg 158 | } 159 | 160 | type Event struct { 161 | Type uint8 162 | Pad0 [19]byte 163 | } 164 | 165 | type Keysym struct { 166 | Scancode uint8 167 | Pad0 [3]byte 168 | Sym uint32 169 | Mod uint32 170 | Unicode uint16 171 | } 172 | -------------------------------------------------------------------------------- /vendor/vendor.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "", 3 | "ignore": "test", 4 | "package": [ 5 | { 6 | "path": "github.com/go-gl-legacy/gl", 7 | "revision": "df25b1fe668dbfe300dda6ebca5f3c7397e8ce02", 8 | "revisionTime": "2015-02-22T20:33:40-07:00" 9 | }, 10 | { 11 | "path": "github.com/robertkrimen/otto", 12 | "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", 13 | "revisionTime": "2014-07-02T21:32:54-07:00" 14 | }, 15 | { 16 | "path": "github.com/robertkrimen/otto/ast", 17 | "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", 18 | "revisionTime": "2014-07-02T21:32:54-07:00" 19 | }, 20 | { 21 | "path": "github.com/robertkrimen/otto/dbg", 22 | "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", 23 | "revisionTime": "2014-07-02T21:32:54-07:00" 24 | }, 25 | { 26 | "path": "github.com/robertkrimen/otto/file", 27 | "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", 28 | "revisionTime": "2014-07-02T21:32:54-07:00" 29 | }, 30 | { 31 | "path": "github.com/robertkrimen/otto/parser", 32 | "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", 33 | "revisionTime": "2014-07-02T21:32:54-07:00" 34 | }, 35 | { 36 | "path": "github.com/robertkrimen/otto/registry", 37 | "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", 38 | "revisionTime": "2014-07-02T21:32:54-07:00" 39 | }, 40 | { 41 | "path": "github.com/robertkrimen/otto/token", 42 | "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", 43 | "revisionTime": "2014-07-02T21:32:54-07:00" 44 | }, 45 | { 46 | "path": "github.com/scottferg/Go-SDL/gfx", 47 | "revision": "0d190b34634e10542215b00d6fe69f2b7f1254ce", 48 | "revisionTime": "2013-09-19T12:59:28-07:00" 49 | }, 50 | { 51 | "path": "github.com/scottferg/Go-SDL/sdl", 52 | "revision": "0d190b34634e10542215b00d6fe69f2b7f1254ce", 53 | "revisionTime": "2013-09-19T12:59:28-07:00" 54 | }, 55 | { 56 | "path": "github.com/scottferg/Go-SDL/sdl/audio", 57 | "revision": "0d190b34634e10542215b00d6fe69f2b7f1254ce", 58 | "revisionTime": "2013-09-19T12:59:28-07:00" 59 | } 60 | ] 61 | } 62 | --------------------------------------------------------------------------------