├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── dummy ├── Makefile ├── dummy.go ├── go.mod ├── go.sum └── nacp.json ├── go-switch.jpg ├── graphics └── gbatest │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── nacp.json ├── minimal ├── Makefile ├── go.mod ├── go.sum ├── minimal.go └── nacp.json └── tests ├── Makefile ├── colors.go ├── go.mod ├── go.sum ├── minimal.go └── nacp.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.elf 3 | *.nro 4 | upload.sh 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := $(wildcard **/**/**/.) 2 | 3 | all: $(SUBDIRS) 4 | 5 | $(SUBDIRS): 6 | $(MAKE) -C $@ 7 | 8 | 9 | .PHONY: all $(SUBDIRS) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Golang Nintendo Switch Examples 2 | 3 | Examples using TinyGo for Nintendo Switch 4 | 5 | # Requirements 6 | 7 | * DevKitPro for Switch (see [Setting up Development Environment](https://switchbrew.org/wiki/Setting_up_Development_Environment)) 8 | * TinyGo with Nintendo Switch Support (https://github.com/racerxdl/tinygo on nintendoswitch branch) 9 | * Linkle (see [https://github.com/MegatonHammer/linkle](https://github.com/MegatonHammer/linkle)) 10 | 11 | # Building a example 12 | 13 | Go to the example folder and then run: 14 | 15 | ```bash 16 | tinygo build -target nintendo-switch -o hello-world.elf 17 | linkle nro hello-world.elf hello-world.nro 18 | ``` 19 | 20 | That should generate a `nro` file that runs on [Yuzu](https://yuzu-emu.org/) or [Atmosphere](https://github.com/Atmosphere-NX/Atmosphere/) 21 | 22 | If you have linkle and tinygo in path, you can run `make` -------------------------------------------------------------------------------- /dummy/Makefile: -------------------------------------------------------------------------------- 1 | 2 | export OUTPUT := $(CURDIR) 3 | export PROGRAMNAME := $(notdir $(CURDIR)) 4 | export PROGRAM := $(OUTPUT)/$(PROGRAMNAME) 5 | 6 | .PHONY: $(BUILD) clean all 7 | 8 | all: $(PROGRAM).nro 9 | 10 | clean: 11 | @rm -fr $(PROGRAM).elf $(PROGRAM).nro 12 | 13 | $(PROGRAM).nro: $(PROGRAM).elf 14 | @echo "Building nro" 15 | @linkle nro $(PROGRAM).elf $(PROGRAM).nro --icon-path=../go-switch.jpg --nacp-path=$(OUTPUT)/nacp.json 16 | 17 | $(PROGRAM).elf: 18 | @echo "Building elf" 19 | @tinygo build -target nintendo-switch -opt=2 -o $(PROGRAM).elf 20 | -------------------------------------------------------------------------------- /dummy/dummy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/racerxdl/gonx/svc" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Hello world to debug console!") 10 | 11 | svc.Break(0, 0, 0) 12 | 13 | for { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dummy/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/racerxdl/go-switch-examples/dummy 2 | 3 | go 1.14 4 | 5 | require github.com/racerxdl/gonx v0.0.0-20210102224128-6d0998d45c2e 6 | -------------------------------------------------------------------------------- /dummy/go.sum: -------------------------------------------------------------------------------- 1 | github.com/racerxdl/gonx v0.0.0-20210102224128-6d0998d45c2e h1:/ZLUQalGCUpXhskYi7QceGFZyZfgbuKQt/WJM9DfVvE= 2 | github.com/racerxdl/gonx v0.0.0-20210102224128-6d0998d45c2e/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 3 | -------------------------------------------------------------------------------- /dummy/nacp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Dummy Example", 3 | "author": "Lucas Teske", 4 | "version": "1.0.0", 5 | "title_id": "0100000000020000" 6 | } 7 | -------------------------------------------------------------------------------- /go-switch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/racerxdl/go-switch-examples/9b18dd789feb2bfe2e7bb22ac837b18993ef2a8d/go-switch.jpg -------------------------------------------------------------------------------- /graphics/gbatest/Makefile: -------------------------------------------------------------------------------- 1 | export OUTPUT := $(CURDIR) 2 | export PROGRAMNAME := $(notdir $(CURDIR)) 3 | export PROGRAM := $(OUTPUT)/$(PROGRAMNAME) 4 | 5 | .PHONY: $(BUILD) clean all 6 | 7 | all: $(PROGRAM).nro 8 | 9 | clean: 10 | @rm -fr $(PROGRAM).elf $(PROGRAM).nro 11 | 12 | $(PROGRAM).nro: $(PROGRAM).elf 13 | @echo "Building nro" 14 | @linkle nro $(PROGRAM).elf $(PROGRAM).nro --icon-path=../../go-switch.jpg --nacp-path=$(OUTPUT)/nacp.json 15 | @echo NRO at $(PROGRAM).nro 16 | 17 | $(PROGRAM).elf: 18 | @echo "Building elf" 19 | @tinygo build -target nintendoswitch -opt=2 -o $(PROGRAM).elf 20 | @echo "ELF at $(PROGRAM).elf" 21 | -------------------------------------------------------------------------------- /graphics/gbatest/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/racerxdl/go-switch-examples/graphics/gbatest 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/racerxdl/gonx v0.0.0-20210103083128-c5afc43bcbd2 7 | tinygo.org/x/drivers v0.14.0 8 | tinygo.org/x/tinydraw v0.0.0-20200416172542-c30d6d84353c 9 | tinygo.org/x/tinyfont v0.2.1 10 | ) 11 | -------------------------------------------------------------------------------- /graphics/gbatest/go.sum: -------------------------------------------------------------------------------- 1 | github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= 2 | github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s= 3 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 4 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 5 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 6 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 7 | github.com/racerxdl/gonx v0.0.0-20200516060607-124c438d76cd h1:9iobHBYrJ6WRKu6aW3bwLXob8LDK369fQll7zxASraw= 8 | github.com/racerxdl/gonx v0.0.0-20200516060607-124c438d76cd/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 9 | github.com/racerxdl/gonx v0.0.0-20210102222404-7370d4611b04 h1:j3QAMVgFYIwAUO/PfPVEX16LcRjjZgdFnIdAsQ6zgZ4= 10 | github.com/racerxdl/gonx v0.0.0-20210102222404-7370d4611b04/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 11 | github.com/racerxdl/gonx v0.0.0-20210102222941-23263f205de5 h1:T8gJDonGPOFe8lTsabQdi4v/bI6U+xC9u5EQZZEsk5w= 12 | github.com/racerxdl/gonx v0.0.0-20210102222941-23263f205de5/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 13 | github.com/racerxdl/gonx v0.0.0-20210102224128-6d0998d45c2e h1:/ZLUQalGCUpXhskYi7QceGFZyZfgbuKQt/WJM9DfVvE= 14 | github.com/racerxdl/gonx v0.0.0-20210102224128-6d0998d45c2e/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 15 | github.com/racerxdl/gonx v0.0.0-20210103083128-c5afc43bcbd2 h1:1zRLfGfK2C63wk+MrCz9Ee50CV4KLfDihJbzSoiQBdM= 16 | github.com/racerxdl/gonx v0.0.0-20210103083128-c5afc43bcbd2/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 17 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 18 | tinygo.org/x/drivers v0.14.0 h1:wT09pltZS8f8ysmRG96nvFsngZ34/6lBQl+rscq0TCY= 19 | tinygo.org/x/drivers v0.14.0/go.mod h1:uT2svMq3EpBZpKkGO+NQHjxjGf1f42ra4OnMMwQL2aI= 20 | tinygo.org/x/tinydraw v0.0.0-20200416172542-c30d6d84353c h1:QKOUxoOXDNosHIoX7PrANTGd5nmLjKKFZ81pXhkjw58= 21 | tinygo.org/x/tinydraw v0.0.0-20200416172542-c30d6d84353c/go.mod h1:ygmD8mKwhhF6HLXIs4FCe5JTYurTD2w32cmymeaYrEw= 22 | tinygo.org/x/tinyfont v0.2.1 h1:FAaemBzw8wsfhAtG6fWW+QjyWw/K8YqEeiWo4N1pv4o= 23 | tinygo.org/x/tinyfont v0.2.1/go.mod h1:eLqnYSrFRjt5STxWaMeOWJTzrKhXqpWw7nU3bPfKOAM= 24 | -------------------------------------------------------------------------------- /graphics/gbatest/main.go: -------------------------------------------------------------------------------- 1 | // Based on https://github.com/conejoninja/gbatest 2 | // but ported to nintendoswitch 3 | package main 4 | 5 | // Draw a red square on the GameBoy Advance screen. 6 | 7 | import ( 8 | "fmt" 9 | "github.com/racerxdl/gonx/nintendoswitch" 10 | "github.com/racerxdl/gonx/services/display" 11 | "github.com/racerxdl/gonx/svc" 12 | "image/color" 13 | "tinygo.org/x/drivers" 14 | "tinygo.org/x/tinydraw" 15 | "tinygo.org/x/tinyfont" 16 | "tinygo.org/x/tinyfont/freemono" 17 | "tinygo.org/x/tinyfont/freesans" 18 | "tinygo.org/x/tinyfont/gophers" 19 | ) 20 | 21 | func main() { 22 | err := nintendoswitch.Configure() 23 | if err != nil { 24 | println("error initializing nintendoswitch: ", err) 25 | svc.Break(0x4442, 0, 0) 26 | return 27 | } 28 | defer nintendoswitch.Cleanup() 29 | 30 | fmt.Println("Fetching surface") 31 | surface, err := display.OpenLayer() 32 | if err != nil { 33 | fmt.Printf("Error getting surface: %s\n", err) 34 | return 35 | } 36 | 37 | fmt.Println("Fetching Frame") 38 | frame, err := surface.GetFrame() 39 | if err != nil { 40 | fmt.Printf("Error getting frame: %s\n", err) 41 | return 42 | } 43 | 44 | frames := 0 45 | 46 | for { 47 | if frames%8 == 0 { 48 | update(frame) 49 | } 50 | 51 | frames++ 52 | 53 | err = frame.Display() 54 | if err != nil { 55 | fmt.Printf("Error displaying data: %s\n", err) 56 | return 57 | } 58 | 59 | err = frame.WaitVSync() 60 | if err != nil { 61 | fmt.Println("Error waiting vsync", err) 62 | return 63 | } 64 | //time.Sleep(time.Millisecond * 10) 65 | } 66 | } 67 | 68 | var ( 69 | krgb = uint8(0) 70 | ) 71 | 72 | func drawLogo(display drivers.Displayer, x, y int16) { 73 | tinyfont.DrawChar(display, &freesans.Bold24pt7b, x+36, y+60, 'T', getRainbowRGB(krgb)) 74 | tinyfont.DrawChar(display, &freesans.Bold24pt7b, x+66, y+60, 'i', getRainbowRGB(1+krgb)) 75 | tinyfont.DrawChar(display, &freesans.Bold24pt7b, x+79, y+60, 'n', getRainbowRGB(2+krgb)) 76 | tinyfont.DrawChar(display, &freesans.Bold24pt7b, x+108, y+60, 'y', getRainbowRGB(3+krgb)) 77 | tinyfont.DrawChar(display, &freesans.Bold24pt7b, x+134, y+60, 'G', getRainbowRGB(4+krgb)) 78 | tinyfont.DrawChar(display, &freesans.Bold24pt7b, x+170, y+60, 'o', getRainbowRGB(5+krgb)) 79 | } 80 | 81 | func drawFosdem(display drivers.Displayer, x, y int16) { 82 | fosdemXOffset := int16(100) 83 | tinyfont.WriteLine(display, &freemono.Bold9pt7b, x+70, y+90, "Go compiler for small places", rescale(color.RGBA{R: 10, G: 30, B: 30, A: 255})) 84 | tinydraw.Triangle(display, x+60+fosdemXOffset, y+110, x+60+fosdemXOffset, y+126, x+174+fosdemXOffset, y+110, rescale(color.RGBA{R: 20, G: 20, A: 255})) 85 | tinydraw.Triangle(display, x+72+fosdemXOffset, y+136, x+184+fosdemXOffset, y+136, x+184+fosdemXOffset, y+120, rescale(color.RGBA{R: 20, B: 20, A: 255})) 86 | tinyfont.WriteLine(display, &freesans.Bold9pt7b, x+68+fosdemXOffset, y+130, "FOSDEM '20", rescale(color.RGBA{R: 10, G: 30, B: 30, A: 255})) 87 | } 88 | 89 | func drawGophers(display drivers.Displayer, x, y int16) { 90 | if krgb >= 40 { 91 | krgb = 0 92 | } 93 | if krgb%2 == 0 { 94 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+14, y+140, 'N', rescale(color.RGBA{A: 255})) 95 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+230, y+140, 'G', rescale(color.RGBA{A: 255})) 96 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+230, y+140, 'N', getRainbowRGB(krgb)) 97 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+14, y+140, 'G', getRainbowRGB(krgb)) 98 | } else { 99 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+230, y+140, 'N', rescale(color.RGBA{A: 255})) 100 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+14, y+140, 'G', rescale(color.RGBA{A: 255})) 101 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+14, y+140, 'N', getRainbowRGB(krgb)) 102 | tinyfont.DrawChar(display, &gophers.Regular121pt, x+230, y+140, 'G', getRainbowRGB(krgb)) 103 | } 104 | } 105 | 106 | func update(display drivers.Displayer) { 107 | drawLogo(display, 514, 200) 108 | drawFosdem(display, 412, 200) 109 | drawGophers(display, 480, 250) 110 | krgb++ 111 | } 112 | 113 | func getRainbowRGB(i uint8) color.RGBA { 114 | if i < 10 { 115 | return rescale(color.RGBA{R: i * 3, G: 30 - i*3, A: 255}) 116 | } else if i < 20 { 117 | i -= 10 118 | return rescale(color.RGBA{R: 30 - i*3, B: i * 3, A: 255}) 119 | } 120 | i -= 20 121 | return rescale(color.RGBA{G: i * 3, B: 30 - i*3, A: 255}) 122 | } 123 | 124 | func rescale(c color.RGBA) color.RGBA { 125 | return color.RGBA{R: c.R * 4, G: c.G * 4, B: c.B * 4, A: c.A} 126 | } 127 | -------------------------------------------------------------------------------- /graphics/gbatest/nacp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GBATest", 3 | "author": "Daniel Esteban, Lucas Teske", 4 | "version": "1.0.0", 5 | "title_id": "0100000000020004" 6 | } 7 | -------------------------------------------------------------------------------- /minimal/Makefile: -------------------------------------------------------------------------------- 1 | 2 | export OUTPUT := $(CURDIR) 3 | export PROGRAMNAME := $(notdir $(CURDIR)) 4 | export PROGRAM := $(OUTPUT)/$(PROGRAMNAME) 5 | 6 | .PHONY: $(BUILD) clean all 7 | 8 | all: $(PROGRAM).nro 9 | 10 | clean: 11 | @rm -fr $(PROGRAM).elf $(PROGRAM).nro 12 | 13 | $(PROGRAM).nro: $(PROGRAM).elf 14 | @echo "Building nro" 15 | @linkle nro $(PROGRAM).elf $(PROGRAM).nro --icon-path=../go-switch.jpg --nacp-path=$(OUTPUT)/nacp.json 16 | 17 | $(PROGRAM).elf: 18 | @echo "Building elf" 19 | @tinygo build -target nintendoswitch -opt=1 -o $(PROGRAM).elf 20 | -------------------------------------------------------------------------------- /minimal/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/racerxdl/go-switch-examples/minimal 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /minimal/go.sum: -------------------------------------------------------------------------------- 1 | github.com/tinygo-org/tinygo v0.13.1 h1:fp7l5wUK7BFTHCfZz4F9GK0d14VG22Bk9eKmsnf4X4U= 2 | -------------------------------------------------------------------------------- /minimal/minimal.go: -------------------------------------------------------------------------------- 1 | // This program is a minimal Nintendo Switch program that just outputs messages to 2 | // emulator console 3 | package main 4 | 5 | func test2() { 6 | panic("test2") 7 | } 8 | 9 | func main() { 10 | println("Hello world!") 11 | println("ABC", 123, 343) 12 | //panic("TEST") 13 | 14 | x := 0 15 | 16 | for x < 100 { 17 | x++ 18 | println("CYCLE") 19 | if x > 50 { 20 | test2() 21 | } 22 | } 23 | 24 | // 25 | // 26 | //for { 27 | // println("Cycle!!") 28 | // time.Sleep(time.Second) 29 | //} 30 | panic("TAS") 31 | } 32 | -------------------------------------------------------------------------------- /minimal/nacp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Minimal", 3 | "author": "Lucas Teske", 4 | "version": "1.0.0", 5 | "title_id": "0100000000020000" 6 | } 7 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | 2 | export OUTPUT := $(CURDIR) 3 | export PROGRAMNAME := $(notdir $(CURDIR)) 4 | export PROGRAM := $(OUTPUT)/$(PROGRAMNAME) 5 | 6 | .PHONY: $(BUILD) clean all 7 | 8 | all: $(PROGRAM).nro 9 | 10 | clean: 11 | @rm -fr $(PROGRAM).elf $(PROGRAM).nro 12 | 13 | tinygonro: 14 | @echo "building nro using tinygo" 15 | @tinygo build -target nintendoswitch -o $(PROGRAM).nro 16 | #@tinygo build -target nintendoswitch -opt=1 -o $(PROGRAM).nro 17 | $(PROGRAM).nro: $(PROGRAM).elf 18 | @echo "Building nro" 19 | @linkle nro $(PROGRAM).elf $(PROGRAM).nro --icon-path=../go-switch.jpg --nacp-path=$(OUTPUT)/nacp.json 20 | 21 | $(PROGRAM).elf: 22 | @echo "Building elf" 23 | @tinygo build -target nintendoswitch -opt=2 -o $(PROGRAM).elf 24 | -------------------------------------------------------------------------------- /tests/colors.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "image/color" 4 | 5 | var ( 6 | Aliceblue = color.RGBA{0xf0, 0xf8, 0xff, 0xff} // rgb(240, 248, 255) 7 | Antiquewhite = color.RGBA{0xfa, 0xeb, 0xd7, 0xff} // rgb(250, 235, 215) 8 | Aqua = color.RGBA{0x00, 0xff, 0xff, 0xff} // rgb(0, 255, 255) 9 | Aquamarine = color.RGBA{0x7f, 0xff, 0xd4, 0xff} // rgb(127, 255, 212) 10 | Azure = color.RGBA{0xf0, 0xff, 0xff, 0xff} // rgb(240, 255, 255) 11 | Beige = color.RGBA{0xf5, 0xf5, 0xdc, 0xff} // rgb(245, 245, 220) 12 | Bisque = color.RGBA{0xff, 0xe4, 0xc4, 0xff} // rgb(255, 228, 196) 13 | Black = color.RGBA{0x00, 0x00, 0x00, 0xff} // rgb(0, 0, 0) 14 | Blanchedalmond = color.RGBA{0xff, 0xeb, 0xcd, 0xff} // rgb(255, 235, 205) 15 | Blue = color.RGBA{0x00, 0x00, 0xff, 0xff} // rgb(0, 0, 255) 16 | Blueviolet = color.RGBA{0x8a, 0x2b, 0xe2, 0xff} // rgb(138, 43, 226) 17 | Brown = color.RGBA{0xa5, 0x2a, 0x2a, 0xff} // rgb(165, 42, 42) 18 | Burlywood = color.RGBA{0xde, 0xb8, 0x87, 0xff} // rgb(222, 184, 135) 19 | Cadetblue = color.RGBA{0x5f, 0x9e, 0xa0, 0xff} // rgb(95, 158, 160) 20 | Chartreuse = color.RGBA{0x7f, 0xff, 0x00, 0xff} // rgb(127, 255, 0) 21 | Chocolate = color.RGBA{0xd2, 0x69, 0x1e, 0xff} // rgb(210, 105, 30) 22 | Coral = color.RGBA{0xff, 0x7f, 0x50, 0xff} // rgb(255, 127, 80) 23 | Cornflowerblue = color.RGBA{0x64, 0x95, 0xed, 0xff} // rgb(100, 149, 237) 24 | Cornsilk = color.RGBA{0xff, 0xf8, 0xdc, 0xff} // rgb(255, 248, 220) 25 | Crimson = color.RGBA{0xdc, 0x14, 0x3c, 0xff} // rgb(220, 20, 60) 26 | Cyan = color.RGBA{0x00, 0xff, 0xff, 0xff} // rgb(0, 255, 255) 27 | Darkblue = color.RGBA{0x00, 0x00, 0x8b, 0xff} // rgb(0, 0, 139) 28 | Darkcyan = color.RGBA{0x00, 0x8b, 0x8b, 0xff} // rgb(0, 139, 139) 29 | Darkgoldenrod = color.RGBA{0xb8, 0x86, 0x0b, 0xff} // rgb(184, 134, 11) 30 | Darkgray = color.RGBA{0xa9, 0xa9, 0xa9, 0xff} // rgb(169, 169, 169) 31 | Darkgreen = color.RGBA{0x00, 0x64, 0x00, 0xff} // rgb(0, 100, 0) 32 | Darkgrey = color.RGBA{0xa9, 0xa9, 0xa9, 0xff} // rgb(169, 169, 169) 33 | Darkkhaki = color.RGBA{0xbd, 0xb7, 0x6b, 0xff} // rgb(189, 183, 107) 34 | Darkmagenta = color.RGBA{0x8b, 0x00, 0x8b, 0xff} // rgb(139, 0, 139) 35 | Darkolivegreen = color.RGBA{0x55, 0x6b, 0x2f, 0xff} // rgb(85, 107, 47) 36 | Darkorange = color.RGBA{0xff, 0x8c, 0x00, 0xff} // rgb(255, 140, 0) 37 | Darkorchid = color.RGBA{0x99, 0x32, 0xcc, 0xff} // rgb(153, 50, 204) 38 | Darkred = color.RGBA{0x8b, 0x00, 0x00, 0xff} // rgb(139, 0, 0) 39 | Darksalmon = color.RGBA{0xe9, 0x96, 0x7a, 0xff} // rgb(233, 150, 122) 40 | Darkseagreen = color.RGBA{0x8f, 0xbc, 0x8f, 0xff} // rgb(143, 188, 143) 41 | Darkslateblue = color.RGBA{0x48, 0x3d, 0x8b, 0xff} // rgb(72, 61, 139) 42 | Darkslategray = color.RGBA{0x2f, 0x4f, 0x4f, 0xff} // rgb(47, 79, 79) 43 | Darkslategrey = color.RGBA{0x2f, 0x4f, 0x4f, 0xff} // rgb(47, 79, 79) 44 | Darkturquoise = color.RGBA{0x00, 0xce, 0xd1, 0xff} // rgb(0, 206, 209) 45 | Darkviolet = color.RGBA{0x94, 0x00, 0xd3, 0xff} // rgb(148, 0, 211) 46 | Deeppink = color.RGBA{0xff, 0x14, 0x93, 0xff} // rgb(255, 20, 147) 47 | Deepskyblue = color.RGBA{0x00, 0xbf, 0xff, 0xff} // rgb(0, 191, 255) 48 | Dimgray = color.RGBA{0x69, 0x69, 0x69, 0xff} // rgb(105, 105, 105) 49 | Dimgrey = color.RGBA{0x69, 0x69, 0x69, 0xff} // rgb(105, 105, 105) 50 | Dodgerblue = color.RGBA{0x1e, 0x90, 0xff, 0xff} // rgb(30, 144, 255) 51 | Firebrick = color.RGBA{0xb2, 0x22, 0x22, 0xff} // rgb(178, 34, 34) 52 | Floralwhite = color.RGBA{0xff, 0xfa, 0xf0, 0xff} // rgb(255, 250, 240) 53 | Forestgreen = color.RGBA{0x22, 0x8b, 0x22, 0xff} // rgb(34, 139, 34) 54 | Fuchsia = color.RGBA{0xff, 0x00, 0xff, 0xff} // rgb(255, 0, 255) 55 | Gainsboro = color.RGBA{0xdc, 0xdc, 0xdc, 0xff} // rgb(220, 220, 220) 56 | Ghostwhite = color.RGBA{0xf8, 0xf8, 0xff, 0xff} // rgb(248, 248, 255) 57 | Gold = color.RGBA{0xff, 0xd7, 0x00, 0xff} // rgb(255, 215, 0) 58 | Goldenrod = color.RGBA{0xda, 0xa5, 0x20, 0xff} // rgb(218, 165, 32) 59 | Gray = color.RGBA{0x80, 0x80, 0x80, 0xff} // rgb(128, 128, 128) 60 | Green = color.RGBA{0x00, 0x80, 0x00, 0xff} // rgb(0, 128, 0) 61 | Greenyellow = color.RGBA{0xad, 0xff, 0x2f, 0xff} // rgb(173, 255, 47) 62 | Grey = color.RGBA{0x80, 0x80, 0x80, 0xff} // rgb(128, 128, 128) 63 | Honeydew = color.RGBA{0xf0, 0xff, 0xf0, 0xff} // rgb(240, 255, 240) 64 | Hotpink = color.RGBA{0xff, 0x69, 0xb4, 0xff} // rgb(255, 105, 180) 65 | Indianred = color.RGBA{0xcd, 0x5c, 0x5c, 0xff} // rgb(205, 92, 92) 66 | Indigo = color.RGBA{0x4b, 0x00, 0x82, 0xff} // rgb(75, 0, 130) 67 | Ivory = color.RGBA{0xff, 0xff, 0xf0, 0xff} // rgb(255, 255, 240) 68 | Khaki = color.RGBA{0xf0, 0xe6, 0x8c, 0xff} // rgb(240, 230, 140) 69 | Lavender = color.RGBA{0xe6, 0xe6, 0xfa, 0xff} // rgb(230, 230, 250) 70 | Lavenderblush = color.RGBA{0xff, 0xf0, 0xf5, 0xff} // rgb(255, 240, 245) 71 | Lawngreen = color.RGBA{0x7c, 0xfc, 0x00, 0xff} // rgb(124, 252, 0) 72 | Lemonchiffon = color.RGBA{0xff, 0xfa, 0xcd, 0xff} // rgb(255, 250, 205) 73 | Lightblue = color.RGBA{0xad, 0xd8, 0xe6, 0xff} // rgb(173, 216, 230) 74 | Lightcoral = color.RGBA{0xf0, 0x80, 0x80, 0xff} // rgb(240, 128, 128) 75 | Lightcyan = color.RGBA{0xe0, 0xff, 0xff, 0xff} // rgb(224, 255, 255) 76 | Lightgoldenrodyellow = color.RGBA{0xfa, 0xfa, 0xd2, 0xff} // rgb(250, 250, 210) 77 | Lightgray = color.RGBA{0xd3, 0xd3, 0xd3, 0xff} // rgb(211, 211, 211) 78 | Lightgreen = color.RGBA{0x90, 0xee, 0x90, 0xff} // rgb(144, 238, 144) 79 | Lightgrey = color.RGBA{0xd3, 0xd3, 0xd3, 0xff} // rgb(211, 211, 211) 80 | Lightpink = color.RGBA{0xff, 0xb6, 0xc1, 0xff} // rgb(255, 182, 193) 81 | Lightsalmon = color.RGBA{0xff, 0xa0, 0x7a, 0xff} // rgb(255, 160, 122) 82 | Lightseagreen = color.RGBA{0x20, 0xb2, 0xaa, 0xff} // rgb(32, 178, 170) 83 | Lightskyblue = color.RGBA{0x87, 0xce, 0xfa, 0xff} // rgb(135, 206, 250) 84 | Lightslategray = color.RGBA{0x77, 0x88, 0x99, 0xff} // rgb(119, 136, 153) 85 | Lightslategrey = color.RGBA{0x77, 0x88, 0x99, 0xff} // rgb(119, 136, 153) 86 | Lightsteelblue = color.RGBA{0xb0, 0xc4, 0xde, 0xff} // rgb(176, 196, 222) 87 | Lightyellow = color.RGBA{0xff, 0xff, 0xe0, 0xff} // rgb(255, 255, 224) 88 | Lime = color.RGBA{0x00, 0xff, 0x00, 0xff} // rgb(0, 255, 0) 89 | Limegreen = color.RGBA{0x32, 0xcd, 0x32, 0xff} // rgb(50, 205, 50) 90 | Linen = color.RGBA{0xfa, 0xf0, 0xe6, 0xff} // rgb(250, 240, 230) 91 | Magenta = color.RGBA{0xff, 0x00, 0xff, 0xff} // rgb(255, 0, 255) 92 | Maroon = color.RGBA{0x80, 0x00, 0x00, 0xff} // rgb(128, 0, 0) 93 | Mediumaquamarine = color.RGBA{0x66, 0xcd, 0xaa, 0xff} // rgb(102, 205, 170) 94 | Mediumblue = color.RGBA{0x00, 0x00, 0xcd, 0xff} // rgb(0, 0, 205) 95 | Mediumorchid = color.RGBA{0xba, 0x55, 0xd3, 0xff} // rgb(186, 85, 211) 96 | Mediumpurple = color.RGBA{0x93, 0x70, 0xdb, 0xff} // rgb(147, 112, 219) 97 | Mediumseagreen = color.RGBA{0x3c, 0xb3, 0x71, 0xff} // rgb(60, 179, 113) 98 | Mediumslateblue = color.RGBA{0x7b, 0x68, 0xee, 0xff} // rgb(123, 104, 238) 99 | Mediumspringgreen = color.RGBA{0x00, 0xfa, 0x9a, 0xff} // rgb(0, 250, 154) 100 | Mediumturquoise = color.RGBA{0x48, 0xd1, 0xcc, 0xff} // rgb(72, 209, 204) 101 | Mediumvioletred = color.RGBA{0xc7, 0x15, 0x85, 0xff} // rgb(199, 21, 133) 102 | Midnightblue = color.RGBA{0x19, 0x19, 0x70, 0xff} // rgb(25, 25, 112) 103 | Mintcream = color.RGBA{0xf5, 0xff, 0xfa, 0xff} // rgb(245, 255, 250) 104 | Mistyrose = color.RGBA{0xff, 0xe4, 0xe1, 0xff} // rgb(255, 228, 225) 105 | Moccasin = color.RGBA{0xff, 0xe4, 0xb5, 0xff} // rgb(255, 228, 181) 106 | Navajowhite = color.RGBA{0xff, 0xde, 0xad, 0xff} // rgb(255, 222, 173) 107 | Navy = color.RGBA{0x00, 0x00, 0x80, 0xff} // rgb(0, 0, 128) 108 | Oldlace = color.RGBA{0xfd, 0xf5, 0xe6, 0xff} // rgb(253, 245, 230) 109 | Olive = color.RGBA{0x80, 0x80, 0x00, 0xff} // rgb(128, 128, 0) 110 | Olivedrab = color.RGBA{0x6b, 0x8e, 0x23, 0xff} // rgb(107, 142, 35) 111 | Orange = color.RGBA{0xff, 0xa5, 0x00, 0xff} // rgb(255, 165, 0) 112 | Orangered = color.RGBA{0xff, 0x45, 0x00, 0xff} // rgb(255, 69, 0) 113 | Orchid = color.RGBA{0xda, 0x70, 0xd6, 0xff} // rgb(218, 112, 214) 114 | Palegoldenrod = color.RGBA{0xee, 0xe8, 0xaa, 0xff} // rgb(238, 232, 170) 115 | Palegreen = color.RGBA{0x98, 0xfb, 0x98, 0xff} // rgb(152, 251, 152) 116 | Paleturquoise = color.RGBA{0xaf, 0xee, 0xee, 0xff} // rgb(175, 238, 238) 117 | Palevioletred = color.RGBA{0xdb, 0x70, 0x93, 0xff} // rgb(219, 112, 147) 118 | Papayawhip = color.RGBA{0xff, 0xef, 0xd5, 0xff} // rgb(255, 239, 213) 119 | Peachpuff = color.RGBA{0xff, 0xda, 0xb9, 0xff} // rgb(255, 218, 185) 120 | Peru = color.RGBA{0xcd, 0x85, 0x3f, 0xff} // rgb(205, 133, 63) 121 | Pink = color.RGBA{0xff, 0xc0, 0xcb, 0xff} // rgb(255, 192, 203) 122 | Plum = color.RGBA{0xdd, 0xa0, 0xdd, 0xff} // rgb(221, 160, 221) 123 | Powderblue = color.RGBA{0xb0, 0xe0, 0xe6, 0xff} // rgb(176, 224, 230) 124 | Purple = color.RGBA{0x80, 0x00, 0x80, 0xff} // rgb(128, 0, 128) 125 | Red = color.RGBA{0xff, 0x00, 0x00, 0xff} // rgb(255, 0, 0) 126 | Rosybrown = color.RGBA{0xbc, 0x8f, 0x8f, 0xff} // rgb(188, 143, 143) 127 | Royalblue = color.RGBA{0x41, 0x69, 0xe1, 0xff} // rgb(65, 105, 225) 128 | Saddlebrown = color.RGBA{0x8b, 0x45, 0x13, 0xff} // rgb(139, 69, 19) 129 | Salmon = color.RGBA{0xfa, 0x80, 0x72, 0xff} // rgb(250, 128, 114) 130 | Sandybrown = color.RGBA{0xf4, 0xa4, 0x60, 0xff} // rgb(244, 164, 96) 131 | Seagreen = color.RGBA{0x2e, 0x8b, 0x57, 0xff} // rgb(46, 139, 87) 132 | Seashell = color.RGBA{0xff, 0xf5, 0xee, 0xff} // rgb(255, 245, 238) 133 | Sienna = color.RGBA{0xa0, 0x52, 0x2d, 0xff} // rgb(160, 82, 45) 134 | Silver = color.RGBA{0xc0, 0xc0, 0xc0, 0xff} // rgb(192, 192, 192) 135 | Skyblue = color.RGBA{0x87, 0xce, 0xeb, 0xff} // rgb(135, 206, 235) 136 | Slateblue = color.RGBA{0x6a, 0x5a, 0xcd, 0xff} // rgb(106, 90, 205) 137 | Slategray = color.RGBA{0x70, 0x80, 0x90, 0xff} // rgb(112, 128, 144) 138 | Slategrey = color.RGBA{0x70, 0x80, 0x90, 0xff} // rgb(112, 128, 144) 139 | Snow = color.RGBA{0xff, 0xfa, 0xfa, 0xff} // rgb(255, 250, 250) 140 | Springgreen = color.RGBA{0x00, 0xff, 0x7f, 0xff} // rgb(0, 255, 127) 141 | Steelblue = color.RGBA{0x46, 0x82, 0xb4, 0xff} // rgb(70, 130, 180) 142 | Tan = color.RGBA{0xd2, 0xb4, 0x8c, 0xff} // rgb(210, 180, 140) 143 | Teal = color.RGBA{0x00, 0x80, 0x80, 0xff} // rgb(0, 128, 128) 144 | Thistle = color.RGBA{0xd8, 0xbf, 0xd8, 0xff} // rgb(216, 191, 216) 145 | Tomato = color.RGBA{0xff, 0x63, 0x47, 0xff} // rgb(255, 99, 71) 146 | Turquoise = color.RGBA{0x40, 0xe0, 0xd0, 0xff} // rgb(64, 224, 208) 147 | Violet = color.RGBA{0xee, 0x82, 0xee, 0xff} // rgb(238, 130, 238) 148 | Wheat = color.RGBA{0xf5, 0xde, 0xb3, 0xff} // rgb(245, 222, 179) 149 | White = color.RGBA{0xff, 0xff, 0xff, 0xff} // rgb(255, 255, 255) 150 | Whitesmoke = color.RGBA{0xf5, 0xf5, 0xf5, 0xff} // rgb(245, 245, 245) 151 | Yellow = color.RGBA{0xff, 0xff, 0x00, 0xff} // rgb(255, 255, 0) 152 | Yellowgreen = color.RGBA{0x9a, 0xcd, 0x32, 0xff} // rgb(154, 205, 50) 153 | ) 154 | -------------------------------------------------------------------------------- /tests/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/racerxdl/go-switch-examples/minimal 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/racerxdl/gonx v0.0.0-20210103083128-c5afc43bcbd2 7 | github.com/tinygo-org/tinygo v0.13.1 8 | golang.org/x/image v0.0.0-20200924062109-4578eab98f00 9 | ) 10 | -------------------------------------------------------------------------------- /tests/go.sum: -------------------------------------------------------------------------------- 1 | github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= 2 | github.com/creack/goselect v0.1.1/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 5 | github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= 6 | github.com/marcinbor85/gohex v0.0.0-20180128172054-7a43cd876e46/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M= 7 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 8 | github.com/racerxdl/gonx v0.0.0-20200516060607-124c438d76cd h1:9iobHBYrJ6WRKu6aW3bwLXob8LDK369fQll7zxASraw= 9 | github.com/racerxdl/gonx v0.0.0-20200531182709-db1d886dc61f h1:DX/Cb8amMcrmyFQMX0hIqiSd4ei8FHVy2Pwj6dD0OUY= 10 | github.com/racerxdl/gonx v0.0.0-20200531182709-db1d886dc61f/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 11 | github.com/racerxdl/gonx v0.0.0-20210102224128-6d0998d45c2e h1:/ZLUQalGCUpXhskYi7QceGFZyZfgbuKQt/WJM9DfVvE= 12 | github.com/racerxdl/gonx v0.0.0-20210102224128-6d0998d45c2e/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 13 | github.com/racerxdl/gonx v0.0.0-20210103083128-c5afc43bcbd2 h1:1zRLfGfK2C63wk+MrCz9Ee50CV4KLfDihJbzSoiQBdM= 14 | github.com/racerxdl/gonx v0.0.0-20210103083128-c5afc43bcbd2/go.mod h1:4MRDx7D70fyiRjr/hwN0+kq3baqmmzIS7KKMExA17Mo= 15 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 16 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 17 | github.com/tinygo-org/tinygo v0.13.1 h1:fp7l5wUK7BFTHCfZz4F9GK0d14VG22Bk9eKmsnf4X4U= 18 | github.com/tinygo-org/tinygo v0.13.1/go.mod h1:mpIvjJOEg9zFxUXMQaYyNs3eqxx1WblEzAFuCLtqDUg= 19 | github.com/tinygo-org/tinygo v0.15.0 h1:os9BHXyEa6QfhoRhunj/65Dqu+vDdzsYsjSvcBjGB5w= 20 | go.bug.st/serial v1.0.0/go.mod h1:rpXPISGjuNjPTRTcMlxi9lN6LoIPxd1ixVjBd8aSk/Q= 21 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 22 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 23 | golang.org/x/image v0.0.0-20200924062109-4578eab98f00 h1:9VSII+GM7HSMYSWsMcnMnDHKcDv2agce+07ISbE3llQ= 24 | golang.org/x/image v0.0.0-20200924062109-4578eab98f00/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 25 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 26 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 27 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 28 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 29 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 30 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 31 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 32 | golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 33 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 34 | golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 35 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 36 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 37 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 38 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 39 | tinygo.org/x/go-llvm v0.0.0-20200401165421-8d120882fc7a/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= 40 | -------------------------------------------------------------------------------- /tests/minimal.go: -------------------------------------------------------------------------------- 1 | // This program is a minimal Nintendo Switch program that just outputs messages to 2 | // emulator console 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "github.com/racerxdl/gonx/font" 8 | "github.com/racerxdl/gonx/nintendoswitch" 9 | "github.com/racerxdl/gonx/services/display" 10 | "github.com/racerxdl/gonx/svc" 11 | "unsafe" 12 | ) 13 | 14 | func main() { 15 | err := nintendoswitch.Configure() 16 | if err != nil { 17 | println("error initializing nintendoswitch: ", err) 18 | svc.Break(0x4442, 0, 0) 19 | return 20 | } 21 | defer nintendoswitch.Cleanup() 22 | 23 | fmt.Println("Fetching surface") 24 | surface, err := display.OpenLayer() 25 | if err != nil { 26 | fmt.Printf("Error getting surface: %s\n", err) 27 | svc.Break(0x4443, 0, 0) 28 | return 29 | } 30 | //defer surface.CloseLayer() 31 | 32 | fmt.Println("Got surface!") 33 | 34 | fmt.Println("Fetching Frame") 35 | frame, err := surface.GetFrame() 36 | if err != nil { 37 | fmt.Printf("Error getting frame: %s\n", err) 38 | svc.Break(0x4444, 0, 0) 39 | *(*uint64)(unsafe.Pointer(uintptr(1))) = uint64(0xDEAD155500000002) 40 | return 41 | } 42 | 43 | frame.Clear(Red) 44 | 45 | fmt.Println("Drawing Red Square") 46 | for y := int16(0); y < 64; y++ { 47 | for x := int16(0); x < 64; x++ { 48 | frame.SetPixel(128+x, 128+y, Red) 49 | } 50 | } 51 | 52 | fmt.Println("Displaying image") 53 | err = frame.Display() 54 | if err != nil { 55 | fmt.Printf("Error displaying data: %s\n", err) 56 | svc.Break(0x4445, 0, 0) 57 | return 58 | } 59 | 60 | drawfont := font.GetFontByName("nixedsys_normal") 61 | 62 | fmt.Println("DRAWN!") 63 | err = frame.WaitVSync() 64 | if err != nil { 65 | fmt.Println("Error waiting vsync", err) 66 | svc.Break(0x4446, 0, 0) 67 | return 68 | } 69 | i := int16(0) 70 | totalFrameCount := 0 71 | for { 72 | frame.Clear(Black) 73 | for y := int16(0); y < 64; y++ { 74 | for x := int16(0); x < 64; x++ { 75 | frame.SetPixel(i+x, i+y, Red) 76 | } 77 | } 78 | i++ 79 | if i > 256 { 80 | i = 0 81 | } 82 | 83 | frame.DrawStringAt(800, 100, "Hello world!!ãõç1;/|/\nHUEBR2\n1234", White, drawfont) 84 | 85 | err = frame.Display() 86 | if err != nil { 87 | fmt.Printf("Error displaying data: %s\n", err) 88 | *(*uint64)(unsafe.Pointer(uintptr(1))) = uint64(0xDEAD155500000004) 89 | return 90 | } 91 | err = frame.WaitVSync() 92 | if err != nil { 93 | fmt.Println("Error waiting vsync", err) 94 | *(*uint64)(unsafe.Pointer(uintptr(1))) = uint64(0xDEAD155500000005) 95 | return 96 | } 97 | totalFrameCount++ 98 | if totalFrameCount > 100 { 99 | break 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /tests/nacp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LucasTests", 3 | "author": "Lucas Teske", 4 | "version": "1.0.0", 5 | "title_id": "0100000000020000" 6 | } 7 | --------------------------------------------------------------------------------