├── .gitignore
├── CMakeLists.txt
├── Makefile
├── README.md
├── build.sh
├── components
├── odroid-go
│ ├── CMakeLists.txt
│ ├── component.mk
│ ├── fonts
│ │ ├── DejaVu12.h
│ │ ├── DejaVuSans18.h
│ │ └── DejaVuSans24.h
│ ├── input.c
│ ├── input.h
│ ├── odroid.c
│ ├── odroid.h
│ ├── sdcard.c
│ ├── sdcard.h
│ ├── sound.c
│ ├── sound.h
│ ├── spi_lcd.c
│ └── spi_lcd.h
└── snes9x
│ ├── .gitignore
│ ├── .gitmodules
│ ├── 65c816.h
│ ├── CMakeLists.txt
│ ├── LICENSE
│ ├── Makefile
│ ├── README.md
│ ├── appveyor.yml
│ ├── apu.cpp
│ ├── apu.h
│ ├── apu_smp.cpp
│ ├── apu_smp.hpp
│ ├── apu_snes.hpp
│ ├── clip.cpp
│ ├── component.mk
│ ├── conffile.cpp
│ ├── conffile.h
│ ├── controls.cpp
│ ├── controls.h
│ ├── core
│ ├── oppseudo_misc.cpp
│ ├── oppseudo_mov.cpp
│ ├── oppseudo_pc.cpp
│ ├── oppseudo_read.cpp
│ └── oppseudo_rmw.cpp
│ ├── cpu.cpp
│ ├── cpuaddr.h
│ ├── cpuexec.cpp
│ ├── cpuexec.h
│ ├── cpumacro.h
│ ├── cpuops.cpp
│ ├── cpuops.h
│ ├── debug.cpp
│ ├── debug.h
│ ├── display.h
│ ├── dma.cpp
│ ├── dma.h
│ ├── docs
│ ├── changes.txt
│ ├── control-inputs.txt
│ ├── controls.txt
│ ├── porting.html
│ ├── portsofsnes9x.txt
│ └── snapshots.txt
│ ├── dsp.cpp
│ ├── dsp.h
│ ├── dsp1.cpp
│ ├── font.h
│ ├── getset.h
│ ├── gfx.cpp
│ ├── gfx.h
│ ├── globals.cpp
│ ├── language.h
│ ├── logger.cpp
│ ├── logger.h
│ ├── memmap.cpp
│ ├── memmap.h
│ ├── messages.h
│ ├── missing.h
│ ├── pixform.h
│ ├── port.h
│ ├── ppu.cpp
│ ├── ppu.h
│ ├── snes9x.cpp
│ ├── snes9x.h
│ ├── stream.cpp
│ ├── stream.h
│ ├── tile.cpp
│ └── tile.h
├── debug.sh
├── main
├── CMakeLists.txt
├── app_main.cpp
├── component.mk
├── rom_selector.cpp
└── snes9x.cpp
├── sdkconfig.defaults
└── tile.raw
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/*
2 | build/*
3 | *.fw
4 | sdkconfig
5 | sdkconfig.old
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5)
2 | include($ENV{IDF_PATH}/tools/cmake/project.cmake)
3 | set(EXTRA_COMPONENT_DIRS "components")
4 | project(snes9x-esp32)
5 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a
3 | # project subdirectory.
4 | #
5 |
6 | PROJECT_NAME := snes9x-esp32
7 |
8 | include $(IDF_PATH)/make/project.mk
9 |
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This port is now abandoned.
2 | A new port is being worked on as part of [retro-go](https://github.com/ducalex/retro-go/) and is already in better shape than this one.
3 |
4 | # Snes9x for Odroid GO
5 | This is a port of the snes9x emulator to the Odroid Go.
6 |
7 | You will notice that I butchered the snes9x codebase and that was for multiple reasons such as: fixing compile errors, smaller binary, performance, simplicity.
8 |
9 | Once (If) I get the emulator to run at an acceptable speed I will bring the code back to as close to upstream as possible.
10 |
11 | ## Things to note:
12 | - It is very slow (currently ~4x too slow)
13 | - No sound
14 | - No saves
15 | - ROMs are limited to 2MB
16 | - No enhancement chip support (DSP will be supported eventually, SA/FX probably not)
17 |
18 | ## Device support
19 | Although only the Odroid GO is officially supported, it is confirmed to also run on a standard ESP32-**WROVER** with an ILI9341 LCD.
20 |
21 | Careful: Most ESP32 dev boards use the ESP32-**WROOM** modules and it won't work for this project (there is not enough memory).
22 |
23 |
24 | # Photo
25 |
26 | 
27 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #make -j 4
3 | release=`date +%Y%m%d`;
4 | ../odroid-go-multi-firmware/tools/mkfw/mkfw "Snes9x ($release)" tile.raw 0 16 2097152 app build/snes9x-esp32.bin
5 | mv firmware.fw snes9x.fw
6 |
--------------------------------------------------------------------------------
/components/odroid-go/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(COMPONENT_SRCDIRS ".")
2 | set(COMPONENT_ADD_INCLUDEDIRS ".")
3 | set(COMPONENT_REQUIRES "nvs_flash spi_flash fatfs freertos")
4 |
5 | register_component()
--------------------------------------------------------------------------------
/components/odroid-go/component.mk:
--------------------------------------------------------------------------------
1 | #
2 | # Component Makefile
3 | #
4 | # This Makefile should, at the very least, just include $(SDK_PATH)/make/component.mk. By default,
5 | # this will take the sources in the src/ directory, compile them and link them into
6 | # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
7 | # please read the SDK documents if you need to do this.
8 | #
9 |
10 | CFLAGS += -O2
11 |
12 | #include $(IDF_PATH)/make/component_common.mk
13 |
14 |
--------------------------------------------------------------------------------
/components/odroid-go/fonts/DejaVu12.h:
--------------------------------------------------------------------------------
1 | // Default font
2 |
3 | // ========================================================================
4 | // This comes with no warranty, implied or otherwise
5 |
6 | // This data structure was designed to support Proportional fonts
7 | // fonts. Individual characters do not have to be multiples of 8 bits wide.
8 | // Any width is fine and does not need to be fixed.
9 |
10 | // The data bits are packed to minimize data requirements, but the tradeoff
11 | // is that a header is required per character.
12 |
13 | // Header Format:
14 | // ------------------------------------------------
15 | // Character Width (Used as a marker to indicate use this format. i.e.: = 0x00)
16 | // Character Height
17 | // First Character (Reserved. 0x00)
18 | // Number Of Characters (Reserved. 0x00)
19 |
20 | // Individual Character Format:
21 | // ----------------------------
22 | // Character Code
23 | // Adjusted Y Offset (start Y of visible pixels)
24 | // Width (width of the visible pixels)
25 | // Height (height of the visible pixels)
26 | // xOffset (start X of visible pixels)
27 | // xDelta (the distance to move the cursor. Effective width of the character.)
28 | // Data[n]
29 |
30 | // NOTE: You can remove any of these characters if they are not needed in
31 | // your application. The first character number in each Glyph indicates
32 | // the ASCII character code. Therefore, these do not have to be sequential.
33 | // Just remove all the content for a particular character to save space.
34 | // ========================================================================
35 |
36 | // dejavu
37 | // Point Size : 12
38 | // Memory usage : 1158 bytes
39 | // # characters : 95
40 |
41 | const unsigned char tft_Dejavu12[] =
42 | {
43 | 0x00, 0x0B, 0x86, 0x04,
44 |
45 | // ' '
46 | 0x20,0x0A,0x00,0x00,0x00,0x04,
47 |
48 | // '!'
49 | 0x21,0x01,0x01,0x09,0x02,0x05,
50 | 0xFD,0x80,
51 | // '"'
52 | 0x22,0x01,0x03,0x03,0x01,0x05,
53 | 0xB6,0x80,
54 | // '#'
55 | 0x23,0x02,0x08,0x08,0x01,0x0A,
56 | 0x12,0x14,0x7F,0x24,0x24,0xFE,0x28,0x48,
57 | // '$'
58 | 0x24,0x01,0x06,0x0B,0x02,0x08,
59 | 0x21,0xCA,0xA8,0xE0,0xE2,0xAA,0x70,0x82,0x00,
60 | // '%'
61 | 0x25,0x01,0x0A,0x09,0x00,0x0B,
62 | 0x61,0x24,0x89,0x22,0x50,0x6D,0x82,0x91,0x24,0x49,0x21,0x80,
63 | // '&'
64 | 0x26,0x01,0x09,0x09,0x01,0x0A,
65 | 0x30,0x24,0x10,0x0C,0x05,0x14,0x4A,0x19,0x8C,0x7B,0x00,
66 | // '''
67 | 0x27,0x01,0x01,0x03,0x01,0x03,
68 | 0xE0,
69 | // '('
70 | 0x28,0x00,0x03,0x0B,0x01,0x05,
71 | 0x69,0x49,0x24,0x48,0x80,
72 | // ')'
73 | 0x29,0x00,0x03,0x0B,0x01,0x05,
74 | 0x89,0x12,0x49,0x4A,0x00,
75 | // '*'
76 | 0x2A,0x01,0x05,0x06,0x01,0x06,
77 | 0x25,0x5C,0xEA,0x90,
78 | // '+'
79 | 0x2B,0x03,0x07,0x07,0x01,0x0A,
80 | 0x10,0x20,0x47,0xF1,0x02,0x04,0x00,
81 | // ','
82 | 0x2C,0x08,0x01,0x03,0x01,0x04,
83 | 0xE0,
84 | // '-'
85 | 0x2D,0x06,0x03,0x01,0x01,0x04,
86 | 0xE0,
87 | // '.'
88 | 0x2E,0x08,0x01,0x02,0x01,0x04,
89 | 0xC0,
90 | // '/'
91 | 0x2F,0x01,0x04,0x0A,0x00,0x04,
92 | 0x11,0x22,0x24,0x44,0x88,
93 | // '0'
94 | 0x30,0x01,0x06,0x09,0x01,0x08,
95 | 0x79,0x28,0x61,0x86,0x18,0x52,0x78,
96 | // '1'
97 | 0x31,0x01,0x05,0x09,0x01,0x08,
98 | 0xE1,0x08,0x42,0x10,0x84,0xF8,
99 | // '2'
100 | 0x32,0x01,0x07,0x09,0x01,0x08,
101 | 0x79,0x18,0x10,0x20,0x82,0x08,0x20,0xFC,
102 | // '3'
103 | 0x33,0x01,0x06,0x09,0x01,0x08,
104 | 0x7A,0x10,0x41,0x38,0x30,0x63,0x78,
105 | // '4'
106 | 0x34,0x01,0x06,0x09,0x01,0x08,
107 | 0x18,0x62,0x92,0x4A,0x2F,0xC2,0x08,
108 | // '5'
109 | 0x35,0x01,0x06,0x09,0x01,0x08,
110 | 0xFA,0x08,0x3C,0x0C,0x10,0x63,0x78,
111 | // '6'
112 | 0x36,0x01,0x06,0x09,0x01,0x08,
113 | 0x39,0x18,0x3E,0xCE,0x18,0x53,0x78,
114 | // '7'
115 | 0x37,0x01,0x06,0x09,0x01,0x08,
116 | 0xFC,0x10,0x82,0x10,0x42,0x08,0x40,
117 | // '8'
118 | 0x38,0x01,0x06,0x09,0x01,0x08,
119 | 0x7B,0x38,0x73,0x7B,0x38,0x73,0x78,
120 | // '9'
121 | 0x39,0x01,0x06,0x09,0x01,0x08,
122 | 0x7B,0x28,0x61,0xCD,0xD0,0x62,0x70,
123 | // ':'
124 | 0x3A,0x04,0x01,0x06,0x01,0x04,
125 | 0xCC,
126 | // ';'
127 | 0x3B,0x04,0x01,0x07,0x01,0x04,
128 | 0xCE,
129 | // '<'
130 | 0x3C,0x03,0x08,0x06,0x01,0x0A,
131 | 0x03,0x1E,0xE0,0xE0,0x1E,0x03,
132 | // '='
133 | 0x3D,0x05,0x08,0x03,0x01,0x0A,
134 | 0xFF,0x00,0xFF,
135 | // '>'
136 | 0x3E,0x03,0x08,0x06,0x01,0x0A,
137 | 0xC0,0x78,0x07,0x07,0x78,0xC0,
138 | // '?'
139 | 0x3F,0x01,0x05,0x09,0x00,0x06,
140 | 0x74,0x42,0x22,0x10,0x04,0x20,
141 | // '@'
142 | 0x40,0x01,0x0B,0x0B,0x01,0x0D,
143 | 0x1F,0x06,0x19,0x01,0x46,0x99,0x13,0x22,0x64,0x54,0x6C,0x40,0x04,0x10,0x7C,0x00,
144 | // 'A'
145 | 0x41,0x01,0x08,0x09,0x00,0x08,
146 | 0x18,0x18,0x24,0x24,0x24,0x42,0x7E,0x42,0x81,
147 | // 'B'
148 | 0x42,0x01,0x06,0x09,0x01,0x08,
149 | 0xFA,0x18,0x61,0xFA,0x18,0x61,0xF8,
150 | // 'C'
151 | 0x43,0x01,0x06,0x09,0x01,0x08,
152 | 0x39,0x18,0x20,0x82,0x08,0x11,0x38,
153 | // 'D'
154 | 0x44,0x01,0x07,0x09,0x01,0x09,
155 | 0xF9,0x0A,0x0C,0x18,0x30,0x60,0xC2,0xF8,
156 | // 'E'
157 | 0x45,0x01,0x06,0x09,0x01,0x08,
158 | 0xFE,0x08,0x20,0xFE,0x08,0x20,0xFC,
159 | // 'F'
160 | 0x46,0x01,0x05,0x09,0x01,0x07,
161 | 0xFC,0x21,0x0F,0xC2,0x10,0x80,
162 | // 'G'
163 | 0x47,0x01,0x07,0x09,0x01,0x09,
164 | 0x3C,0x86,0x04,0x08,0xF0,0x60,0xA1,0x3C,
165 | // 'H'
166 | 0x48,0x01,0x07,0x09,0x01,0x09,
167 | 0x83,0x06,0x0C,0x1F,0xF0,0x60,0xC1,0x82,
168 | // 'I'
169 | 0x49,0x01,0x01,0x09,0x01,0x03,
170 | 0xFF,0x80,
171 | // 'J'
172 | 0x4A,0x01,0x03,0x0B,0xFF,0x03,
173 | 0x24,0x92,0x49,0x27,0x00,
174 | // 'K'
175 | 0x4B,0x01,0x07,0x09,0x01,0x07,
176 | 0x85,0x12,0x45,0x0C,0x14,0x24,0x44,0x84,
177 | // 'L'
178 | 0x4C,0x01,0x05,0x09,0x01,0x06,
179 | 0x84,0x21,0x08,0x42,0x10,0xF8,
180 | // 'M'
181 | 0x4D,0x01,0x08,0x09,0x01,0x0A,
182 | 0x81,0xC3,0xC3,0xA5,0xA5,0x99,0x99,0x81,0x81,
183 | // 'N'
184 | 0x4E,0x01,0x07,0x09,0x01,0x09,
185 | 0xC3,0x86,0x8D,0x19,0x31,0x62,0xC3,0x86,
186 | // 'O'
187 | 0x4F,0x01,0x07,0x09,0x01,0x09,
188 | 0x38,0x8A,0x0C,0x18,0x30,0x60,0xA2,0x38,
189 | // 'P'
190 | 0x50,0x01,0x06,0x09,0x01,0x08,
191 | 0xFA,0x38,0x63,0xFA,0x08,0x20,0x80,
192 | // 'Q'
193 | 0x51,0x01,0x07,0x0B,0x01,0x09,
194 | 0x38,0x8A,0x0C,0x18,0x30,0x60,0xA2,0x38,0x10,0x10,
195 | // 'R'
196 | 0x52,0x01,0x07,0x09,0x01,0x08,
197 | 0xF9,0x1A,0x14,0x6F,0x91,0x21,0x42,0x82,
198 | // 'S'
199 | 0x53,0x01,0x06,0x09,0x01,0x08,
200 | 0x7B,0x18,0x30,0x78,0x30,0x63,0x78,
201 | // 'T'
202 | 0x54,0x01,0x07,0x09,0x00,0x07,
203 | 0xFE,0x20,0x40,0x81,0x02,0x04,0x08,0x10,
204 | // 'U'
205 | 0x55,0x01,0x07,0x09,0x01,0x09,
206 | 0x83,0x06,0x0C,0x18,0x30,0x60,0xA2,0x38,
207 | // 'V'
208 | 0x56,0x01,0x0A,0x09,0xFF,0x08,
209 | 0x40,0x90,0x22,0x10,0x84,0x21,0x04,0x81,0x20,0x30,0x0C,0x00,
210 | // 'W'
211 | 0x57,0x01,0x0B,0x09,0x00,0x0B,
212 | 0x84,0x28,0x89,0x11,0x27,0x22,0xA8,0x55,0x0E,0xE0,0x88,0x11,0x00,
213 | // 'X'
214 | 0x58,0x01,0x07,0x09,0x00,0x07,
215 | 0xC6,0x88,0xA1,0xC1,0x07,0x0A,0x22,0x82,
216 | // 'Y'
217 | 0x59,0x01,0x07,0x09,0x00,0x07,
218 | 0x82,0x89,0x11,0x43,0x82,0x04,0x08,0x10,
219 | // 'Z'
220 | 0x5A,0x01,0x07,0x09,0x01,0x09,
221 | 0xFE,0x04,0x10,0x41,0x04,0x10,0x40,0xFE,
222 | // '['
223 | 0x5B,0x01,0x02,0x0B,0x02,0x05,
224 | 0xEA,0xAA,0xAC,
225 | // '\'
226 | 0x5C,0x01,0x04,0x0A,0x00,0x04,
227 | 0x88,0x44,0x42,0x22,0x11,
228 | // ']'
229 | 0x5D,0x01,0x02,0x0B,0x01,0x05,
230 | 0xD5,0x55,0x5C,
231 | // '^'
232 | 0x5E,0x01,0x08,0x03,0x01,0x0A,
233 | 0x18,0x24,0x42,
234 | // '_'
235 | 0x5F,0x0C,0x06,0x01,0x00,0x06,
236 | 0xFC,
237 | // '`'
238 | 0x60,0x00,0x03,0x02,0x01,0x06,
239 | 0x44,
240 | // 'a'
241 | 0x61,0x03,0x06,0x07,0x01,0x08,
242 | 0x7A,0x30,0x5F,0x86,0x37,0x40,
243 | // 'b'
244 | 0x62,0x00,0x06,0x0A,0x01,0x08,
245 | 0x82,0x08,0x2E,0xCA,0x18,0x61,0xCE,0xE0,
246 | // 'c'
247 | 0x63,0x03,0x05,0x07,0x01,0x07,
248 | 0x72,0x61,0x08,0x25,0xC0,
249 | // 'd'
250 | 0x64,0x00,0x06,0x0A,0x01,0x08,
251 | 0x04,0x10,0x5D,0xCE,0x18,0x61,0xCD,0xD0,
252 | // 'e'
253 | 0x65,0x03,0x06,0x07,0x01,0x08,
254 | 0x39,0x38,0x7F,0x81,0x13,0x80,
255 | // 'f'
256 | 0x66,0x00,0x04,0x0A,0x00,0x04,
257 | 0x34,0x4F,0x44,0x44,0x44,
258 | // 'g'
259 | 0x67,0x03,0x06,0x0A,0x01,0x08,
260 | 0x77,0x38,0x61,0x87,0x37,0x41,0x4C,0xE0,
261 | // 'h'
262 | 0x68,0x00,0x06,0x0A,0x01,0x08,
263 | 0x82,0x08,0x2E,0xC6,0x18,0x61,0x86,0x10,
264 | // 'i'
265 | 0x69,0x01,0x01,0x09,0x01,0x03,
266 | 0xBF,0x80,
267 | // 'j'
268 | 0x6A,0x01,0x02,0x0C,0x00,0x03,
269 | 0x45,0x55,0x56,
270 | // 'k'
271 | 0x6B,0x00,0x06,0x0A,0x01,0x07,
272 | 0x82,0x08,0x22,0x92,0x8E,0x28,0x92,0x20,
273 | // 'l'
274 | 0x6C,0x00,0x01,0x0A,0x01,0x03,
275 | 0xFF,0xC0,
276 | // 'm'
277 | 0x6D,0x03,0x09,0x07,0x01,0x0B,
278 | 0xB3,0x66,0x62,0x31,0x18,0x8C,0x46,0x22,
279 | // 'n'
280 | 0x6E,0x03,0x06,0x07,0x01,0x08,
281 | 0xBB,0x18,0x61,0x86,0x18,0x40,
282 | // 'o'
283 | 0x6F,0x03,0x06,0x07,0x01,0x08,
284 | 0x7B,0x38,0x61,0x87,0x37,0x80,
285 | // 'p'
286 | 0x70,0x03,0x06,0x0A,0x01,0x08,
287 | 0xBB,0x28,0x61,0x87,0x3B,0xA0,0x82,0x00,
288 | // 'q'
289 | 0x71,0x03,0x06,0x0A,0x01,0x08,
290 | 0x77,0x38,0x61,0x87,0x37,0x41,0x04,0x10,
291 | // 'r'
292 | 0x72,0x03,0x04,0x07,0x01,0x05,
293 | 0xBC,0x88,0x88,0x80,
294 | // 's'
295 | 0x73,0x03,0x06,0x07,0x01,0x07,
296 | 0x72,0x28,0x1C,0x0A,0x27,0x00,
297 | // 't'
298 | 0x74,0x01,0x04,0x09,0x00,0x05,
299 | 0x44,0xF4,0x44,0x44,0x30,
300 | // 'u'
301 | 0x75,0x03,0x06,0x07,0x01,0x08,
302 | 0x86,0x18,0x61,0x86,0x37,0x40,
303 | // 'v'
304 | 0x76,0x03,0x08,0x07,0xFF,0x06,
305 | 0x42,0x42,0x24,0x24,0x24,0x18,0x18,
306 | // 'w'
307 | 0x77,0x03,0x09,0x07,0x00,0x09,
308 | 0x88,0xC4,0x57,0x4A,0xA5,0x51,0x10,0x88,
309 | // 'x'
310 | 0x78,0x03,0x06,0x07,0x00,0x06,
311 | 0x85,0x24,0x8C,0x49,0x28,0x40,
312 | // 'y'
313 | 0x79,0x03,0x08,0x0A,0xFF,0x06,
314 | 0x42,0x42,0x24,0x24,0x14,0x18,0x08,0x08,0x10,0x60,
315 | // 'z'
316 | 0x7A,0x03,0x05,0x07,0x00,0x05,
317 | 0xF8,0x44,0x44,0x43,0xE0,
318 | // '{'
319 | 0x7B,0x01,0x05,0x0B,0x02,0x08,
320 | 0x19,0x08,0x42,0x60,0x84,0x21,0x06,
321 | // '|'
322 | 0x7C,0x01,0x01,0x0C,0x02,0x04,
323 | 0xFF,0xF0,
324 | // '}'
325 | 0x7D,0x01,0x05,0x0B,0x01,0x08,
326 | 0xC1,0x08,0x42,0x0C,0x84,0x21,0x30,
327 | // '~'
328 | 0x7E,0x04,0x08,0x03,0x01,0x0A,
329 | 0x00,0x71,0x8E,
330 |
331 | // Terminator
332 | 0xFF
333 | };
334 |
--------------------------------------------------------------------------------
/components/odroid-go/input.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "freertos/FreeRTOS.h"
23 | #include "freertos/semphr.h"
24 | #include "freertos/task.h"
25 | #include "driver/rtc_io.h"
26 | #include "driver/gpio.h"
27 | #include "driver/adc.h"
28 |
29 | #include "odroid.h"
30 |
31 | static odroid_input_state gamepad_state = {0};
32 | static bool input_gamepad_initialized = false;
33 | static void (*odroid_input_callback_fn)(odroid_input_state) = NULL;
34 |
35 |
36 | void odroid_input_read_raw(uint8_t *values)
37 | {
38 | memset(values, 0, ODROID_INPUT_MAX);
39 |
40 | int joyX = adc1_get_raw(ODROID_GAMEPAD_IO_X);
41 | int joyY = adc1_get_raw(ODROID_GAMEPAD_IO_Y);
42 |
43 | if (joyX > 2048 + 1024)
44 | values[ODROID_INPUT_LEFT] = 1;
45 | else if (joyX > 1024)
46 | values[ODROID_INPUT_RIGHT] = 1;
47 |
48 | if (joyY > 2048 + 1024)
49 | values[ODROID_INPUT_UP] = 1;
50 | else if (joyY > 1024)
51 | values[ODROID_INPUT_DOWN] = 1;
52 |
53 | values[ODROID_INPUT_SELECT] = !(gpio_get_level(ODROID_GAMEPAD_IO_SELECT));
54 | values[ODROID_INPUT_START] = !(gpio_get_level(ODROID_GAMEPAD_IO_START));
55 |
56 | values[ODROID_INPUT_A] = !(gpio_get_level(ODROID_GAMEPAD_IO_A));
57 | values[ODROID_INPUT_B] = !(gpio_get_level(ODROID_GAMEPAD_IO_B));
58 |
59 | values[ODROID_INPUT_MENU] = !(gpio_get_level(ODROID_GAMEPAD_IO_MENU));
60 | values[ODROID_INPUT_VOLUME] = !(gpio_get_level(ODROID_GAMEPAD_IO_VOLUME));
61 | }
62 |
63 |
64 | static void odroid_input_task(void *arg)
65 | {
66 | printf("odroid_input_task: Input task started.\n");
67 |
68 | int i, changes;
69 |
70 | while(1)
71 | {
72 | // Read hardware
73 | odroid_input_read_raw(&gamepad_state.realtime);
74 | changes = 0;
75 |
76 | // Debounce
77 | for(i = 0; i < ODROID_INPUT_MAX; ++i)
78 | {
79 | gamepad_state.debounce[i] <<= 1;
80 |
81 | gamepad_state.debounce[i] |= gamepad_state.realtime[i] ? 1 : 0;
82 | uint8_t val = gamepad_state.debounce[i] & 0x03; //0x0f;
83 | switch (val) {
84 | case 0x00:
85 | gamepad_state.values[i] = 0;
86 | break;
87 |
88 | case 0x03: //0x0f:
89 | gamepad_state.values[i] = 1;
90 | break;
91 |
92 | default:
93 | // ignore
94 | break;
95 | }
96 |
97 | if (gamepad_state.values[i] != gamepad_state.previous[i]) {
98 | changes++;
99 | }
100 | }
101 |
102 | if (changes > 0 && odroid_input_callback_fn != NULL) {
103 | (*odroid_input_callback_fn)(gamepad_state);
104 | // update previous only if there's a callback, otherwise get_state will do it;
105 | memcpy(gamepad_state.previous, gamepad_state.values, ODROID_INPUT_MAX);
106 | }
107 |
108 | // delay
109 | vTaskDelay(20 / portTICK_PERIOD_MS);
110 | }
111 | }
112 |
113 |
114 | void odroid_input_get_state(odroid_input_state *dst)
115 | {
116 | memcpy(dst, &gamepad_state, sizeof(gamepad_state));
117 | memcpy(gamepad_state.previous, gamepad_state.values, ODROID_INPUT_MAX);
118 | }
119 |
120 |
121 | void odroid_input_set_callback(void (*callback)(odroid_input_state))
122 | {
123 | odroid_input_callback_fn = callback;
124 | }
125 |
126 |
127 | void odroid_input_init(void)
128 | {
129 | if (input_gamepad_initialized) {
130 | return;
131 | }
132 |
133 | printf("odroid_input_init: Initializing input.\n");
134 |
135 | gpio_set_direction(ODROID_GAMEPAD_IO_SELECT, GPIO_MODE_INPUT);
136 | gpio_set_pull_mode(ODROID_GAMEPAD_IO_SELECT, GPIO_PULLUP_ONLY);
137 |
138 | gpio_set_direction(ODROID_GAMEPAD_IO_START, GPIO_MODE_INPUT);
139 |
140 | gpio_set_direction(ODROID_GAMEPAD_IO_A, GPIO_MODE_INPUT);
141 | gpio_set_pull_mode(ODROID_GAMEPAD_IO_A, GPIO_PULLUP_ONLY);
142 |
143 | gpio_set_direction(ODROID_GAMEPAD_IO_B, GPIO_MODE_INPUT);
144 | gpio_set_pull_mode(ODROID_GAMEPAD_IO_B, GPIO_PULLUP_ONLY);
145 |
146 | adc1_config_width(ADC_WIDTH_12Bit);
147 | adc1_config_channel_atten(ODROID_GAMEPAD_IO_X, ADC_ATTEN_11db);
148 | adc1_config_channel_atten(ODROID_GAMEPAD_IO_Y, ADC_ATTEN_11db);
149 |
150 | rtc_gpio_deinit(ODROID_GAMEPAD_IO_MENU);
151 | gpio_set_direction(ODROID_GAMEPAD_IO_MENU, GPIO_MODE_INPUT);
152 | gpio_set_pull_mode(ODROID_GAMEPAD_IO_MENU, GPIO_PULLUP_ONLY);
153 |
154 | gpio_set_direction(ODROID_GAMEPAD_IO_VOLUME, GPIO_MODE_INPUT);
155 |
156 | input_gamepad_initialized = true;
157 |
158 | // Start background polling
159 | xTaskCreatePinnedToCore(&odroid_input_task, "odroid_input_task", 1024 * 2, NULL, 6, NULL, ODROID_TASKS_USE_CORE);
160 | }
161 |
--------------------------------------------------------------------------------
/components/odroid-go/input.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef _ODROID_INPUT_H_
19 | #define _ODROID_INPUT_H_
20 |
21 | #include
22 |
23 | #define ODROID_GAMEPAD_IO_X ADC1_CHANNEL_6
24 | #define ODROID_GAMEPAD_IO_Y ADC1_CHANNEL_7
25 | #define ODROID_GAMEPAD_IO_SELECT GPIO_NUM_27
26 | #define ODROID_GAMEPAD_IO_START GPIO_NUM_39
27 | #define ODROID_GAMEPAD_IO_A GPIO_NUM_32
28 | #define ODROID_GAMEPAD_IO_B GPIO_NUM_33
29 | #define ODROID_GAMEPAD_IO_MENU GPIO_NUM_13
30 | #define ODROID_GAMEPAD_IO_VOLUME GPIO_NUM_0
31 |
32 | enum
33 | {
34 | ODROID_INPUT_UP = 0,
35 | ODROID_INPUT_RIGHT,
36 | ODROID_INPUT_DOWN,
37 | ODROID_INPUT_LEFT,
38 | ODROID_INPUT_SELECT,
39 | ODROID_INPUT_START,
40 | ODROID_INPUT_A,
41 | ODROID_INPUT_B,
42 | ODROID_INPUT_MENU,
43 | ODROID_INPUT_VOLUME,
44 |
45 | ODROID_INPUT_MAX
46 | };
47 |
48 | typedef struct
49 | {
50 | uint8_t values[ODROID_INPUT_MAX];
51 | uint8_t previous[ODROID_INPUT_MAX];
52 | uint8_t debounce[ODROID_INPUT_MAX];
53 | uint8_t realtime[ODROID_INPUT_MAX];
54 | } odroid_input_state;
55 |
56 | void odroid_input_get_state(odroid_input_state *);
57 | void odroid_input_set_callback(void (*callback)(odroid_input_state));
58 | void odroid_input_read_raw(uint8_t *);
59 | void odroid_input_init(void);
60 |
61 | #endif
--------------------------------------------------------------------------------
/components/odroid-go/odroid.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "freertos/FreeRTOS.h"
19 | #include "freertos/task.h"
20 | #include "freertos/semphr.h"
21 | #include "esp_heap_caps.h"
22 | #include "driver/gpio.h"
23 | #include "odroid.h"
24 |
25 | static SemaphoreHandle_t spiLock = NULL;
26 |
27 | size_t free_bytes_total()
28 | {
29 | multi_heap_info_t info;
30 | heap_caps_get_info(&info, MALLOC_CAP_DEFAULT);
31 | return info.total_free_bytes;
32 | }
33 |
34 | size_t free_bytes_internal()
35 | {
36 | multi_heap_info_t info;
37 | heap_caps_get_info(&info, MALLOC_CAP_INTERNAL);
38 | return info.total_free_bytes;
39 | }
40 |
41 | size_t free_bytes_spiram()
42 | {
43 | multi_heap_info_t info;
44 | heap_caps_get_info(&info, MALLOC_CAP_SPIRAM);
45 | return info.total_free_bytes;
46 | }
47 |
48 | void odroid_system_init()
49 | {
50 | // SPI
51 | spiLock = xSemaphoreCreateMutex();
52 |
53 | // LED
54 | gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
55 | gpio_set_level(GPIO_NUM_2, 0);
56 |
57 | // SD Card (needs to be before LCD)
58 | odroid_sdcard_init();
59 |
60 | // LCD
61 | spi_lcd_init();
62 |
63 | // NVS Flash
64 | // nvs_flash_init();
65 |
66 | // Input
67 | odroid_input_init();
68 |
69 | // Sound
70 | //odroid_sound_init();
71 | }
72 |
73 | void odroid_system_led_set(int value)
74 | {
75 | gpio_set_level(GPIO_NUM_2, value);
76 | }
77 |
78 | void odroid_system_sleep()
79 | {
80 |
81 | }
82 |
83 | int odroid_system_battery_level()
84 | {
85 | return 0;
86 | }
87 |
88 | void odroid_fatal_error(char *error)
89 | {
90 | printf("Error: %s\n", error);
91 | spi_lcd_init(); // This is really only called if the error occurs in the SD card init
92 | spi_lcd_useFrameBuffer(false); // Send the error directly to the LCD
93 | spi_lcd_usePalette(false);
94 | spi_lcd_setFontColor(LCD_RGB(255, 0, 0)); // Red
95 | spi_lcd_clear();
96 | spi_lcd_print(0, 0, "A fatal error occurred :(");
97 | spi_lcd_print(0, 50, error);
98 | odroid_sound_deinit();
99 | exit(-1);
100 | }
101 |
102 | void inline odroid_spi_bus_acquire()
103 | {
104 | xSemaphoreTake(spiLock, portMAX_DELAY);
105 | }
106 |
107 | void inline odroid_spi_bus_release()
108 | {
109 | xSemaphoreGive(spiLock);
110 | }
111 |
--------------------------------------------------------------------------------
/components/odroid-go/odroid.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef _ODROID_H_
19 | #define _ODROID_H_
20 |
21 | #include "esp_heap_caps.h"
22 | #include "spi_lcd.h"
23 | #include "sdcard.h"
24 | #include "sound.h"
25 | #include "input.h"
26 |
27 | #define PIN_NUM_MISO 19
28 | #define PIN_NUM_MOSI 23
29 | #define PIN_NUM_CLK 18
30 | #define PIN_NUM_DC 21
31 | #define PIN_NUM_LCD_CS 5
32 | #define PIN_NUM_SD_CS 22
33 | #define PIN_NUM_LCD_BCKL 14
34 | #define SPI_DMA_CHANNEL 2
35 |
36 | #ifndef ODROID_TASKS_USE_CORE
37 | #define ODROID_TASKS_USE_CORE 0
38 | #endif
39 |
40 | size_t free_bytes_total();
41 | size_t free_bytes_internal();
42 | size_t free_bytes_spiram();
43 |
44 | void odroid_system_init();
45 | void odroid_system_led_set(int value);
46 | void odroid_spi_bus_acquire();
47 | void odroid_spi_bus_release();
48 | void odroid_fatal_error(char *error);
49 |
50 | #endif
--------------------------------------------------------------------------------
/components/odroid-go/sdcard.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "esp_vfs_fat.h"
24 | #include "driver/sdmmc_host.h"
25 | #include "driver/sdspi_host.h"
26 | #include "sdmmc_cmd.h"
27 | #include "odroid.h"
28 |
29 | static bool sdcard_initialized = false;
30 |
31 |
32 | void odroid_sdcard_init()
33 | {
34 | if (sdcard_initialized) return;
35 |
36 | printf("odroid_sdcard_init: Initializing SD Card.\n");
37 |
38 | sdmmc_host_t host = SDSPI_HOST_DEFAULT();
39 | host.slot = HSPI_HOST; // HSPI_HOST;
40 | host.max_freq_khz = SDMMC_FREQ_DEFAULT;
41 |
42 | sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
43 | slot_config.gpio_miso = PIN_NUM_MISO;
44 | slot_config.gpio_mosi = PIN_NUM_MOSI;
45 | slot_config.gpio_sck = PIN_NUM_CLK;
46 | slot_config.gpio_cs = PIN_NUM_SD_CS;
47 | slot_config.dma_channel = SPI_DMA_CHANNEL;
48 |
49 | esp_vfs_fat_sdmmc_mount_config_t mount_config = {
50 | .format_if_mount_failed = false,
51 | .max_files = 8
52 | };
53 |
54 | sdmmc_card_t* card;
55 |
56 | odroid_spi_bus_acquire();
57 | esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
58 | odroid_spi_bus_release();
59 |
60 | if (ret != ESP_OK) {
61 | if (ret == ESP_FAIL) {
62 | odroid_fatal_error("odroid_sdcard_init: Failed to mount filesystem.");
63 | } else {
64 | odroid_fatal_error("odroid_sdcard_init: Failed to initialize the card.");
65 | }
66 | } else {
67 | sdcard_initialized = true;
68 | }
69 | }
70 |
71 |
72 | int odroid_sdcard_read_file(char const *name, char **buffer)
73 | {
74 | odroid_spi_bus_acquire();
75 |
76 | FILE *fp = fopen(name, "rb");
77 |
78 | if (fp) {
79 | fseek(fp, 0, SEEK_END);
80 | int length = ftell(fp);
81 | fseek(fp, 0, SEEK_SET);
82 | *buffer = malloc(length);
83 | int read = fread(*buffer, 1, length, fp);
84 | fclose(fp);
85 |
86 | if (read != length) {
87 | printf("odroid_sdcard_read_file: Length mismatch (Got %d, expected %d)\n", read, length);
88 | }
89 |
90 | odroid_spi_bus_release();
91 | return read;
92 | }
93 |
94 | printf("odroid_sdcard_read_file: failed to open %s\n", name);
95 |
96 | odroid_spi_bus_release();
97 | return -1;
98 | }
99 |
100 |
101 | int odroid_sdcard_write_file(char const *name, void *source, int length)
102 | {
103 | odroid_spi_bus_acquire();
104 | FILE *fp = fopen(name, "wb");
105 |
106 | if (fp) {
107 | int written = fwrite(source, 1, length, fp); // Write data
108 | fclose(fp);
109 |
110 | if (written != length) {
111 | printf("odroid_sdcard_write_file: Length mismatch (Got %d, expected %d)\n", written, length);
112 | }
113 |
114 | odroid_spi_bus_release();
115 | return written;
116 | }
117 |
118 | printf("odroid_sdcard_write_file: failed to open %s\n", name);
119 |
120 | odroid_spi_bus_release();
121 | return -1;
122 | }
123 |
124 |
125 | int odroid_sdcard_mkdir(char const *path)
126 | {
127 | odroid_spi_bus_acquire();
128 | int ret = mkdir(path, 0755);
129 | odroid_spi_bus_release();
130 |
131 | return ret;
132 | }
133 |
134 |
135 | int odroid_sdcard_remove(char const *path)
136 | {
137 | odroid_spi_bus_acquire();
138 | int ret = remove(path);
139 | odroid_spi_bus_release();
140 |
141 | return ret;
142 | }
143 |
144 |
145 | int odroid_sdcard_list_files(char const *directory, char **buffer)
146 | {
147 | return 0;
148 | }
149 |
--------------------------------------------------------------------------------
/components/odroid-go/sdcard.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef _ODROID_SDCARD_H_
19 | #define _ODROID_SDCARD_H_
20 |
21 | void odroid_sdcard_init(void);
22 | int odroid_sdcard_read_file(char const *name, char **buffer);
23 | int odroid_sdcard_write_file(char const *name, void *source, int length);
24 | int odroid_sdcard_mkdir(char const *path);
25 | int odroid_sdcard_remove(char const *path);
26 | //#undef fopen
27 | //#define fopen
28 |
29 | #endif
--------------------------------------------------------------------------------
/components/odroid-go/sound.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include "freertos/FreeRTOS.h"
19 | #include "freertos/queue.h"
20 | #include "freertos/task.h"
21 | #include "driver/i2s.h"
22 | #include "odroid.h"
23 |
24 | #define SAMPLESIZE 2 // 16bit
25 | #define SAMPLERATE 22050
26 |
27 | static bool sound_initialized = false;
28 |
29 |
30 | void odroid_sound_init(void)
31 | {
32 | if (sound_initialized) return;
33 |
34 | printf("odroid_sound_init: Initializing sound.\n");
35 |
36 | static const i2s_config_t i2s_config = {
37 | .mode = I2S_MODE_MASTER | I2S_MODE_TX | /*I2S_MODE_PDM,*/ I2S_MODE_DAC_BUILT_IN,
38 | .sample_rate = SAMPLERATE,
39 | .bits_per_sample = SAMPLESIZE * 8, /* the DAC module will only take the 8bits from MSB */
40 | .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
41 | .communication_format = I2S_COMM_FORMAT_I2S_MSB,
42 | .intr_alloc_flags = 0, // default interrupt priority
43 | .dma_buf_count = 2,
44 | .dma_buf_len = 512, // (2) 16bit channels
45 | .use_apll = false
46 | };
47 |
48 | esp_err_t ret = i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); //install and start i2s driver
49 |
50 | if (ret != ESP_OK) {
51 | odroid_fatal_error("odroid_sound_init: Failed to initialize I2S.");
52 | }
53 |
54 | i2s_set_pin(I2S_NUM_0, NULL); //for internal DAC, this will enable both of the internal channels
55 |
56 | i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
57 | }
58 |
59 |
60 | void odroid_sound_deinit()
61 | {
62 | i2s_driver_uninstall(I2S_NUM_0);
63 | sound_initialized = false;
64 | }
65 |
66 |
67 | size_t * odroid_sound_write(void *buffer, size_t length)
68 | {
69 | size_t bytesWritten = 0;
70 | i2s_write(I2S_NUM_0, buffer, length, &bytesWritten, portMAX_DELAY);
71 | return bytesWritten;
72 | }
73 |
74 |
75 | void odroid_sound_set_sample_rate(uint32_t rate)
76 | {
77 | i2s_set_sample_rates(I2S_NUM_0, rate); //set sample rates
78 | }
79 |
80 |
81 | void odroid_sound_set_volume(uint32_t rate)
82 | {
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/components/odroid-go/sound.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef _ODROID_SOUND_H_
19 | #define _ODROID_SOUND_H_
20 |
21 | #define ODROID_SAMPLE_RATE 22050
22 | size_t * odroid_sound_write(void *buffer, size_t length);
23 | void odroid_sound_set_sample_rate(uint32_t rate);
24 | void odroid_sound_deinit(void);
25 | void odroid_sound_init(void);
26 |
27 | #endif
--------------------------------------------------------------------------------
/components/odroid-go/spi_lcd.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of odroid-go-std-lib.
3 | * Copyright (c) 2019 ducalex.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, version 3.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #ifndef _SPI_LCD_H_
19 | #define _SPI_LCD_H_
20 |
21 | typedef struct {
22 | uint8_t charCode;
23 | int adjYOffset;
24 | int width;
25 | int height;
26 | int xOffset;
27 | int xDelta;
28 | uint16_t dataPtr;
29 | } propFont;
30 |
31 | #define MADCTL_MY 0x80
32 | #define MADCTL_MX 0x40
33 | #define MADCTL_MV 0x20
34 | #define MADCTL_ML 0x10
35 | #define MADCTL_MH 0x04
36 | #define TFT_RGB_BGR 0x08
37 | #define TFT_LED_DUTY_MAX 0x1fff
38 | #define LCD_CMD 0
39 | #define LCD_DATA 1
40 |
41 | #define LCD_RGB(r, g, b) \
42 | (((((r / 255 * 31) & 0x1F) << 11) | (((g / 255 * 62) & 0x3F) << 5) | (((b / 255 * 31) & 0x1F))) << 8 \
43 | | ((((r / 255 * 31) & 0x1F) << 11) | (((g / 255 * 62) & 0x3F) << 5) | (((b / 255 * 31) & 0x1F))) >> 8) & 0xFFFF
44 |
45 | #define LCD_DEFAULT_PALETTE NULL
46 |
47 | short backlight_percentage_get(void);
48 | void backlight_percentage_set(short level);
49 |
50 | void spi_lcd_init();
51 | void spi_lcd_cmd(uint8_t cmd);
52 | void spi_lcd_write8(uint8_t data);
53 | void spi_lcd_write16(uint16_t data);
54 | void spi_lcd_write(uint8_t *data, int len, int dc);
55 | void spi_lcd_setWindow(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
56 | void spi_lcd_wait_finish();
57 | void spi_lcd_usePalette(bool use);
58 | void spi_lcd_setPalette(const int16_t *palette);
59 | void spi_lcd_clear();
60 | void spi_lcd_drawPixel(int x, int y, uint16_t color);
61 | void spi_lcd_fill(int x, int y, int w, int h, uint16_t color);
62 | void spi_lcd_setFont(const uint8_t *font);
63 | void spi_lcd_setFontColor(uint16_t color);
64 | void spi_lcd_print(int x, int y, char *string);
65 | void spi_lcd_printf(int x, int y, char *string, ...);
66 | void spi_lcd_useFrameBuffer(bool use);
67 | void spi_lcd_fb_setPtr(void *buffer);
68 | void*spi_lcd_fb_getPtr();
69 | void spi_lcd_fb_free();
70 | void spi_lcd_fb_alloc();
71 | void spi_lcd_fb_clear();
72 | void spi_lcd_fb_flush(); // fb_flush sends the buffer to the display now, it's synchronous
73 | void spi_lcd_fb_update(); // fb_update tells the display task it's time to redraw, it's async
74 | void spi_lcd_fb_write(void *buffer);
75 |
76 | #endif
--------------------------------------------------------------------------------
/components/snes9x/.gitignore:
--------------------------------------------------------------------------------
1 | # Files that can arise when using snes9x
2 | win32/snes9x.conf
3 | win32/Valid.Ext
4 | win32/stdout.txt
5 | win32/stderr.txt
6 | win32/Roms
7 | win32/Saves
8 | win32/Cheats
9 | win32/Screenshots
10 | win32/Movies
11 | win32/SPCs
12 | win32/BIOS
13 | *.smc
14 | *.sfc
15 | *.fig
16 | *.srm
17 | *.00[0123456789]
18 | *.oops
19 | *.ips
20 | *.ups
21 | *.bps
22 | *.avi
23 | *.shader
24 | *.cg
25 | *.cgp
26 | *.smv
27 | *.cht
28 | *.rtc
29 |
30 |
31 | # Included libraries in OS X that should not be ignored.
32 | !macosx/libz_u.a
33 | !macosx/libHIDUtilities_u.a
34 |
35 | # Included libraries in windows that should not be ignored.
36 | !win32/ddraw/ddraw_x86.lib
37 | !win32/ddraw/ddraw_x64.lib
38 |
39 | # Created by https://www.gitignore.io/api/c,c++,visualstudio
40 |
41 | ### C ###
42 | # Prerequisites
43 | *.d
44 |
45 | # Object files
46 | *.o
47 | *.ko
48 | *.obj
49 | *.elf
50 |
51 | # Linker output
52 | *.ilk
53 | *.map
54 | *.exp
55 |
56 | # Precompiled Headers
57 | *.gch
58 | *.pch
59 |
60 | # Libraries
61 | *.lib
62 | *.a
63 | *.la
64 | *.lo
65 |
66 | # Shared objects (inc. Windows DLLs)
67 | *.dll
68 | *.so
69 | *.so.*
70 | *.dylib
71 |
72 | # Executables
73 | *.exe
74 | *.out
75 | *.app
76 | *.i*86
77 | *.x86_64
78 | *.hex
79 |
80 | # Debug files
81 | *.dSYM/
82 | *.su
83 | *.idb
84 | *.pdb
85 |
86 | # Kernel Module Compile Results
87 | *.mod*
88 | *.cmd
89 | modules.order
90 | Module.symvers
91 | Mkfile.old
92 | dkms.conf
93 |
94 | ### C++ ###
95 | # Prerequisites
96 |
97 | # Compiled Object files
98 | *.slo
99 |
100 | # Precompiled Headers
101 |
102 | # Compiled Dynamic libraries
103 |
104 | # Fortran module files
105 | *.mod
106 | *.smod
107 |
108 | # Compiled Static libraries
109 | *.lai
110 |
111 | # Executables
112 |
113 | ### VisualStudio ###
114 | ## Ignore Visual Studio temporary files, build results, and
115 | ## files generated by popular Visual Studio add-ons.
116 | ##
117 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
118 |
119 | # User-specific files
120 | *.suo
121 | *.user
122 | *.userosscache
123 | *.sln.docstates
124 |
125 | # User-specific files (MonoDevelop/Xamarin Studio)
126 | *.userprefs
127 |
128 | # Build results
129 | [Dd]ebug/
130 | [Dd]ebugPublic/
131 | [Rr]elease/
132 | [Rr]eleases/
133 | x64/
134 | x86/
135 | bld/
136 | [Bb]in/
137 | [Oo]bj/
138 | [Ll]og/
139 |
140 | # Visual Studio 2015 cache/options directory
141 | .vs/
142 | # Uncomment if you have tasks that create the project's static files in wwwroot
143 | #wwwroot/
144 |
145 | # MSTest test Results
146 | [Tt]est[Rr]esult*/
147 | [Bb]uild[Ll]og.*
148 |
149 | # NUNIT
150 | *.VisualState.xml
151 | TestResult.xml
152 |
153 | # Build Results of an ATL Project
154 | [Dd]ebugPS/
155 | [Rr]eleasePS/
156 | dlldata.c
157 |
158 | # .NET Core
159 | project.lock.json
160 | project.fragment.lock.json
161 | artifacts/
162 | **/Properties/launchSettings.json
163 |
164 | *_i.c
165 | *_p.c
166 | *_i.h
167 | *.meta
168 | *.pgc
169 | *.pgd
170 | *.rsp
171 | *.sbr
172 | *.tlb
173 | *.tli
174 | *.tlh
175 | *.tmp
176 | *.tmp_proj
177 | *.log
178 | *.vspscc
179 | *.vssscc
180 | .builds
181 | *.pidb
182 | *.svclog
183 | *.scc
184 |
185 | # Chutzpah Test files
186 | _Chutzpah*
187 |
188 | # Visual C++ cache files
189 | ipch/
190 | *.aps
191 | *.ncb
192 | *.opendb
193 | *.opensdf
194 | *.sdf
195 | *.cachefile
196 | *.VC.db
197 | *.VC.VC.opendb
198 |
199 | # Visual Studio profiler
200 | *.psess
201 | *.vsp
202 | *.vspx
203 | *.sap
204 |
205 | # TFS 2012 Local Workspace
206 | $tf/
207 |
208 | # Guidance Automation Toolkit
209 | *.gpState
210 |
211 | # ReSharper is a .NET coding add-in
212 | _ReSharper*/
213 | *.[Rr]e[Ss]harper
214 | *.DotSettings.user
215 |
216 | # JustCode is a .NET coding add-in
217 | .JustCode
218 |
219 | # TeamCity is a build add-in
220 | _TeamCity*
221 |
222 | # DotCover is a Code Coverage Tool
223 | *.dotCover
224 |
225 | # Visual Studio code coverage results
226 | *.coverage
227 | *.coveragexml
228 |
229 | # NCrunch
230 | _NCrunch_*
231 | .*crunch*.local.xml
232 | nCrunchTemp_*
233 |
234 | # MightyMoose
235 | *.mm.*
236 | AutoTest.Net/
237 |
238 | # Web workbench (sass)
239 | .sass-cache/
240 |
241 | # Installshield output folder
242 | [Ee]xpress/
243 |
244 | # DocProject is a documentation generator add-in
245 | DocProject/buildhelp/
246 | DocProject/Help/*.HxT
247 | DocProject/Help/*.HxC
248 | DocProject/Help/*.hhc
249 | DocProject/Help/*.hhk
250 | DocProject/Help/*.hhp
251 | DocProject/Help/Html2
252 | DocProject/Help/html
253 |
254 | # Click-Once directory
255 | publish/
256 |
257 | # Publish Web Output
258 | *.[Pp]ublish.xml
259 | *.azurePubxml
260 | # TODO: Comment the next line if you want to checkin your web deploy settings
261 | # but database connection strings (with potential passwords) will be unencrypted
262 | *.pubxml
263 | *.publishproj
264 |
265 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
266 | # checkin your Azure Web App publish settings, but sensitive information contained
267 | # in these scripts will be unencrypted
268 | PublishScripts/
269 |
270 | # NuGet Packages
271 | *.nupkg
272 | # The packages folder can be ignored because of Package Restore
273 | **/packages/*
274 | # except build/, which is used as an MSBuild target.
275 | !**/packages/build/
276 | # Uncomment if necessary however generally it will be regenerated when needed
277 | #!**/packages/repositories.config
278 | # NuGet v3's project.json files produces more ignorable files
279 | *.nuget.props
280 | *.nuget.targets
281 |
282 | # Microsoft Azure Build Output
283 | csx/
284 | *.build.csdef
285 |
286 | # Microsoft Azure Emulator
287 | ecf/
288 | rcf/
289 |
290 | # Windows Store app package directories and files
291 | AppPackages/
292 | BundleArtifacts/
293 | Package.StoreAssociation.xml
294 | _pkginfo.txt
295 |
296 | # Visual Studio cache files
297 | # files ending in .cache can be ignored
298 | *.[Cc]ache
299 | # but keep track of directories ending in .cache
300 | !*.[Cc]ache/
301 |
302 | # Others
303 | ClientBin/
304 | ~$*
305 | *~
306 | *.dbmdl
307 | *.dbproj.schemaview
308 | *.jfm
309 | *.pfx
310 | *.publishsettings
311 | orleans.codegen.cs
312 |
313 | # Since there are multiple workflows, uncomment next line to ignore bower_components
314 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
315 | #bower_components/
316 |
317 | # RIA/Silverlight projects
318 | Generated_Code/
319 |
320 | # Backup & report files from converting an old project file
321 | # to a newer Visual Studio version. Backup files are not needed,
322 | # because we have git ;-)
323 | _UpgradeReport_Files/
324 | Backup*/
325 | UpgradeLog*.XML
326 | UpgradeLog*.htm
327 |
328 | # SQL Server files
329 | *.mdf
330 | *.ldf
331 | *.ndf
332 |
333 | # Business Intelligence projects
334 | *.rdl.data
335 | *.bim.layout
336 | *.bim_*.settings
337 |
338 | # Microsoft Fakes
339 | FakesAssemblies/
340 |
341 | # GhostDoc plugin setting file
342 | *.GhostDoc.xml
343 |
344 | # Node.js Tools for Visual Studio
345 | .ntvs_analysis.dat
346 | node_modules/
347 |
348 | # Typescript v1 declaration files
349 | typings/
350 |
351 | # Visual Studio 6 build log
352 | *.plg
353 |
354 | # Visual Studio 6 workspace options file
355 | *.opt
356 |
357 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
358 | *.vbw
359 |
360 | # Visual Studio LightSwitch build output
361 | **/*.HTMLClient/GeneratedArtifacts
362 | **/*.DesktopClient/GeneratedArtifacts
363 | **/*.DesktopClient/ModelManifest.xml
364 | **/*.Server/GeneratedArtifacts
365 | **/*.Server/ModelManifest.xml
366 | _Pvt_Extensions
367 |
368 | # Paket dependency manager
369 | .paket/paket.exe
370 | paket-files/
371 |
372 | # FAKE - F# Make
373 | .fake/
374 |
375 | # JetBrains Rider
376 | .idea/
377 | *.sln.iml
378 |
379 | # CodeRush
380 | .cr/
381 |
382 | # Python Tools for Visual Studio (PTVS)
383 | __pycache__/
384 | *.pyc
385 |
386 | # Cake - Uncomment if you are using it
387 | # tools/**
388 | # !tools/packages.config
389 |
390 | # Telerik's JustMock configuration file
391 | *.jmconfig
392 |
393 | # BizTalk build output
394 | *.btp.cs
395 | *.btm.cs
396 | *.odx.cs
397 | *.xsd.cs
398 |
399 | # End of https://www.gitignore.io/api/c,c++,visualstudio
400 |
--------------------------------------------------------------------------------
/components/snes9x/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "win32/libpng/src"]
2 | path = win32/libpng/src
3 | url = https://git.code.sf.net/p/libpng/code
4 | [submodule "win32/zlib/src"]
5 | path = win32/zlib/src
6 | url = https://github.com/madler/zlib.git
7 | [submodule "win32/DirectXMath"]
8 | path = win32/DirectXMath
9 | url = https://github.com/Microsoft/DirectXMath
10 | [submodule "shaders/SPIRV-Cross"]
11 | path = shaders/SPIRV-Cross
12 | url = https://github.com/KhronosGroup/SPIRV-Cross.git
13 | [submodule "win32/glslang/src"]
14 | path = win32/glslang/src
15 | url = https://github.com/KhronosGroup/glslang.git
16 |
--------------------------------------------------------------------------------
/components/snes9x/65c816.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************\
2 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 | This file is licensed under the Snes9x License.
4 | For further information, consult the LICENSE file in the root directory.
5 | \*****************************************************************************/
6 |
7 | #ifndef _65C816_H_
8 | #define _65C816_H_
9 |
10 | #define Carry 1
11 | #define Zero 2
12 | #define IRQ 4
13 | #define Decimal 8
14 | #define IndexFlag 16
15 | #define MemoryFlag 32
16 | #define Overflow 64
17 | #define Negative 128
18 | #define Emulation 256
19 |
20 | #define SetCarry() (ICPU._Carry = 1)
21 | #define ClearCarry() (ICPU._Carry = 0)
22 | #define SetZero() (ICPU._Zero = 0)
23 | #define ClearZero() (ICPU._Zero = 1)
24 | #define SetIRQ() (Registers.PL |= IRQ)
25 | #define ClearIRQ() (Registers.PL &= ~IRQ)
26 | #define SetDecimal() (Registers.PL |= Decimal)
27 | #define ClearDecimal() (Registers.PL &= ~Decimal)
28 | #define SetIndex() (Registers.PL |= IndexFlag)
29 | #define ClearIndex() (Registers.PL &= ~IndexFlag)
30 | #define SetMemory() (Registers.PL |= MemoryFlag)
31 | #define ClearMemory() (Registers.PL &= ~MemoryFlag)
32 | #define SetOverflow() (ICPU._Overflow = 1)
33 | #define ClearOverflow() (ICPU._Overflow = 0)
34 | #define SetNegative() (ICPU._Negative = 0x80)
35 | #define ClearNegative() (ICPU._Negative = 0)
36 |
37 | #define CheckCarry() (ICPU._Carry)
38 | #define CheckZero() (ICPU._Zero == 0)
39 | #define CheckIRQ() (Registers.PL & IRQ)
40 | #define CheckDecimal() (Registers.PL & Decimal)
41 | #define CheckIndex() (Registers.PL & IndexFlag)
42 | #define CheckMemory() (Registers.PL & MemoryFlag)
43 | #define CheckOverflow() (ICPU._Overflow)
44 | #define CheckNegative() (ICPU._Negative & 0x80)
45 | #define CheckEmulation() (Registers.P.W & Emulation)
46 |
47 | #define SetFlags(f) (Registers.P.W |= (f))
48 | #define ClearFlags(f) (Registers.P.W &= ~(f))
49 | #define CheckFlag(f) (Registers.PL & (f))
50 |
51 | typedef union
52 | {
53 | #ifdef LSB_FIRST
54 | struct { uint8 l, h; } B;
55 | #else
56 | struct { uint8 h, l; } B;
57 | #endif
58 | uint16 W;
59 | } pair;
60 |
61 | typedef union
62 | {
63 | #ifdef LSB_FIRST
64 | struct { uint8 xPCl, xPCh, xPB, z; } B;
65 | struct { uint16 xPC, d; } W;
66 | #else
67 | struct { uint8 z, xPB, xPCh, xPCl; } B;
68 | struct { uint16 d, xPC; } W;
69 | #endif
70 | uint32 xPBPC;
71 | } PC_t;
72 |
73 | struct SRegisters
74 | {
75 | uint8 DB;
76 | pair P;
77 | pair A;
78 | pair D;
79 | pair S;
80 | pair X;
81 | pair Y;
82 | PC_t PC;
83 | };
84 |
85 | #define AL A.B.l
86 | #define AH A.B.h
87 | #define XL X.B.l
88 | #define XH X.B.h
89 | #define YL Y.B.l
90 | #define YH Y.B.h
91 | #define SL S.B.l
92 | #define SH S.B.h
93 | #define DL D.B.l
94 | #define DH D.B.h
95 | #define PL P.B.l
96 | #define PH P.B.h
97 | #define PBPC PC.xPBPC
98 | #define PCw PC.W.xPC
99 | #define PCh PC.B.xPCh
100 | #define PCl PC.B.xPCl
101 | #define PB PC.B.xPB
102 |
103 | extern struct SRegisters Registers;
104 |
105 | #endif
106 |
--------------------------------------------------------------------------------
/components/snes9x/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(COMPONENT_SRCDIRS ".")
2 | set(COMPONENT_ADD_INCLUDEDIRS ".")
3 | set(COMPONENT_REQUIRES "odroid-go")
4 | register_component()
5 | component_compile_options(
6 | -fomit-frame-pointer -fno-exceptions -fno-stack-protector
7 | -finline-limit=255
8 | -fdata-sections -ffunction-sections -Wl,--gc-sections
9 | -fno-stack-protector -fno-ident -fomit-frame-pointer
10 | -falign-functions=1 -falign-jumps=1 -falign-loops=1
11 | -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops
12 | -fmerge-all-constants -fno-math-errno
13 | -fno-exceptions -fno-rtti
14 | )
15 |
--------------------------------------------------------------------------------
/components/snes9x/LICENSE:
--------------------------------------------------------------------------------
1 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
2 |
3 | (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
4 | Jerremy Koot (jkoot@snes9x.com)
5 |
6 | (c) Copyright 2002 - 2004 Matthew Kendora
7 |
8 | (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
9 |
10 | (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
11 |
12 | (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
13 |
14 | (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
15 | Kris Bleakley (codeviolation@hotmail.com)
16 |
17 | (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
18 | Nach (n-a-c-h@users.sourceforge.net),
19 |
20 | (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com)
21 |
22 | (c) Copyright 2006 - 2007 nitsuja
23 |
24 | (c) Copyright 2009 - 2019 BearOso,
25 | OV2
26 |
27 | (c) Copyright 2017 qwertymodo
28 |
29 | (c) Copyright 2011 - 2017 Hans-Kristian Arntzen,
30 | Daniel De Matteis
31 | (Under no circumstances will commercial rights be given)
32 |
33 |
34 | BS-X C emulator code
35 | (c) Copyright 2005 - 2006 Dreamer Nom,
36 | zones
37 |
38 | C4 x86 assembler and some C emulation code
39 | (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
40 | Nach,
41 | zsKnight (zsknight@zsnes.com)
42 |
43 | C4 C++ code
44 | (c) Copyright 2003 - 2006 Brad Jorsch,
45 | Nach
46 |
47 | DSP-1 emulator code
48 | (c) Copyright 1998 - 2006 _Demo_,
49 | Andreas Naive (andreasnaive@gmail.com),
50 | Gary Henderson,
51 | Ivar (ivar@snes9x.com),
52 | John Weidman,
53 | Kris Bleakley,
54 | Matthew Kendora,
55 | Nach,
56 | neviksti (neviksti@hotmail.com)
57 |
58 | DSP-2 emulator code
59 | (c) Copyright 2003 John Weidman,
60 | Kris Bleakley,
61 | Lord Nightmare (lord_nightmare@users.sourceforge.net),
62 | Matthew Kendora,
63 | neviksti
64 |
65 | DSP-3 emulator code
66 | (c) Copyright 2003 - 2006 John Weidman,
67 | Kris Bleakley,
68 | Lancer,
69 | z80 gaiden
70 |
71 | DSP-4 emulator code
72 | (c) Copyright 2004 - 2006 Dreamer Nom,
73 | John Weidman,
74 | Kris Bleakley,
75 | Nach,
76 | z80 gaiden
77 |
78 | OBC1 emulator code
79 | (c) Copyright 2001 - 2004 zsKnight,
80 | pagefault (pagefault@zsnes.com),
81 | Kris Bleakley
82 | Ported from x86 assembler to C by sanmaiwashi
83 |
84 | SPC7110 and RTC C++ emulator code used in 1.39-1.51
85 | (c) Copyright 2002 Matthew Kendora with research by
86 | zsKnight,
87 | John Weidman,
88 | Dark Force
89 |
90 | SPC7110 and RTC C++ emulator code used in 1.52+
91 | (c) Copyright 2009 byuu,
92 | neviksti
93 |
94 | S-DD1 C emulator code
95 | (c) Copyright 2003 Brad Jorsch with research by
96 | Andreas Naive,
97 | John Weidman
98 |
99 | S-RTC C emulator code
100 | (c) Copyright 2001 - 2006 byuu,
101 | John Weidman
102 |
103 | ST010 C++ emulator code
104 | (c) Copyright 2003 Feather,
105 | John Weidman,
106 | Kris Bleakley,
107 | Matthew Kendora
108 |
109 | Super FX x86 assembler emulator code
110 | (c) Copyright 1998 - 2003 _Demo_,
111 | pagefault,
112 | zsKnight
113 |
114 | Super FX C emulator code
115 | (c) Copyright 1997 - 1999 Ivar,
116 | Gary Henderson,
117 | John Weidman
118 |
119 | Sound emulator code used in 1.5-1.51
120 | (c) Copyright 1998 - 2003 Brad Martin
121 | (c) Copyright 1998 - 2006 Charles Bilyue'
122 |
123 | Sound emulator code used in 1.52+
124 | (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
125 |
126 | S-SMP emulator code used in 1.54+
127 | (c) Copyright 2016 byuu
128 |
129 | SH assembler code partly based on x86 assembler code
130 | (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
131 |
132 | 2xSaI filter
133 | (c) Copyright 1999 - 2001 Derek Liauw Kie Fa
134 |
135 | HQ2x, HQ3x, HQ4x filters
136 | (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
137 |
138 | NTSC filter
139 | (c) Copyright 2006 - 2007 Shay Green
140 |
141 | GTK+ GUI code
142 | (c) Copyright 2004 - 2019 BearOso
143 |
144 | Win32 GUI code
145 | (c) Copyright 2003 - 2006 blip,
146 | funkyass,
147 | Matthew Kendora,
148 | Nach,
149 | nitsuja
150 | (c) Copyright 2009 - 2019 OV2
151 |
152 | Mac OS GUI code
153 | (c) Copyright 1998 - 2001 John Stiles
154 | (c) Copyright 2001 - 2011 zones
155 |
156 | Libretro port
157 | (c) Copyright 2011 - 2017 Hans-Kristian Arntzen,
158 | Daniel De Matteis
159 | (Under no circumstances will commercial rights be given)
160 |
161 |
162 | Specific ports contains the works of other authors. See headers in
163 | individual files.
164 |
165 |
166 | Snes9x homepage: http://www.snes9x.com/
167 | Snes9x source code: https://github.com/snes9xgit/snes9x/
168 |
169 | Permission to use, copy, modify and/or distribute Snes9x in both binary
170 | and source form, for non-commercial purposes, is hereby granted without
171 | fee, providing that this license information and copyright notice appear
172 | with all copies and any derived work.
173 |
174 | This software is provided 'as-is', without any express or implied
175 | warranty. In no event shall the authors be held liable for any damages
176 | arising from the use of this software or it's derivatives.
177 |
178 | Snes9x is freeware for PERSONAL USE only. Commercial users should
179 | seek permission of the copyright holders first. Commercial use includes,
180 | but is not limited to, charging money for Snes9x or software derived from
181 | Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
182 | using Snes9x as a promotion for your commercial product.
183 |
184 | The copyright holders request that bug fixes and improvements to the code
185 | should be forwarded to them so everyone can benefit from the modifications
186 | in future versions.
187 |
188 | Super NES and Super Nintendo Entertainment System are trademarks of
189 | Nintendo Co., Limited and its subsidiary companies.
190 |
191 | -------------------------------------------------------------------------------
192 |
193 | Some parts included in Snes9x are usually available under a different license,
194 | their authors have granted exception for their use in Snes9x (and/or they are
195 | licensed as LGPL):
196 | - JMA: GPL/LGPL, see jma/license.txt
197 | - snes_ntsc: LGPL, see filter/snes_ntsc-license.txt
198 | - xBRZ: GPLv3, see filter/xbrz-license.txt
199 |
--------------------------------------------------------------------------------
/components/snes9x/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Component Makefile
3 | #
4 | # This Makefile should, at the very least, just include $(SDK_PATH)/make/component.mk. By default,
5 | # this will take the sources in the src/ directory, compile them and link them into
6 | # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
7 | # please read the SDK documents if you need to do this.
8 | #
9 |
10 |
11 | include $(IDF_PATH)/make/component.mk
12 |
13 |
--------------------------------------------------------------------------------
/components/snes9x/README.md:
--------------------------------------------------------------------------------
1 | # Snes9x
2 | *Snes9x - Portable Super Nintendo Entertainment System (TM) emulator*
3 |
4 | This is the official source code repository for the Snes9x project.
5 |
6 | Please check the [Wiki](https://github.com/snes9xgit/snes9x/wiki) for additional information.
7 |
--------------------------------------------------------------------------------
/components/snes9x/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 1.60-{build}
2 |
3 | image: Visual Studio 2017
4 |
5 | environment:
6 | matrix:
7 | - generator: "Visual Studio 15"
8 | config: Release Unicode
9 | platform: Win32
10 | arch: win32
11 | output: win32\snes9x.exe
12 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
13 |
14 | - generator: "Visual Studio 15"
15 | config: Release Unicode
16 | platform: x64
17 | arch: win32-x64
18 | output: win32\snes9x-x64.exe
19 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
20 |
21 | - generator: "Visual Studio 15"
22 | config: libretro Release
23 | platform: Win32
24 | arch: libretro
25 | output: libretro\Win32\libretro Release\snes9x_libretro.dll
26 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
27 |
28 | - generator: "Visual Studio 15"
29 | config: libretro Release
30 | platform: x64
31 | arch: libretro-x64
32 | output: libretro\x64\libretro Release\snes9x_libretro.dll
33 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
34 |
35 | init:
36 | - git config --global core.autocrlf input
37 |
38 | before_build:
39 | - git submodule update --init --recursive
40 |
41 | build_script:
42 | - if "%config%"=="Release Unicode" msbuild win32\snes9xw.sln /t:build /p:Configuration="%config%";Platform="%platform%" /m /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
43 | - if "%config%"=="libretro Release" msbuild libretro\libretro-win32.vcxproj /t:build /p:Configuration="%config%";Platform="%platform%" /m /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
44 |
45 | after_build:
46 | - ps: $env:gitrev = git describe --tags
47 | - ps: $env:my_version = "$env:gitrev"
48 | - set package_name=snes9x-%my_version%-%arch%
49 | - if exist artifacts rmdir /s /q artifacts
50 | - mkdir artifacts
51 | - copy "%output%" artifacts
52 | - if "%config%"=="Release Unicode"
53 | copy docs\changes.txt artifacts |
54 | copy LICENSE artifacts |
55 | copy win32\docs\faqs-windows.txt artifacts |
56 | copy win32\docs\readme-windows.txt artifacts |
57 | copy data\cheats.bml artifacts
58 | - 7z a %package_name%.zip .\artifacts\*
59 |
60 | artifacts:
61 | - path: $(package_name).zip
62 | name: $(arch)
63 |
--------------------------------------------------------------------------------
/components/snes9x/apu.cpp:
--------------------------------------------------------------------------------
1 | /*****************************************************************************\
2 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 | This file is licensed under the Snes9x License.
4 | For further information, consult the LICENSE file in the root directory.
5 | \*****************************************************************************/
6 |
7 | #include
8 | #include "snes9x.h"
9 | #include "apu.h"
10 | static const int APU_DEFAULT_INPUT_RATE = 31950; // ~59.94Hz
11 | static const int APU_SAMPLE_BLOCK = 48;
12 | static const int APU_NUMERATOR_NTSC = 15664;
13 | static const int APU_DENOMINATOR_NTSC = 328125;
14 | static const int APU_NUMERATOR_PAL = 34176;
15 | static const int APU_DENOMINATOR_PAL = 709379;
16 |
17 | namespace SNES {
18 | struct Processor
19 | {
20 | unsigned frequency;
21 | int32 clock;
22 | };
23 |
24 | #include "apu_smp.hpp"
25 |
26 | class CPU
27 | {
28 | public:
29 | uint8 registers[4];
30 |
31 | inline void reset ()
32 | {
33 | registers[0] = registers[1] = registers[2] = registers[3] = 0;
34 | }
35 |
36 | inline void port_write (uint8 port, uint8 data)
37 | {
38 | registers[port & 3] = data;
39 | }
40 |
41 | inline uint8 port_read (uint8 port)
42 | {
43 | return registers[port & 3];
44 | }
45 | };
46 | CPU cpu;
47 | } // namespace SNES
48 |
49 |
50 | bool8 S9xInitSound(int buffer_ms)
51 | {
52 | return false;
53 | }
54 |
55 | bool8 S9xInitAPU(void)
56 | {
57 | return (TRUE);
58 | }
59 |
60 | void S9xDeinitAPU(void)
61 | {
62 | }
63 |
64 | uint8 S9xAPUReadPort(int port)
65 | {
66 | S9xAPUExecute();
67 | return ((uint8)SNES::smp.port_read(port & 3));
68 | }
69 |
70 | void S9xAPUWritePort(int port, uint8 byte)
71 | {
72 | S9xAPUExecute();
73 | SNES::cpu.port_write(port & 3, byte);
74 | }
75 |
76 | void S9xAPUSetReferenceTime(int32 cpucycles)
77 | {
78 | }
79 |
80 | void S9xAPUExecute(void)
81 | {
82 | static uint32 remainder = 0;
83 | int32 cpucycles = CPU.Cycles;
84 | SNES::smp.clock -= (APU_NUMERATOR_NTSC * (cpucycles - 0) + remainder) / APU_DENOMINATOR_NTSC;
85 | SNES::smp.enter();
86 |
87 | S9xAPUSetReferenceTime(CPU.Cycles);
88 | }
89 |
90 | void S9xAPUEndScanline(void)
91 | {
92 | S9xAPUExecute();
93 | }
94 |
95 | void S9xAPUTimingSetSpeedup(int ticks)
96 | {
97 | }
98 |
99 | void S9xResetAPU(void)
100 | {
101 | SNES::cpu.reset();
102 | SNES::smp.power();
103 |
104 | S9xClearSamples();
105 | }
106 |
107 | void S9xSoftResetAPU(void)
108 | {
109 | SNES::cpu.reset();
110 | SNES::smp.reset();
111 |
112 | S9xClearSamples();
113 | }
114 |
115 | void S9xAPUSaveState(uint8 *block)
116 | {
117 | }
118 |
119 | void S9xAPULoadState(uint8 *block)
120 | {
121 | }
122 |
123 | void S9xAPULoadBlarggState(uint8 *oldblock)
124 | {
125 | }
126 |
127 | bool8 S9xSPCDump(const char *filename)
128 | {
129 | return (TRUE);
130 | }
131 |
132 | bool8 S9xMixSamples(uint8 *dest, int sample_count)
133 | {
134 | return true;
135 | }
136 |
137 | int S9xGetSampleCount(void)
138 | {
139 | return 0;
140 | }
141 |
142 | void S9xLandSamples(void)
143 | {
144 | }
145 |
146 | void S9xClearSamples(void)
147 | {
148 | }
149 |
150 | bool8 S9xSyncSound(void)
151 | {
152 | return true;
153 | }
154 |
155 | void S9xSetSamplesAvailableCallback(apu_callback callback, void *data)
156 | {
157 | }
158 |
159 | void S9xUpdateDynamicRate(int avail, int buffer_size)
160 | {
161 | }
162 |
163 | void S9xSetSoundControl(uint8 voice_switch)
164 | {
165 | }
166 |
167 | void S9xSetSoundMute(bool8 mute)
168 | {
169 | }
170 |
171 | void S9xDumpSPCSnapshot(void)
172 | {
173 | }
174 |
--------------------------------------------------------------------------------
/components/snes9x/apu.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************\
2 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 | This file is licensed under the Snes9x License.
4 | For further information, consult the LICENSE file in the root directory.
5 | \*****************************************************************************/
6 |
7 | #ifndef _APU_H_
8 | #define _APU_H_
9 |
10 | #include "snes9x.h"
11 |
12 | typedef void (*apu_callback) (void *);
13 |
14 | #define SPC_SAVE_STATE_BLOCK_SIZE (1024 * 65)
15 | #define SPC_FILE_SIZE (66048)
16 |
17 | bool8 S9xInitAPU (void);
18 | void S9xDeinitAPU (void);
19 | void S9xResetAPU (void);
20 | void S9xSoftResetAPU (void);
21 | uint8 S9xAPUReadPort (int);
22 | void S9xAPUWritePort (int, uint8);
23 | void S9xAPUExecute (void);
24 | void S9xAPUEndScanline (void);
25 | void S9xAPUSetReferenceTime (int32);
26 | void S9xAPUTimingSetSpeedup (int);
27 | void S9xAPULoadState (uint8 *);
28 | void S9xAPULoadBlarggState(uint8 *oldblock);
29 | void S9xAPUSaveState (uint8 *);
30 | void S9xDumpSPCSnapshot (void);
31 | bool8 S9xSPCDump (const char *);
32 |
33 | bool8 S9xInitSound (int);
34 | bool8 S9xOpenSoundDevice (void);
35 |
36 | bool8 S9xSyncSound (void);
37 | int S9xGetSampleCount (void);
38 | void S9xSetSoundControl (uint8);
39 | void S9xSetSoundMute (bool8);
40 | void S9xLandSamples (void);
41 | void S9xClearSamples (void);
42 | bool8 S9xMixSamples (uint8 *, int);
43 | void S9xSetSamplesAvailableCallback (apu_callback, void *);
44 | void S9xUpdateDynamicRate (int, int);
45 |
46 | #define DSP_INTERPOLATION_NONE 0
47 | #define DSP_INTERPOLATION_LINEAR 1
48 | #define DSP_INTERPOLATION_GAUSSIAN 2
49 | #define DSP_INTERPOLATION_CUBIC 3
50 | #define DSP_INTERPOLATION_SINC 4
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/components/snes9x/apu_smp.hpp:
--------------------------------------------------------------------------------
1 | class SMP : public Processor {
2 | public:
3 | static const uint8 iplrom[64];
4 | uint8 *apuram;
5 |
6 | unsigned port_read(unsigned port);
7 | void port_write(unsigned port, unsigned data);
8 |
9 | unsigned mmio_read(unsigned addr);
10 | void mmio_write(unsigned addr, unsigned data);
11 |
12 | void enter();
13 | void power();
14 | void reset();
15 |
16 | SMP();
17 | ~SMP();
18 |
19 | //private:
20 | struct Flags {
21 | bool n, v, p, b, h, i, z, c;
22 |
23 | inline operator unsigned() const {
24 | return (n << 7) | (v << 6) | (p << 5) | (b << 4)
25 | | (h << 3) | (i << 2) | (z << 1) | (c << 0);
26 | };
27 |
28 | inline unsigned operator=(unsigned data) {
29 | n = data & 0x80; v = data & 0x40; p = data & 0x20; b = data & 0x10;
30 | h = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01;
31 | return data;
32 | }
33 |
34 | inline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); }
35 | inline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); }
36 | inline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); }
37 | };
38 |
39 | unsigned opcode_number;
40 | unsigned opcode_cycle;
41 |
42 | uint16 rd, wr, dp, sp, ya, bit;
43 |
44 | struct Regs {
45 | uint16 pc;
46 | uint8 sp;
47 | union {
48 | uint16 ya;
49 | #ifndef __BIG_ENDIAN__
50 | struct { uint8 a, y; } B;
51 | #else
52 | struct { uint8 y, a; } B;
53 | #endif
54 | };
55 | uint8 x;
56 | Flags p;
57 | } regs;
58 |
59 | struct Status {
60 | //$00f1
61 | bool iplrom_enable;
62 |
63 | //$00f2
64 | unsigned dsp_addr;
65 |
66 | //$00f8,$00f9
67 | unsigned ram00f8;
68 | unsigned ram00f9;
69 | } status;
70 |
71 | template
72 | struct Timer {
73 | bool enable;
74 | uint8 target;
75 | uint8 stage1_ticks;
76 | uint8 stage2_ticks;
77 | uint8 stage3_ticks;
78 |
79 | inline void tick();
80 | inline void tick(unsigned clocks);
81 | };
82 |
83 | Timer<128> timer0;
84 | Timer<128> timer1;
85 | Timer< 16> timer2;
86 |
87 | inline void tick();
88 | inline void tick(unsigned clocks);
89 | inline void op_io();
90 | inline void op_io(unsigned clocks);
91 | inline uint8 op_read(uint16 addr);
92 | inline void op_write(uint16 addr, uint8 data);
93 | inline void op_step();
94 | inline void op_writestack(uint8 data);
95 | inline uint8 op_readstack();
96 | static const unsigned cycle_count_table[256];
97 | uint64 cycle_table_cpu[256];
98 | unsigned cycle_table_dsp[256];
99 | uint64 cycle_step_cpu;
100 |
101 | inline uint8 op_adc (uint8 x, uint8 y);
102 | inline uint16 op_addw(uint16 x, uint16 y);
103 | inline uint8 op_and (uint8 x, uint8 y);
104 | inline uint8 op_cmp (uint8 x, uint8 y);
105 | inline uint16 op_cmpw(uint16 x, uint16 y);
106 | inline uint8 op_eor (uint8 x, uint8 y);
107 | inline uint8 op_inc (uint8 x);
108 | inline uint8 op_dec (uint8 x);
109 | inline uint8 op_or (uint8 x, uint8 y);
110 | inline uint8 op_sbc (uint8 x, uint8 y);
111 | inline uint16 op_subw(uint16 x, uint16 y);
112 | inline uint8 op_asl (uint8 x);
113 | inline uint8 op_lsr (uint8 x);
114 | inline uint8 op_rol (uint8 x);
115 | inline uint8 op_ror (uint8 x);
116 | #ifdef DEBUGGER
117 | void disassemble_opcode(char *output, uint16 addr);
118 | inline uint8 disassemble_read(uint16 addr);
119 | inline uint16 relb(int8 offset, int op_len);
120 | #endif
121 | };
122 |
123 | extern SMP smp;
124 |
--------------------------------------------------------------------------------
/components/snes9x/apu_snes.hpp:
--------------------------------------------------------------------------------
1 | #ifndef __SNES_HPP
2 | #define __SNES_HPP
3 |
4 | #include "snes9x.h"
5 |
6 | #if defined(__GNUC__)
7 | #define inline inline
8 | #define alwaysinline inline __attribute__((always_inline))
9 | #elif defined(_MSC_VER)
10 | #define inline inline
11 | #define alwaysinline inline __forceinline
12 | #else
13 | #define inline inline
14 | #define alwaysinline inline
15 | #endif
16 |
17 | #define debugvirtual
18 |
19 | namespace SNES
20 | {
21 |
22 | struct Processor
23 | {
24 | unsigned frequency;
25 | int32 clock;
26 | };
27 |
28 | #include "apu_smp.hpp"
29 |
30 | class CPU
31 | {
32 | public:
33 | uint8 registers[4];
34 |
35 | inline void reset ()
36 | {
37 | registers[0] = registers[1] = registers[2] = registers[3] = 0;
38 | }
39 |
40 | alwaysinline void port_write (uint8 port, uint8 data)
41 | {
42 | registers[port & 3] = data;
43 | }
44 |
45 | alwaysinline uint8 port_read (uint8 port)
46 | {
47 | return registers[port & 3];
48 | }
49 | };
50 |
51 | extern CPU cpu;
52 |
53 | } // namespace SNES
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/components/snes9x/clip.cpp:
--------------------------------------------------------------------------------
1 | /*****************************************************************************\
2 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 | This file is licensed under the Snes9x License.
4 | For further information, consult the LICENSE file in the root directory.
5 | \*****************************************************************************/
6 |
7 | #include "snes9x.h"
8 | #include "memmap.h"
9 |
10 | static uint8 region_map[6][6] =
11 | {
12 | { 0, 0x01, 0x03, 0x07, 0x0f, 0x1f },
13 | { 0, 0, 0x02, 0x06, 0x0e, 0x1e },
14 | { 0, 0, 0, 0x04, 0x0c, 0x1c },
15 | { 0, 0, 0, 0, 0x08, 0x18 },
16 | { 0, 0, 0, 0, 0, 0x10 }
17 | };
18 |
19 | static inline uint8 CalcWindowMask (int, uint8, uint8);
20 | static inline void StoreWindowRegions (uint8, struct ClipData *, int, int16 *, uint8 *, bool8, bool8 s = FALSE);
21 |
22 |
23 | static inline uint8 CalcWindowMask (int i, uint8 W1, uint8 W2)
24 | {
25 | if (!PPU.ClipWindow1Enable[i])
26 | {
27 | if (!PPU.ClipWindow2Enable[i])
28 | return (0);
29 | else
30 | {
31 | if (!PPU.ClipWindow2Inside[i])
32 | return (~W2);
33 | return (W2);
34 | }
35 | }
36 | else
37 | {
38 | if (!PPU.ClipWindow2Enable[i])
39 | {
40 | if (!PPU.ClipWindow1Inside[i])
41 | return (~W1);
42 | return (W1);
43 | }
44 | else
45 | {
46 | if (!PPU.ClipWindow1Inside[i])
47 | W1 = ~W1;
48 | if (!PPU.ClipWindow2Inside[i])
49 | W2 = ~W2;
50 |
51 | switch (PPU.ClipWindowOverlapLogic[i])
52 | {
53 | case 0: // OR
54 | return (W1 | W2);
55 |
56 | case 1: // AND
57 | return (W1 & W2);
58 |
59 | case 2: // XOR
60 | return (W1 ^ W2);
61 |
62 | case 3: // XNOR
63 | return (~(W1 ^ W2));
64 | }
65 | }
66 | }
67 |
68 | // Never get here
69 | return (0);
70 | }
71 |
72 | static inline void StoreWindowRegions (uint8 Mask, struct ClipData *Clip, int n_regions, int16 *windows, uint8 *drawing_modes, bool8 sub, bool8 StoreMode0)
73 | {
74 | int ct = 0;
75 |
76 | for (int j = 0; j < n_regions; j++)
77 | {
78 | int DrawMode = drawing_modes[j];
79 | if (sub)
80 | DrawMode |= 1;
81 | if (Mask & (1 << j))
82 | DrawMode = 0;
83 |
84 | if (!StoreMode0 && !DrawMode)
85 | continue;
86 |
87 | if (ct > 0 && Clip->Right[ct - 1] == windows[j] && Clip->DrawMode[ct - 1] == DrawMode)
88 | Clip->Right[ct - 1] = windows[j + 1]; // This region borders with and has the same drawing mode as the previous region: merge them.
89 | else
90 | {
91 | // Add a new region to the BG
92 | Clip->Left[ct] = windows[j];
93 | Clip->Right[ct] = windows[j + 1];
94 | Clip->DrawMode[ct] = DrawMode;
95 | ct++;
96 | }
97 | }
98 |
99 | Clip->Count = ct;
100 | }
101 |
102 | void S9xComputeClipWindows (void)
103 | {
104 | int16 windows[6] = { 0, 256, 256, 256, 256, 256 };
105 | uint8 drawing_modes[5] = { 0, 0, 0, 0, 0 };
106 | int n_regions = 1;
107 | int i, j;
108 |
109 | // Calculate window regions. We have at most 5 regions, because we have 6 control points
110 | // (screen edges, window 1 left & right, and window 2 left & right).
111 |
112 | if (PPU.Window1Left <= PPU.Window1Right)
113 | {
114 | if (PPU.Window1Left > 0)
115 | {
116 | windows[2] = 256;
117 | windows[1] = PPU.Window1Left;
118 | n_regions = 2;
119 | }
120 |
121 | if (PPU.Window1Right < 255)
122 | {
123 | windows[n_regions + 1] = 256;
124 | windows[n_regions] = PPU.Window1Right + 1;
125 | n_regions++;
126 | }
127 | }
128 |
129 | if (PPU.Window2Left <= PPU.Window2Right)
130 | {
131 | for (i = 0; i <= n_regions; i++)
132 | {
133 | if (PPU.Window2Left == windows[i])
134 | break;
135 |
136 | if (PPU.Window2Left < windows[i])
137 | {
138 | for (j = n_regions; j >= i; j--)
139 | windows[j + 1] = windows[j];
140 |
141 | windows[i] = PPU.Window2Left;
142 | n_regions++;
143 | break;
144 | }
145 | }
146 |
147 | for (; i <= n_regions; i++)
148 | {
149 | if (PPU.Window2Right + 1 == windows[i])
150 | break;
151 |
152 | if (PPU.Window2Right + 1 < windows[i])
153 | {
154 | for (j = n_regions; j >= i; j--)
155 | windows[j + 1] = windows[j];
156 |
157 | windows[i] = PPU.Window2Right + 1;
158 | n_regions++;
159 | break;
160 | }
161 | }
162 | }
163 |
164 | // Get a bitmap of which regions correspond to each window.
165 |
166 | uint8 W1, W2;
167 |
168 | if (PPU.Window1Left <= PPU.Window1Right)
169 | {
170 | for (i = 0; windows[i] != PPU.Window1Left; i++) ;
171 | for (j = i; windows[j] != PPU.Window1Right + 1; j++) ;
172 | W1 = region_map[i][j];
173 | }
174 | else
175 | W1 = 0;
176 |
177 | if (PPU.Window2Left <= PPU.Window2Right)
178 | {
179 | for (i = 0; windows[i] != PPU.Window2Left; i++) ;
180 | for (j = i; windows[j] != PPU.Window2Right + 1; j++) ;
181 | W2 = region_map[i][j];
182 | }
183 | else
184 | W2 = 0;
185 |
186 | // Color Window affects the drawing mode for each region.
187 | // Modes are: 3=Draw as normal, 2=clip color (math only), 1=no math (draw only), 0=nothing.
188 |
189 | uint8 CW_color = 0, CW_math = 0;
190 | uint8 CW = CalcWindowMask(5, W1, W2);
191 |
192 | switch (Memory.FillRAM[0x2130] & 0xc0)
193 | {
194 | case 0x00: CW_color = 0; break;
195 | case 0x40: CW_color = ~CW; break;
196 | case 0x80: CW_color = CW; break;
197 | case 0xc0: CW_color = 0xff; break;
198 | }
199 |
200 | switch (Memory.FillRAM[0x2130] & 0x30)
201 | {
202 | case 0x00: CW_math = 0; break;
203 | case 0x10: CW_math = ~CW; break;
204 | case 0x20: CW_math = CW; break;
205 | case 0x30: CW_math = 0xff; break;
206 | }
207 |
208 | for (i = 0; i < n_regions; i++)
209 | {
210 | if (!(CW_color & (1 << i)))
211 | drawing_modes[i] |= 1;
212 | if (!(CW_math & (1 << i)))
213 | drawing_modes[i] |= 2;
214 | }
215 |
216 | // Store backdrop clip window (draw everywhere color window allows)
217 |
218 | StoreWindowRegions(0, &IPPU.Clip[0][5], n_regions, windows, drawing_modes, FALSE, TRUE);
219 | StoreWindowRegions(0, &IPPU.Clip[1][5], n_regions, windows, drawing_modes, TRUE, TRUE);
220 |
221 | // Store per-BG and OBJ clip windows
222 |
223 | for (j = 0; j < 5; j++)
224 | {
225 | uint8 W = Settings.DisableGraphicWindows ? 0 : CalcWindowMask(j, W1, W2);
226 | for (int sub = 0; sub < 2; sub++)
227 | {
228 | if (Memory.FillRAM[sub + 0x212e] & (1 << j))
229 | StoreWindowRegions(W, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
230 | else
231 | StoreWindowRegions(0, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
232 | }
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/components/snes9x/component.mk:
--------------------------------------------------------------------------------
1 | #
2 | # "main" pseudo-component makefile.
3 | #
4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
5 |
6 | # -finstrument-functions
7 | CXXFLAGS += -O3 -fomit-frame-pointer -fno-exceptions -fno-stack-protector -mlongcalls
8 | -finline-limit=255 -fdata-sections -ffunction-sections -Wl,--gc-sections \
9 | -fno-ident -falign-functions=1 -falign-jumps=1 -falign-loops=1 \
10 | -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \
11 | -fmerge-all-constants -fno-math-errno -fno-rtti
12 |
--------------------------------------------------------------------------------
/components/snes9x/conffile.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************\
2 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 | This file is licensed under the Snes9x License.
4 | For further information, consult the LICENSE file in the root directory.
5 | \*****************************************************************************/
6 |
7 | #ifndef _CONFIG_H_
8 | #define _CONFIG_H_
9 |
10 | #include
11 | #include