gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/include/nes/nes.h
1 /** @file nes/nes.h
2 NES specific functions.
3 */
4 #ifndef _NES_H
5 #define _NES_H
6
7 #include <types.h>
8 #include <stdint.h>
9 #include <gbdk/version.h>
10 #include <nes/hardware.h>
11 #include <nes/rgb_to_nes_macro.h>
12
13 #define NINTENDO_NES
14
15 // Here NINTENDO means Game Boy & related clones
16 #ifdef NINTENDO
17 #undef NINTENDO
18 #endif
19
20 #ifdef SEGA
21 #undef SEGA
22 #endif
23
24 #ifdef MSX
25 #undef MSX
26 #endif
27
28 #define SYSTEM_BITS_NTSC 0x00
29 #define SYSTEM_BITS_PAL 0x40
30 #define SYSTEM_BITS_DENDY 0x80
31 extern const uint8_t _SYSTEM;
32
33 #define SYSTEM_60HZ 0x00
34 #define SYSTEM_50HZ 0x01
35
36 #define TIMER_VBLANK_PARITY_MODE_SYSTEM_60HZ 0x78
37 #define TIMER_VBLANK_PARITY_MODE_SYSTEM_50HZ 0x5D
38
39 #define RGB(r,g,b) RGB_TO_NES(((r) | ((g) << 2) | ((b) << 4)))
40 #define RGB8(r,g,b) RGB_TO_NES((((r) >> 6) | (((g) >> 6) << 2) | (((b) >> 6) << 4)))
41 #define RGBHTML(RGB24bit) RGB_TO_NES((((RGB24bit) >> 22) | ((((RGB24bit) & 0xFFFF) >> 14) << 2) | ((((RGB24bit) & 0xFF) >> 6) << 4)))
42
43 /** Common colors based on the EGA default palette.
44 *
45 * Manually entered from https://www.nesdev.org/wiki/PPU_palettes#RGBI
46 *
47 */
48 #define RGB_RED 0x16 // EGA12
49 #define RGB_DARKRED 0x06 // EGA4
50 #define RGB_GREEN 0x2A // EGA10
51 #define RGB_DARKGREEN 0x1A // EGA2
52 #define RGB_BLUE 0x12 // EGA9
53 #define RGB_DARKBLUE 0x02 // EGA1
54 #define RGB_YELLOW 0x28 // EGA14
55 #define RGB_DARKYELLOW 0x18 // EGA6
56 #define RGB_CYAN 0x2C // EGA11
57 #define RGB_AQUA 0x1C // EGA3
58 #define RGB_PINK 0x24 // EGA13
59 #define RGB_PURPLE 0x14 // EGA5
60 #define RGB_BLACK 0x0F // EGA0
61 #define RGB_DARKGRAY 0x00 // EGA8
62 #define RGB_LIGHTGRAY 0x10 // EGA7
63 #define RGB_WHITE 0x30 // EGA15
64
65 typedef uint8_t palette_color_t;
66
67 void set_bkg_palette(uint8_t first_palette, uint8_t nb_palettes, const palette_color_t *rgb_data) NO_OVERLAY_LOCALS;
68
69 void set_sprite_palette(uint8_t first_palette, uint8_t nb_palettes, const palette_color_t *rgb_data) NO_OVERLAY_LOCALS;
70
71 void set_bkg_palette_entry(uint8_t palette, uint8_t entry, palette_color_t rgb_data) NO_OVERLAY_LOCALS;
72
73 void set_sprite_palette_entry(uint8_t palette, uint8_t entry, palette_color_t rgb_data) NO_OVERLAY_LOCALS;
74
75 /** Joypad bits.
76 A logical OR of these is used in the wait_pad and joypad
77 functions. For example, to see if the B button is pressed
78 try
79
80 uint8_t keys;
81 keys = joypad();
82 if (keys & J_B) {
83 ...
84 }
85
86 @see joypad
87 */
88 #define J_UP 0x08U
89 #define J_DOWN 0x04U
90 #define J_LEFT 0x02U
91 #define J_RIGHT 0x01U
92 #define J_A 0x80U
93 #define J_B 0x40U
94 #define J_SELECT 0x20U
95 #define J_START 0x10U
96
97 /** Screen modes.
98 Normally used by internal functions only.
99 @see mode()
100 */
101 #define M_DRAWING 0x01U
102 #define M_TEXT_OUT 0x02U
103 #define M_TEXT_INOUT 0x03U
104 /** Set this in addition to the others to disable scrolling
105
106 If scrolling is disabled, the cursor returns to (0,0)
107 @see mode()
108 */
109 #define M_NO_SCROLL 0x04U
110 /** Set this to disable interpretation
111 @see mode()
112 */
113 #define M_NO_INTERP 0x08U
114
115 /** If this is set, sprite colours come from OBJ1PAL. Else
116 they come from OBJ0PAL
117 @see set_sprite_prop().
118 */
119 #define S_PALETTE 0x10U
120 /** If set the sprite will be flipped horizontally.
121 @see set_sprite_prop()
122 */
123 #define S_FLIPX 0x40U
124 /** If set the sprite will be flipped vertically.
125 @see set_sprite_prop()
126 */
127 #define S_FLIPY 0x80U
128 /** If this bit is clear, then the sprite will be displayed
129 on top of the background and window.
130 @see set_sprite_prop()
131 */
132 #define S_PRIORITY 0x20U
133 /** Defines how palette number is encoded in OAM.
134 Required for the png2asset tool's metasprite output.
135 */
136 #define S_PAL(n) n
137
138 /* Interrupt flags */
139 /** Disable calling of interrupt service routines
140 */
141 #define EMPTY_IFLAG 0x00U
142 /** VBlank Interrupt occurs at the start of the vertical blank.
143
144 During this period the video ram may be freely accessed.
145 @see set_interrupts(), @see add_VBL
146 */
147 #define VBL_IFLAG 0x01U
148 /** LCD Interrupt when triggered by the STAT register.
149 @see set_interrupts(), @see add_LCD
150 */
151 #define LCD_IFLAG 0x02U
152 /** Timer Interrupt when the timer @ref TIMA_REG overflows.
153 @see set_interrupts(), @see add_TIM
154 */
155 #define TIM_IFLAG 0x04U
156
157 /* DMG Palettes */
158 #define DMG_BLACK 0x03
159 #define DMG_DARK_GRAY 0x02
160 #define DMG_LITE_GRAY 0x01
161 #define DMG_WHITE 0x00
162 /** Macro to create a DMG palette from 4 colors
163
164 @param C0 Color for Index 0
165 @param C1 Color for Index 1
166 @param C2 Color for Index 2
167 @param C3 Color for Index 3
168
169 The resulting format is four greyscale colors
170 packed into a single unsigned byte.
171
172 Example:
173 \code{.c}
174 REG_BGP = DMG_PALETTE(DMG_BLACK, DMG_DARK_GRAY, DMG_LITE_GRAY, DMG_WHITE);
175 \endcode
176
177 @see OBP0_REG, OBP1_REG, BGP_REG
178 @see DMG_BLACK, DMG_DARK_GRAY, DMG_LITE_GRAY, DMG_WHITE
179
180 */
181 #define DMG_PALETTE(C0, C1, C2, C3) ((uint8_t)((((C3) & 0x03) << 6) | (((C2) & 0x03) << 4) | (((C1) & 0x03) << 2) | ((C0) & 0x03)))
182
183 /* Limits */
184 /** Width of the visible screen in pixels.
185 */
186 #define SCREENWIDTH DEVICE_SCREEN_PX_WIDTH
187 /** Height of the visible screen in pixels.
188 */
189 #define SCREENHEIGHT DEVICE_SCREEN_PX_HEIGHT
190
191 /** Interrupt handlers
192 */
193 typedef void (*int_handler)(void) NONBANKED;
194
195 /** The remove functions will remove any interrupt handler.
196
197 A handler of NULL will cause bad things
198 to happen if the given interrupt is enabled.
199
200 Removes the VBL interrupt handler. @see add_VBL()
201 */
202 void remove_VBL(int_handler h) NO_OVERLAY_LOCALS;
203
204 /** Removes the LCD interrupt handler.
205 @see add_LCD(), remove_VBL()
206 */
207 void remove_LCD(int_handler h) NO_OVERLAY_LOCALS;
208
209 /** Removes the TIM interrupt handler.
210 @see add_TIM(), remove_VBL()
211 */
212 void remove_TIM(int_handler h) NO_OVERLAY_LOCALS;
213
214 /** Adds a Vertical Blanking interrupt handler.
215
216 @param h The handler to be called whenever a V-blank
217 interrupt occurs.
218
219 Only a single handler is currently supported for NES.
220
221 __Do not__ use the function definition attributes
222 @ref CRITICAL and @ref INTERRUPT when declaring
223 ISR functions added via add_VBL() (or LCD, etc).
224 Those attributes are only required when constructing
225 a bare jump from the interrupt vector itself (such as
226 with @ref ISR_VECTOR()).
227
228 ISR handlers added using add_VBL()/etc are instead
229 called via the GBDK ISR dispatcher which makes
230 the extra function attributes unecessary.
231
232 @note The default GBDK VBL is installed automatically.
233
234 @note On the current NES implementation, this handler
235 is actually faked, and called before vblank occurs, by
236 @ref vsync(). Writes to PPU registers should be done to
237 the shadow_ versions, so they are updated by the default
238 VBL handler only when vblank actually occurs.
239
240 @see ISR_VECTOR()
241 */
242 void add_VBL(int_handler h) NO_OVERLAY_LOCALS;
243
244 /** Adds a LCD interrupt handler.
245
246 Called when the scanline matches the _lcd_scanline variables.
247
248 Only a single handler is currently supported for NES.
249
250 The use-case is to indicate to the user when the
251 video hardware is about to redraw a given LCD line.
252 This can be useful for dynamically controlling the
253 scrolling registers to perform special video effects.
254
255 __Do not__ use the function definition attributes
256 @ref CRITICAL and @ref INTERRUPT when declaring
257 ISR functions added via add_VBL() (or LCD, etc).
258 Those attributes are only required when constructing
259 a bare jump from the interrupt vector itself (such as
260 with @ref ISR_VECTOR()).
261
262 ISR handlers added using add_VBL()/etc are instead
263 called via the GBDK ISR dispatcher which makes
264 the extra function attributes unecessary.
265
266 @note On the current NES implementation, this handler
267 is actually faked, and called by the default VBL handler
268 after a manual delay loop. Only one such faked "interrupt"
269 is possible per frame.
270 This means the CPU cycles wasted in the delay loop increase
271 with higher values of _lcd_scanline. In practice, it makes
272 this functionality mostly suited for a top status bar.
273
274 @see add_VBL, nowait_int_handler, ISR_VECTOR()
275 */
276 void add_LCD(int_handler h) NO_OVERLAY_LOCALS;
277
278 /** Adds a timer interrupt handler.
279
280 Can not be used together with @ref add_low_priority_TIM
281
282 This interrupt handler is invoked at the end of the NMI handler
283 for gbdk-nes, after first processing the registers writes done
284 by the VBL and and LCD handlers.
285 It is therefore currently limited to 60Hz / 50Hz
286 (depending on system).
287
288 @note
289 Make sure to wrap TIM interrupt handlers with a nooverlay pragma.
290 For more details see @ref docs_nes_tim_overlay
291
292 @see add_VBL
293 @see set_interrupts() with TIM_IFLAG, ISR_VECTOR()
294 */
295 void add_TIM(int_handler h) NO_OVERLAY_LOCALS;
296
297 /** The maximum number of times the LCD handler will be called per frame.
298 */
299 #define MAX_LCD_ISR_CALLS 4
300
301 /** Set the current screen mode - one of M_* modes
302
303 Normally used by internal functions only.
304
305 @see M_DRAWING, M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
306 */
307 void mode(uint8_t m) NO_OVERLAY_LOCALS;
308
309 /** Returns the current mode
310
311 @see M_DRAWING, M_TEXT_OUT, M_TEXT_INOUT, M_NO_SCROLL, M_NO_INTERP
312 */
313 uint8_t get_mode(void) NO_OVERLAY_LOCALS;
314
315 /** Returns the system gbdk is running on.
316
317 */
318 inline uint8_t get_system(void) {
319 if(_SYSTEM == SYSTEM_BITS_NTSC)
320 return SYSTEM_60HZ;
321 else
322 return SYSTEM_50HZ;
323 }
324
325 /** Global Time Counter in VBL periods (60Hz)
326
327 Increments once per Frame
328
329 Will wrap around every ~18 minutes (unsigned 16 bits = 65535 / 60 / 60 = 18.2)
330 */
331 extern volatile uint16_t sys_time;
332
333 /** Tracks current active ROM bank
334
335 The active bank number is not tracked by @ref _current_bank when
336 @ref SWITCH_ROM_MBC5_8M is used.
337
338 This variable is updated automatically when you call SWITCH_ROM_MBC1 or
339 SWITCH_ROM_MBC5, SWITCH_ROM(), or call a BANKED function.
340
341 @see SWITCH_ROM_MBC1(), SWITCH_ROM_MBC5(), SWITCH_ROM()
342 */
343 extern volatile uint8_t _current_bank;
344 #define CURRENT_BANK _current_bank
345
346 /** Obtains the __bank number__ of VARNAME
347
348 @param VARNAME Name of the variable which has a __bank_VARNAME companion symbol which is adjusted by bankpack
349
350 Use this to obtain the bank number from a bank reference
351 created with @ref BANKREF().
352
353 @see BANKREF_EXTERN(), BANKREF()
354 */
355 #ifndef BANK
356 #define BANK(VARNAME) ( (uint8_t) & __bank_ ## VARNAME )
357 #endif
358
359 /** Creates a reference for retrieving the bank number of a variable or function
360
361 @param VARNAME Variable name to use, which may be an existing identifier
362
363 @see BANK() for obtaining the bank number of the included data.
364
365 More than one `BANKREF()` may be created per file, but each call should
366 always use a unique VARNAME.
367
368 Use @ref BANKREF_EXTERN() within another source file
369 to make the variable and it's data accesible there.
370 */
371 #define BANKREF(VARNAME) void __func_ ## VARNAME(void) __banked __naked { \
372 __asm \
373 .local b___func_ ## VARNAME \
374 ___bank_ ## VARNAME = b___func_ ## VARNAME \
375 .globl ___bank_ ## VARNAME \
376 __endasm; \
377 }
378
379 /** Creates extern references for accessing a BANKREF() generated variable.
380
381 @param VARNAME Name of the variable used with @ref BANKREF()
382
383 This makes a @ref BANKREF() reference in another source
384 file accessible in the current file for use with @ref BANK().
385
386 @see BANKREF(), BANK()
387 */
388 #define BANKREF_EXTERN(VARNAME) extern const void __bank_ ## VARNAME;
389
390 /** Dummy macro for no-bank-switching WIP prototype
391 @param b ROM bank to switch to
392 */
393 #define SWITCH_ROM_DUMMY(b)
394
395 /** Macro for simple UNROM-like switching (write bank# to single 8-bit register)
396 @param b ROM bank to switch to
397 */
398 #define SWITCH_ROM_UNROM(b) _switch_prg0(b)
399
400 /** Makes default mapper switch the active ROM bank
401 @param b ROM bank to switch to (max 255)
402
403 @see SWITCH_ROM_UNROM
404 */
405 #define SWITCH_ROM SWITCH_ROM_UNROM
406
407 /** No-op at the moment. Placeholder for future mappers / test compatibility.
408 @param b SRAM bank to switch to
409
410 */
411 #define SWITCH_RAM(b) 0
412
413 /** No-op at the moment. Placeholder for future mappers / test compatibility.
414
415 */
416 #define ENABLE_RAM
417
418 /** No-op at the moment. Placeholder for future mappers / test compatibility.
419
420 */
421 #define DISABLE_RAM
422
423 /** Delays the given number of milliseconds.
424 Uses no timers or interrupts, and can be called with
425 interrupts disabled
426 */
427 void delay(uint16_t d) NO_OVERLAY_LOCALS;
428
429 /** Reads and returns the current state of the joypad.
430 Return value is an OR of J_*
431
432 When testing for multiple different buttons, it's
433 best to read the joypad state *once* into a variable
434 and then test using that variable.
435
436 @see J_START, J_SELECT, J_A, J_B, J_UP, J_DOWN, J_LEFT, J_RIGHT
437 */
438 uint8_t joypad(void) NO_OVERLAY_LOCALS;
439
440 /** Waits until at least one of the buttons given in mask are pressed.
441
442 Normally only used for checking one key, but it will
443 support many, even J_LEFT at the same time as J_RIGHT. :)
444
445 @see joypad
446 @see J_START, J_SELECT, J_A, J_B, J_UP, J_DOWN, J_LEFT, J_RIGHT
447 */
448 uint8_t waitpad(uint8_t mask) NO_OVERLAY_LOCALS;
449
450 /** Waits for the directional pad and all buttons to be released.
451
452 */
453 void waitpadup(void) NO_OVERLAY_LOCALS;
454
455 /** Multiplayer joypad structure.
456
457 Must be initialized with @ref joypad_init() first then it
458 may be used to poll all avaliable joypads with @ref joypad_ex()
459 */
460 typedef struct {
461 uint8_t npads;
462 union {
463 struct {
464 uint8_t joy0, joy1, joy2, joy3;
465 };
466 uint8_t joypads[4];
467 };
468 } joypads_t;
469
470 /** Initializes joypads_t structure for polling multiple joypads
471 @param npads number of joypads requested (1, 2 or 4)
472 @param joypads pointer to joypads_t structure to be initialized
473
474 Only required for @ref joypad_ex, not required for calls to regular @ref joypad()
475 @returns number of joypads avaliable
476 @see joypad_ex(), joypads_t
477 */
478 uint8_t joypad_init(uint8_t npads, joypads_t * joypads) NO_OVERLAY_LOCALS;
479
480 /** Polls all avaliable joypads
481
482 @see joypad_init(), joypads_t
483 */
484 void joypad_ex(joypads_t * joypads) NO_OVERLAY_LOCALS;
485
486
487
488 /** Enables unmasked interrupts
489
490 @note Use @ref CRITICAL {...} instead for creating a block of
491 of code which should execute with interrupts temporarily
492 turned off.
493
494 @see disable_interrupts, set_interrupts, CRITICAL
495 */
496 inline void enable_interrupts(void) {
497 __asm__("cli");
498 }
499
500 /** Disables interrupts
501
502 @note Use @ref CRITICAL {...} instead for creating a block of
503 of code which should execute with interrupts temporarily
504 turned off.
505
506 This function may be called as many times as you like;
507 however the first call to @ref enable_interrupts will re-enable
508 them.
509
510 @see enable_interrupts, set_interrupts, CRITICAL
511 */
512 inline void disable_interrupts(void) {
513 __asm__("sei");
514 }
515
516 /** Sets the interrupt mask to flags.
517 @param flags A logical OR of *_IFLAGS
518
519 @see VBL_IFLAG, LCD_IFLAG, TIM_IFLAG
520 */
521 void set_interrupts(uint8_t flags) NO_OVERLAY_LOCALS;
522
523 /** Performs a soft reset.
524
525 For the Game Boy and related it does this by jumping to address 0x0150
526 which is in crt0.s (the c-runtime that executes before main() is called).
527
528 This performs various startup steps such as resetting the stack,
529 clearing WRAM and OAM, resetting initialized variables and some
530 display registers (scroll, window, LCDC), etc.
531
532 This is not the same a hard power reset.
533 */
534 inline void reset(void) {
535 __asm__("jmp [0xFFFC]");
536 }
537
538 /** Waits for the vertical blank interrupt.
539
540 This is often used in main loops to idle the CPU
541 until it's time to start the next frame. It's also useful for
542 syncing animation with the screen re-draw.
543
544 Warning: If the VBL interrupt is disabled, this function will
545 never return.
546 */
547 void vsync(void) NO_OVERLAY_LOCALS;
548
549 /** Obsolete. This function has been replaced by vsync(), which has identical behavior.
550 */
551 void wait_vbl_done(void) NO_OVERLAY_LOCALS;
552
553 /** Turns the display on.
554
555 @see DISPLAY_ON
556 */
557 void display_on(void) NO_OVERLAY_LOCALS;
558
559 /** Turns the display off immediately.
560 @see DISPLAY_ON
561 */
562 void display_off(void) NO_OVERLAY_LOCALS;
563
564 /** Copies data from shadow OAM to OAM
565 */
566 void refresh_OAM(void) NO_OVERLAY_LOCALS;
567
568 /** Turns the display back on.
569 @see display_off, DISPLAY_OFF
570 */
571 #define DISPLAY_ON \
572 display_on();
573
574 /** Turns the display off immediately.
575 @see display_off, DISPLAY_ON
576 */
577 #define DISPLAY_OFF \
578 display_off();
579
580 /** Blanks leftmost column, so it is not garbaged when you use horizontal scroll
581 @see SHOW_LEFT_COLUMN
582 */
583 #define HIDE_LEFT_COLUMN \
584 shadow_PPUMASK &= ~(PPUMASK_SHOW_BG_LC | PPUMASK_SHOW_SPR_LC); \
585
586 /** Shows leftmost column
587 @see HIDE_LEFT_COLUMN
588 */
589 #define SHOW_LEFT_COLUMN \
590 shadow_PPUMASK |= (PPUMASK_SHOW_BG_LC | PPUMASK_SHOW_SPR_LC);
591
592 /** Does nothing for NES
593 not implemented yet
594 */
595 #define SET_BORDER_COLOR(C)
596
597 /** Turns on the background layer.
598 Sets bit 0 of the LCDC register to 1.
599 */
600 #define SHOW_BKG \
601 shadow_PPUMASK |= PPUMASK_SHOW_BG;
602
603 /** Turns off the background layer.
604 Sets bit 0 of the LCDC register to 0.
605 */
606 #define HIDE_BKG \
607 shadow_PPUMASK &= ~PPUMASK_SHOW_BG;
608
609 /** Turns on the Window layer
610 Sets bit 5 of the LCDC register to 1.
611
612 This only controls Window visibility. If either
613 the Background layer (which the window is part of)
614 or the Display are not turned then the Window contents
615 will not be visible. Those can be turned on using
616 @ref SHOW_BKG and @ref DISPLAY_ON.
617 */
618 #define SHOW_WIN _show_window();
619
620 /** Turns off the window layer.
621 Clears bit 5 of the LCDC register to 0.
622 */
623 #define HIDE_WIN _hide_window();
624
625 /** Turns on the sprites layer.
626 Sets bit 1 of the LCDC register to 1.
627 */
628 #define SHOW_SPRITES \
629 shadow_PPUMASK |= PPUMASK_SHOW_SPR;
630
631 /** Turns off the sprites layer.
632 Clears bit 1 of the LCDC register to 0.
633 */
634 #define HIDE_SPRITES \
635 shadow_PPUMASK &= ~PPUMASK_SHOW_SPR;
636
637 /** Sets sprite size to 8x16 pixels, two tiles one above the other.
638 Sets bit 2 of the LCDC register to 1.
639 */
640 #define SPRITES_8x16 \
641 shadow_PPUCTRL |= PPUCTRL_SPR_8X16;
642
643 /** Sets sprite size to 8x8 pixels, one tile.
644 Clears bit 2 of the LCDC register to 0.
645 */
646 #define SPRITES_8x8 \
647 shadow_PPUCTRL &= ~PPUCTRL_SPR_8X16;
648
649 /** Macro returns TRUE if device supports color
650 * (it always does on NES)
651 */
652 #define DEVICE_SUPPORTS_COLOR (TRUE)
653
654 /** Macro returns TRUE if device supports window layer
655 */
656 #ifdef NES_WINDOW_LAYER
657 #define DEVICE_SUPPORTS_WINDOW (TRUE)
658 #else
659 #define DEVICE_SUPPORTS_WINDOW (FALSE)
660 #endif
661
662 /** Macro returns TRUE if device supports reading from VRAM
663 */
664 #define DEVICE_SUPPORTS_VRAM_READ (FALSE)
665
666 /**
667 * Set byte in vram at given memory location
668 *
669 * @param addr address to write to
670 * @param v value
671 */
672 void set_vram_byte(uint8_t * addr, uint8_t v) NO_OVERLAY_LOCALS;
673
674 /**
675 * Get address of X,Y tile of background map
676 */
677 uint8_t * get_bkg_xy_addr(uint8_t x, uint8_t y) NO_OVERLAY_LOCALS;
678
679 #define COMPAT_PALETTE(C0,C1,C2,C3) ((uint8_t)(((C3) << 6) | ((C2) << 4) | ((C1) << 2) | (C0)))
680
681 /** Sets palette for 2bpp color translation for GG/SMS, does nothing on GB
682 */
683 inline void set_2bpp_palette(uint16_t palette) {
684 palette;
685 }
686
687 extern uint16_t _current_1bpp_colors;
688 void set_1bpp_colors_ex(uint8_t fgcolor, uint8_t bgcolor, uint8_t mode) NO_OVERLAY_LOCALS;
689 inline void set_1bpp_colors(uint8_t fgcolor, uint8_t bgcolor) {
690 set_1bpp_colors_ex(fgcolor, bgcolor, 0);
691 }
692
693 /** Sets VRAM Tile Pattern data for the Background
694
695 Writes __nb_tiles__ tiles to VRAM starting at __first_tile__, tile data
696 is sourced from __data__. Each Tile is 16 bytes in size (8x8 pixels, 2 bits-per-pixel).
697
698 Note: Sprite Tiles 128-255 share the same memory region as Background Tiles 128-255.
699
700 @see set_tile_data
701 */
702 void set_bkg_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
703 #define set_bkg_2bpp_data set_bkg_data
704
705 /** Sets VRAM Tile Pattern data for the Background using 1bpp source data
706
707 Similar to @ref set_bkg_data, except source data is 1 bit-per-pixel
708 which gets expanded into 2 bits-per-pixel.
709
710 For a given bit that represent a pixel:
711 \li 0 will be expanded into color 0
712 \li 1 will be expanded into color 1, 2 or 3 depending on color argument
713
714 @see SHOW_BKG, HIDE_BKG, set_bkg_tiles
715 */
716 void set_bkg_1bpp_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
717
718 /** Sets a rectangular region of Background Tile Map.
719
720 Entries are copied from map at __tiles__ to the Background Tile Map starting at
721 __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
722
723 Use @ref set_bkg_submap() instead when:
724 \li Source map is wider than 32 tiles.
725 \li Writing a width that does not match the source map width __and__ more
726 than one row high at a time.
727
728 One byte per source tile map entry.
729
730 Writes that exceed coordinate 31 on the x or y axis will wrap around to
731 the Left and Top edges.
732
733 @see SHOW_BKG
734 @see set_bkg_data, set_bkg_submap, set_win_tiles, set_tiles
735 */
736 void set_bkg_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles) NO_OVERLAY_LOCALS;
737 #define set_tile_map set_bkg_tiles
738
739 /** Sets a rectangular region of Background Tile Map Attributes.
740
741 @param x X Start position in Background Map tile coordinates. Range 0 - 15
742 @param y Y Start position in Background Map tile coordinates. Range 0 - 14
743 @param w Width of area to set in tiles. Range 1 - 16
744 @param h Height of area to set in tiles. Range 1 - 15
745 @param attributes Pointer to source tile map attribute data
746
747 Entries are copied from map at __tiles__ to the Background Tile Map starting at
748 __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
749
750 NES 16x16 Tile Attributes are tightly packed into 4 attributes per byte,
751 with each 16x16 area of a 32x32 pixel block using the bits as follows:
752 D1-D0: Top-left 16x16 pixels
753 D3-D2: Top-right 16x16 pixels
754 D5-D4: Bottom-left 16x16 pixels
755 D7-D6: Bottom-right 16x16 pixels
756
757 https://www.nesdev.org/wiki/PPU_attribute_tables
758
759 @see SHOW_BKG
760 @see set_bkg_data, set_bkg_submap_attributes, set_win_tiles, set_tiles
761 */
762 void set_bkg_attributes_nes16x16(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *attributes) NO_OVERLAY_LOCALS;
763
764 /** Sets a rectangular region of Background Tile Map Attributes.
765
766 Entries are copied from map at __tiles__ to the Background Tile Map starting at
767 __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
768
769 Use @ref set_bkg_submap_attributes() instead when:
770 \li Source map is wider than 32 tiles.
771 \li Writing a width that does not match the source map width __and__ more
772 than one row high at a time.
773
774 One byte per source tile map attribute entry.
775
776 Writes that exceed coordinate 31 on the x or y axis will wrap around to
777 the Left and Top edges.
778
779 Please note that this is just a wrapper function for set_bkg_attributes_nes16x16()
780 and divides the coordinates and dimensions by 2 to achieve this.
781 It is intended to make code more portable by using the same coordinate system
782 that systems with the much more common 8x8 attribute resolution would use.
783
784 @see SHOW_BKG
785 @see set_bkg_data, set_bkg_submap_attributes, set_win_tiles, set_tiles
786 */
787 inline void set_bkg_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *attributes)
788 {
789 set_bkg_attributes_nes16x16(x >> 1, y >> 1, (w + 1) >> 1, (h + 1) >> 1, attributes);
790 }
791 /** Sets a rectangular area of the Background Tile Map using a sub-region
792 from a source tile map. Useful for scrolling implementations of maps
793 larger than 32 x 30 tiles / 16x15 attributes.
794
795 @param x X Start position in both the Source Attribute Map and hardware Background Map attribute coordinates. Range 0 - 255
796 @param y Y Start position in both the Source Attribute Map and hardware Background Map attribute coordinates. Range 0 - 255
797 @param w Width of area to set in Attributes. Range 1 - 127
798 @param h Height of area to set in Attributes. Range 1 - 127
799 @param map Pointer to source tile map data
800 @param map_w Width of source tile map in tiles. Range 1 - 127
801
802 Entries are copied from __map__ to the Background Attribute Map starting at
803 __x__, __y__ writing across for __w__ tiles and down for __h__ attributes,
804 using __map_w__ as the rowstride for the source attribute map.
805
806 The __x__ and __y__ parameters are in Source Attribute Map Attribute
807 coordinates. The location tiles will be written to on the
808 hardware Background Map is derived from those, but only uses
809 the lower 5 bits of each axis, for range of 0-15 (they are
810 bit-masked: `x & 0xF` and `y & 0xF`). As a result the two
811 coordinate systems are aligned together.
812
813 In order to transfer tile map data in a way where the
814 coordinate systems are not aligned, an offset from the
815 Source Attribute Map pointer can be passed in:
816 `(map_ptr + x + (y * map_width))`.
817
818 For example, if you want the tile id at `1,2` from the source map to
819 show up at `0,0` on the hardware Background Map (instead of at `1,2`)
820 then modify the pointer address that is passed in:
821 `map_ptr + 1 + (2 * map_width)`
822
823 Use this instead of @ref set_bkg_tiles when the source map is wider than
824 32 tiles or when writing a width that does not match the source map width.
825
826 One byte per source attribute map entry.
827
828 Writes that exceed coordinate 15/14 on the x / y axis will wrap around to
829 the Left and Top edges.
830
831 See @ref set_bkg_tiles for setting CGB attribute maps with @ref VBK_REG.
832
833 @see SHOW_BKG
834 @see set_bkg_data, set_bkg_tiles, set_win_submap, set_tiles
835 */
836 void set_bkg_submap_attributes_nes16x16(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) NO_OVERLAY_LOCALS;
837
838 /** Sets a rectangular area of the Background Tile Map attributes using
839 a sub-region from a source tile map. Useful for scrolling implementations
840 of maps larger than 32 x 30 tiles.
841
842 Please note that this is just a wrapper function for set_bkg_submap_attributes_nes16x16()
843 and divides the coordinates and dimensions by 2 to achieve this.
844 It is intended to make code more portable by using the same coordinate system
845 that systems with the much more common 8x8 attribute resolution would use.
846
847 @see SHOW_BKG
848 @see set_bkg_data, set_bkg_tiles, set_win_submap, set_tiles
849 */
850 inline void set_bkg_submap_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *attributes, uint8_t map_w)
851 {
852 set_bkg_submap_attributes_nes16x16(x >> 1, y >> 1, (w + 1) >> 1, (h + 1) >> 1, attributes, (map_w + 1) >> 1);
853 }
854
855
856 /** Sets a rectangular region of Background Tile Map.
857 The offset value in __base_tile__ is added to
858 the tile ID for each map entry.
859
860 @param x X Start position in Background Map tile coordinates. Range 0 - 31
861 @param y Y Start position in Background Map tile coordinates. Range 0 - 31
862 @param w Width of area to set in tiles. Range 1 - 32
863 @param h Height of area to set in tiles. Range 1 - 32
864 @param tiles Pointer to source tile map data
865 @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
866
867 This is identical to @ref set_bkg_tiles() except that it
868 adds the __base_tile__ parameter for when a tile map's tiles don't
869 start at index zero. (For example, the tiles used by the map
870 range from 100 -> 120 in VRAM instead of 0 -> 20).
871
872 @see set_bkg_tiles for more details
873 */
874 void set_bkg_based_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles, uint8_t base_tile) NO_OVERLAY_LOCALS;
875
876
877 /** Sets a rectangular area of the Background Tile Map using a sub-region
878 from a source tile map. Useful for scrolling implementations of maps
879 larger than 32 x 32 tiles.
880
881 @ param x X Start position in Background Map tile coordinates. Range 0 - 31
882 @ param y Y Start position in Background Map tile coordinates. Range 0 - 31
883 @ param w Width of area to set in tiles. Range 1 - 255
884 @ param h Height of area to set in tiles. Range 1 - 255
885 @ param map Pointer to source tile map data
886 @ param map_w Width of source tile map in tiles. Range 1 - 255
887
888 Entries are copied from __map__ to the Background Tile Map starting at
889 __x__, __y__ writing across for __w__ tiles and down for __h__ tiles,
890 using __map_w__ as the rowstride for the source tile map.
891
892 Use this instead of @ref set_bkg_tiles when the source map is wider than
893 32 tiles or when writing a width that does not match the source map width.
894
895 One byte per source tile map entry.
896
897 Writes that exceed coordinate 31 on the x or y axis will wrap around to
898 the Left and Top edges.
899
900 See @ref set_bkg_tiles for setting CGB attribute maps with @ref VBK_REG.
901
902 @see SHOW_BKG
903 @see set_bkg_data, set_bkg_tiles, set_win_submap, set_tiles
904 */
905 void set_bkg_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w) NO_OVERLAY_LOCALS;
906 #define set_tile_submap set_bkg_submap
907
908
909 /** Sets a rectangular area of the Background Tile Map using a sub-region
910 from a source tile map. The offset value in __base_tile__ is added to
911 the tile ID for each map entry.
912
913 @param x X Start position in Background Map tile coordinates. Range 0 - 31
914 @param y Y Start position in Background Map tile coordinates. Range 0 - 31
915 @param w Width of area to set in tiles. Range 1 - 255
916 @param h Height of area to set in tiles. Range 1 - 255
917 @param map Pointer to source tile map data
918 @param map_w Width of source tile map in tiles. Range 1 - 255
919 @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
920
921 This is identical to @ref set_bkg_submap() except that it
922 adds the __base_tile__ parameter for when a tile map's tiles don't
923 start at index zero. (For example, the tiles used by the map
924 range from 100 -> 120 in VRAM instead of 0 -> 20).
925
926 @see set_bkg_submap for more details
927 */
928 void set_bkg_based_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w, uint8_t base_tile) NO_OVERLAY_LOCALS;
929
930
931 /** Copies a rectangular region of Background Tile Map entries into a buffer.
932
933 Entries are copied into __tiles__ from the Background Tile Map starting at
934 __x__, __y__ reading across for __w__ tiles and down for __h__ tiles.
935
936 One byte per tile.
937
938 The buffer pointed to by __tiles__ should be at least __x__ x __y__ bytes in size.
939
940 @see get_bkg_tile_xy, get_tiles
941 */
942 void get_bkg_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t *tiles) NO_OVERLAY_LOCALS;
943
944
945 /**
946 * Set single tile t on background layer at x,y
947 * @param x X-coordinate
948 * @param y Y-coordinate
949 * @param t tile index
950 * @return returns the address of tile, so you may use faster set_vram_byte() later
951 */
952 uint8_t * set_bkg_tile_xy(uint8_t x, uint8_t y, uint8_t t) NO_OVERLAY_LOCALS;
953 #define set_tile_xy set_bkg_tile_xy
954
955 /**
956 Set single 2x2 tile attribute a on background layer at x,y
957
958 @param x X-coordinate
959 @param y Y-coordinate
960 @param a tile attributes
961 */
962 void set_bkg_attribute_xy_nes16x16(uint8_t x, uint8_t y, uint8_t a) NO_OVERLAY_LOCALS;
963
964 /**
965 Set single attribute data a on window layer at x,y
966
967 @param x X-coordinate
968 @param y Y-coordinate
969 @param a tile attributes
970 */
971 void set_win_attribute_xy_nes16x16(uint8_t x, uint8_t y, uint8_t a) NO_OVERLAY_LOCALS;
972
973 /**
974 Set single 2x2 tile attribute a on background layer at x,y
975
976 Please note that this is just a wrapper function for set_bkg_submap_attributes_nes16x16()
977 and divides the coordinates and dimensions by 2 to achieve this.
978 It is intended to make code more portable by using the same coordinate system
979 that systems with the much more common 8x8 attribute resolution would use.
980
981 @param x X-coordinate
982 @param y Y-coordinate
983 @param a tile attributes
984 */
985 inline void set_bkg_attribute_xy(uint8_t x, uint8_t y, uint8_t a)
986 {
987 set_bkg_attribute_xy_nes16x16(x >> 1, y >> 1, a);
988 }
989 #define set_attribute_xy set_bkg_attribute_xy
990
991 /** Set single attribute data a on window layer at x,y
992
993 Please note that this is just a wrapper function for set_win_attribute_xy_nes16x16()
994 and divides the coordinates and dimensions by 2 to achieve this.
995 It is intended to make code more portable by using the same coordinate system
996 that systems with the much more common 8x8 attribute resolution would use.
997
998 @param x X-coordinate
999 @param y Y-coordinate
1000 @param a tile attributes
1001 @return returns the address of tile attribute, so you may use faster set_vram_byte() later
1002
1003 @note On the Game Boy this is only usable in Game Boy Color mode
1004 */
1005 inline uint8_t * set_win_attribute_xy(uint8_t x, uint8_t y, uint8_t a)
1006 {
1007 set_win_attribute_xy_nes16x16(x >> 1, y >> 1, a);
1008 return NULL;
1009 }
1010
1011 /**
1012 * Get single tile t on background layer at x,y
1013 * @param x X-coordinate
1014 * @param y Y-coordinate
1015 * @return returns tile index
1016 */
1017 uint8_t get_bkg_tile_xy(uint8_t x, uint8_t y) NO_OVERLAY_LOCALS;
1018
1019
1020 /** Moves the Background Layer to the position specified in __x__ and __y__ in pixels.
1021
1022 @param x X axis screen coordinate for Left edge of the Background
1023 @param y Y axis screen coordinate for Top edge of the Background
1024
1025 0,0 is the top left corner of the GB screen. The Background Layer wraps around the screen,
1026 so when part of it goes off the screen it appears on the opposite side (factoring in the
1027 larger size of the Background Layer versus the screen size).
1028
1029 The background layer is always under the Window Layer.
1030
1031 @see SHOW_BKG, HIDE_BKG
1032 */
1033 inline void move_bkg(scroll_x_t x, scroll_y_t y) {
1034 // store low 8 bits to shadow scroll registers
1035 bkg_scroll_x = (uint8_t)x;
1036 bkg_scroll_y = (uint8_t)(y >= 240 ? (y - 240) : y);
1037 // store 9th bit of x and y in shadow PPUCTRL register
1038 #if DEVICE_SCREEN_BUFFER_WIDTH > 32 && DEVICE_SCREEN_BUFFER_HEIGHT > 30
1039 uint8_t msb_x = (uint8_t)((x >> 8) & 1);
1040 uint8_t msb_y = (uint8_t)(y >= 240 ? 1 : 0);
1041 shadow_PPUCTRL = (shadow_PPUCTRL & 0xFC) | (msb_y << 1) | msb_x;
1042 #elif DEVICE_SCREEN_BUFFER_WIDTH > 32
1043 uint8_t msb_x = (uint8_t)((x >> 8) & 1);
1044 shadow_PPUCTRL = (shadow_PPUCTRL & 0xFC) | msb_x;
1045 #elif DEVICE_SCREEN_BUFFER_HEIGHT > 30
1046 uint8_t msb_y = (uint8_t)(y >= 240 ? 1 : 0);
1047 shadow_PPUCTRL = (shadow_PPUCTRL & 0xFC) | (msb_y << 1);
1048 #endif
1049 }
1050
1051
1052 /** Moves the Background relative to it's current position.
1053
1054 @param x Number of pixels to move the Background on the __X axis__
1055 \n Range: -128 - 127
1056 @param y Number of pixels to move the Background on the __Y axis__
1057 \n Range: -128 - 127
1058
1059 @see move_bkg
1060 */
1061 inline void scroll_bkg(int8_t x, int8_t y) {
1062 move_bkg(bkg_scroll_x + x, bkg_scroll_y + y);
1063 }
1064
1065 /**
1066 * Get address of X,Y tile of window map
1067 */
1068 #if defined(NES_WINDOW_LAYER)
1069 uint8_t * get_win_xy_addr(uint8_t x, uint8_t y) NO_OVERLAY_LOCALS;
1070 #else
1071 #define get_win_xy_addr get_bkg_xy_addr
1072 #endif
1073
1074 /** Sets VRAM Tile Pattern data for the Window / Background
1075
1076 @param first_tile Index of the first tile to write
1077 @param nb_tiles Number of tiles to write
1078 @param data Pointer to (2 bpp) source Tile Pattern data.
1079
1080 This is the same as @ref set_bkg_data, since the Window Layer and
1081 Background Layer share the same Tile pattern data.
1082
1083 @see set_bkg_data
1084 @see set_win_tiles, set_bkg_data, set_data
1085 @see SHOW_WIN, HIDE_WIN
1086 */
1087 #if defined(NES_WINDOW_LAYER)
1088 void set_win_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
1089 #else
1090 #define set_win_data set_bkg_data
1091 #endif
1092
1093 /** Sets VRAM Tile Pattern data for the Window / Background using 1bpp source data
1094
1095 @param first_tile Index of the first tile to write
1096 @param nb_tiles Number of tiles to write
1097 @param data Pointer to (1bpp) source Tile Pattern data
1098
1099 This is the same as @ref set_bkg_1bpp_data, since the Window Layer and
1100 Background Layer share the same Tile pattern data.
1101
1102 For a given bit that represent a pixel:
1103 \li 0 will be expanded into the Background color
1104 \li 1 will be expanded into the Foreground color
1105
1106 See @ref set_1bpp_colors for details about setting the Foreground and Background colors.
1107
1108 @see set_bkg_data, set_win_data, set_1bpp_colors
1109 @see set_bkg_1bpp_data, set_sprite_1bpp_data
1110 */
1111 #if defined(NES_WINDOW_LAYER)
1112 void set_win_1bpp_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
1113 #else
1114 #define set_win_1bpp_data set_bkg_1bpp_data
1115 #endif
1116
1117 /** Sets a rectangular region of the Window Tile Map.
1118
1119 @param x X Start position in Window Map tile coordinates. Range 0 - 31
1120 @param y Y Start position in Window Map tile coordinates. Range 0 - 31
1121 @param w Width of area to set in tiles. Range 1 - 32
1122 @param h Height of area to set in tiles. Range 1 - 32
1123 @param tiles Pointer to source tile map data
1124
1125 Entries are copied from map at __tiles__ to the Window Tile Map starting at
1126 __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
1127
1128 Use @ref set_win_submap() instead when:
1129 \li Source map is wider than 32 tiles.
1130 \li Writing a width that does not match the source map width __and__ more
1131 than one row high at a time.
1132
1133 One byte per source tile map entry.
1134
1135 Writes that exceed coordinate 31 on the x or y axis will wrap around to
1136 the Left and Top edges.
1137
1138 @note Patterns 128-255 overlap with patterns 128-255 of the sprite Tile Pattern table.
1139
1140 GBC only: @ref VBK_REG determines whether Tile Numbers or Tile Attributes get set.
1141 \li VBK_REG = @ref VBK_TILES Tile Numbers are written
1142 \li VBK_REG = @ref VBK_ATTRIBUTES Tile Attributes are written
1143
1144 For more details about GBC Tile Attributes see @ref set_bkg_tiles.
1145
1146 @see SHOW_WIN, HIDE_WIN, set_win_submap, set_bkg_tiles, set_bkg_data, set_tiles
1147 */
1148 #if defined(NES_WINDOW_LAYER)
1149 void set_win_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles) NO_OVERLAY_LOCALS;
1150 #else
1151 #define set_win_tiles set_bkg_tiles
1152 #endif
1153
1154 /** Sets a rectangular region of the Window Tile Map.
1155 The offset value in __base_tile__ is added to
1156 the tile ID for each map entry.
1157
1158 @param x X Start position in Window Map tile coordinates. Range 0 - 31
1159 @param y Y Start position in Window Map tile coordinates. Range 0 - 31
1160 @param w Width of area to set in tiles. Range 1 - 32
1161 @param h Height of area to set in tiles. Range 1 - 32
1162 @param tiles Pointer to source tile map data
1163 @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
1164
1165 This is identical to @ref set_win_tiles() except that it
1166 adds the __base_tile__ parameter for when a tile map's tiles don't
1167 start at index zero. (For example, the tiles used by the map
1168 range from 100 -> 120 in VRAM instead of 0 -> 20).
1169
1170 @see set_win_tiles for more details
1171 */
1172 #if defined(NES_WINDOW_LAYER)
1173 void set_win_based_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *tiles, uint8_t base_tile) NO_OVERLAY_LOCALS;
1174 #else
1175 #define set_win_based_tiles set_bkg_based_tiles
1176 #endif
1177
1178 /** Sets a rectangular area of the Window Tile Map using a sub-region
1179 from a source tile map.
1180
1181 @param x X Start position in both the Source Tile Map and hardware Window Map tile coordinates. Range 0 - 255
1182 @param y Y Start position in both the Source Tile Map and hardware Window Map tile coordinates. Range 0 - 255
1183 @param w Width of area to set in tiles. Range 1 - 255
1184 @param h Height of area to set in tiles. Range 1 - 255
1185 @param map Pointer to source tile map data
1186 @param map_w Width of source tile map in tiles. Range 1 - 255
1187
1188 Entries are copied from __map__ to the Window Tile Map starting at
1189 __x__, __y__ writing across for __w__ tiles and down for __h__ tiles,
1190 using __map_w__ as the rowstride for the source tile map.
1191
1192 The __x__ and __y__ parameters are in Source Tile Map tile
1193 coordinates. The location tiles will be written to on the
1194 hardware Background Map is derived from those, but only uses
1195 the lower 5 bits of each axis, for range of 0-31 (they are
1196 bit-masked: `x & 0x1F` and `y & 0x1F`). As a result the two
1197 coordinate systems are aligned together.
1198
1199 In order to transfer tile map data in a way where the
1200 coordinate systems are not aligned, an offset from the
1201 Source Tile Map pointer can be passed in:
1202 `(map_ptr + x + (y * map_width))`.
1203
1204 For example, if you want the tile id at `1,2` from the source map to
1205 show up at `0,0` on the hardware Background Map (instead of at `1,2`)
1206 then modify the pointer address that is passed in:
1207 `map_ptr + 1 + (2 * map_width)`
1208
1209 Use this instead of @ref set_win_tiles when the source map is wider than
1210 32 tiles or when writing a width that does not match the source map width.
1211
1212 One byte per source tile map entry.
1213
1214 Writes that exceed coordinate 31 on the x or y axis will wrap around to
1215 the Left and Top edges.
1216
1217 GBC only: @ref VBK_REG determines whether Tile Numbers or Tile Attributes get set.
1218 \li VBK_REG = @ref VBK_TILES Tile Numbers are written
1219 \li VBK_REG = @ref VBK_ATTRIBUTES Tile Attributes are written
1220
1221 See @ref set_bkg_tiles for details about CGB attribute maps with @ref VBK_REG.
1222
1223 @see SHOW_WIN, HIDE_WIN, set_win_tiles, set_bkg_submap, set_bkg_tiles, set_bkg_data, set_tiles
1224 **/
1225 #if defined(NES_WINDOW_LAYER)
1226 void set_win_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w);
1227 #else
1228 #define set_win_submap set_bkg_submap
1229 #endif
1230
1231 /** Sets a rectangular area of the Window Tile Map using a sub-region
1232 from a source tile map. The offset value in __base_tile__ is added
1233 to the tile ID for each map entry.
1234
1235 @param x X Start position in both the Source Tile Map and hardware Window Map tile coordinates. Range 0 - 255
1236 @param y Y Start position in both the Source Tile Map and hardware Window Map tile coordinates. Range 0 - 255
1237 @param w Width of area to set in tiles. Range 1 - 255
1238 @param h Height of area to set in tiles. Range 1 - 255
1239 @param map Pointer to source tile map data
1240 @param map_w Width of source tile map in tiles. Range 1 - 255
1241 @param base_tile Offset each tile ID entry of the source map by this value. Range 1 - 255
1242
1243 This is identical to @ref set_win_submap() except that it
1244 adds the __base_tile__ parameter for when a tile map's tiles don't
1245 start at index zero. (For example, the tiles used by the map
1246 range from 100 -> 120 in VRAM instead of 0 -> 20).
1247
1248 @see set_win_submap for more details
1249 **/
1250 #if defined(NES_WINDOW_LAYER)
1251 void set_win_based_submap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t map_w, uint8_t base_tile) NO_OVERLAY_LOCALS;
1252 #else
1253 #define set_win_based_submap set_bkg_based_submap
1254 #endif
1255
1256 /** Sets a rectangular area of the Window Tile Map attributes using
1257 a sub-region from a source tile map. Useful for scrolling implementations
1258 of maps larger than 32 x 30 tiles.
1259
1260 @see SHOW_BKG
1261 @see set_win_data, set_win_tiles, set_bkg_submap, set_tiles
1262 */
1263 #if defined(NES_WINDOW_LAYER)
1264 void set_win_submap_attributes_nes16x16(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *attributes, uint8_t map_w) NO_OVERLAY_LOCALS;
1265 #else
1266 #define set_win_submap_attributes_nes16x16 set_bkg_submap_attributes_nes16x16
1267 #endif
1268
1269 /** Sets a rectangular area of the Window Tile Map attributes using
1270 a sub-region from a source tile map. Useful for scrolling implementations
1271 of maps larger than 32 x 30 tiles.
1272
1273 Please note that this is just a wrapper function for set_win_submap_attributes_nes16x16()
1274 and divides the coordinates and dimensions by 2 to achieve this.
1275 It is intended to make code more portable by using the same coordinate system
1276 that systems with the much more common 8x8 attribute resolution would use.
1277
1278 @see SHOW_BKG
1279 @see set_win_data, set_win_tiles, set_bkg_submap, set_tiles
1280 */
1281 #if defined(NES_WINDOW_LAYER)
1282 inline void set_win_submap_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *attributes, uint8_t map_w)
1283 {
1284 set_win_submap_attributes_nes16x16(x >> 1, y >> 1, (w + 1) >> 1, (h + 1) >> 1, attributes, (map_w + 1) >> 1);
1285 }
1286 #else
1287 #define set_win_submap_attributes set_bkg_submap_attributes
1288 #endif
1289
1290 /**
1291 * Set single tile t on window layer at x,y
1292 * @param x X-coordinate
1293 * @param y Y-coordinate
1294 * @param t tile index
1295 * @return returns the address of tile, so you may use faster set_vram_byte() later
1296 */
1297 #if defined(NES_WINDOW_LAYER)
1298 uint8_t * set_win_tile_xy(uint8_t x, uint8_t y, uint8_t t) NO_OVERLAY_LOCALS;
1299 #else
1300 #define set_win_tile_xy set_bkg_tile_xy
1301 #endif
1302
1303 /** Moves the Window to the __x__, __y__ position on the screen.
1304
1305 @param x X coordinate for Left edge of the Window (actual displayed location will be X - 7)
1306 @param y Y coordinate for Top edge of the Window
1307
1308 7,0 is the top left corner of the screen in Window coordinates. The Window is locked to the bottom right corner.
1309
1310 The Window is always over the Background layer.
1311
1312 @see SHOW_WIN, HIDE_WIN
1313 */
1314 #if defined(NES_WINDOW_LAYER)
1315 inline void move_win(scroll_x_t x, scroll_y_t y) {
1316 WX_REG=x, WY_REG=y;
1317 }
1318 #else
1319 #define move_win move_bkg
1320 #endif
1321
1322
1323 /** Move the Window relative to its current position.
1324
1325 @param x Number of pixels to move the window on the __X axis__
1326 \n Range: -128 - 127
1327 @param y Number of pixels to move the window on the __Y axis__
1328 \n Range: -128 - 127
1329
1330 @see move_win
1331 */
1332 #if defined(NES_WINDOW_LAYER)
1333 inline void scroll_win(int8_t x, int8_t y) {
1334 WX_REG+=x, WY_REG+=y;
1335 }
1336 #else
1337 #define scroll_win scroll_bkg
1338 #endif
1339
1340 /** Sets VRAM Tile Pattern data for Sprites
1341
1342 Writes __nb_tiles__ tiles to VRAM starting at __first_tile__, tile data
1343 is sourced from __data__. Each Tile is 16 bytes in size (8x8 pixels, 2 bits-per-pixel).
1344
1345 Note: Sprite Tiles 128-255 share the same memory region as Background Tiles 128-255.
1346
1347 GBC only: @ref VBK_REG determines which bank of tile patterns are written to.
1348 \li VBK_REG=0 indicates the first bank
1349 \li VBK_REG=1 indicates the second
1350 */
1351 void set_sprite_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
1352 #define set_sprite_2bpp_data set_sprite_data
1353
1354 /** Sets VRAM Tile Pattern data for Sprites using 1bpp source data
1355
1356 Similar to @ref set_sprite_data, except source data is 1 bit-per-pixel
1357 which gets expanded into 2 bits-per-pixel.
1358
1359 For a given bit that represent a pixel:
1360 \li 0 will be expanded into color 0
1361 \li 1 will be expanded into color 3
1362
1363 @see SHOW_SPRITES, HIDE_SPRITES, set_sprite_tile
1364 */
1365 void set_sprite_1bpp_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
1366
1367 /** Sprite Attributes structure
1368 @param x X Coordinate of the sprite on screen
1369 @param y Y Coordinate of the sprite on screen - 1
1370 @param tile Sprite tile number (see @ref set_sprite_tile)
1371 @param prop OAM Property Flags (see @ref set_sprite_prop)
1372 */
1373 typedef struct OAM_item_t {
1374 uint8_t y; //< Y coordinate of the sprite on screen - 1
1375 uint8_t tile; //< Sprite tile number
1376 uint8_t prop; //< OAM Property Flags
1377 uint8_t x; //< X coordinate of the sprite on screen
1378 } OAM_item_t;
1379
1380
1381 /** Shadow OAM array in WRAM, that is DMA-transferred into the real OAM each VBlank
1382 */
1383 extern volatile struct OAM_item_t shadow_OAM[];
1384
1385 /** MSB of shadow_OAM address is used by OAM DMA copying routine
1386 */
1387 extern uint8_t _shadow_OAM_base;
1388
1389 #define DISABLE_OAM_DMA \
1390 _shadow_OAM_base = 0
1391
1392 /** Disable OAM DMA copy each VBlank
1393 */
1394 #define DISABLE_VBL_TRANSFER DISABLE_OAM_DMA
1395
1396 #define ENABLE_OAM_DMA \
1397 _shadow_OAM_base = (uint8_t)((uint16_t)&shadow_OAM >> 8)
1398
1399 /** Enable OAM DMA copy each VBlank and set it to transfer default shadow_OAM array
1400 */
1401 #define ENABLE_VBL_TRANSFER ENABLE_OAM_DMA
1402
1403 /** Amount of hardware sprites in OAM
1404 */
1405 #define MAX_HARDWARE_SPRITES 64
1406
1407 /** True if sprite hardware can flip sprites by X (horizontally)
1408 */
1409 #define HARDWARE_SPRITE_CAN_FLIP_X 1
1410
1411 /** True if sprite hardware can flip sprites by Y (vertically)
1412 */
1413 #define HARDWARE_SPRITE_CAN_FLIP_Y 1
1414
1415 /** Enable OAM DMA copy each VBlank and set it to transfer any 256-byte aligned array
1416 */
1417 inline void SET_SHADOW_OAM_ADDRESS(void * address) {
1418 _shadow_OAM_base = (uint8_t)((uint16_t)address >> 8);
1419 }
1420
1421 /** Sets sprite number __nb__in the OAM to display tile number __tile__.
1422
1423 @param nb Sprite number, range 0 - 63
1424 @param tile Selects a tile (0 - 255) from PPU memory at 0000h - 0FFFh / 1000h - 1FFFh
1425
1426 In 8x16 mode:
1427 \li The sprite will also display the next tile (__tile__ + 1)
1428 directly below (y + 8) the first tile.
1429 \li The lower bit of the tile number is ignored:
1430 the upper 8x8 tile is (__tile__ & 0xFE), and
1431 the lower 8x8 tile is (__tile__ | 0x01).
1432 \li See: @ref SPRITES_8x16
1433 */
1434 void set_sprite_tile(uint8_t nb, uint8_t tile) NO_OVERLAY_LOCALS;
1435
1436
1437 /** Returns the tile number of sprite number __nb__ in the OAM.
1438
1439 @param nb Sprite number, range 0 - 63
1440
1441 @see set_sprite_tile for more details
1442 */
1443 uint8_t get_sprite_tile(uint8_t nb) NO_OVERLAY_LOCALS;
1444
1445
1446 /** Sets the OAM Property Flags of sprite number __nb__ to those defined in __prop__.
1447
1448 @param nb Sprite number, range 0 - 39
1449 @param prop Property setting (see bitfield description)
1450
1451 The bits in __prop__ represent:
1452 \li Bit 7 - Vertical flip. Dictates which way up the sprite is drawn
1453 vertically.
1454 \n 0: normal
1455 \n 1: upside down
1456 \li Bit 6 - Horizontal flip. Dictates which way up the sprite is
1457 drawn horizontally.
1458 \n 0: normal
1459 \n 1: back to front
1460 \li Bit 5 - Priority flag. When this is set, the sprites appear behind the
1461 background and window layer.
1462 \n 0: infront
1463 \n 1: behind
1464 \li Bit 4 - Unimplemented
1465 \li Bit 3 - Unimplemented
1466 \li Bit 2 - Unimplemented
1467 \li Bit 1 - See bit 0.
1468 \li Bit 0 - Bits 0-1 indicate which color palette the sprite should use. Note: only palettes 4 to 7 will be available for NES sprites.
1469
1470 It's recommended to use GBDK constants (eg: S_FLIPY) to configure sprite properties as these are crossplatform.
1471
1472 \code{.c}
1473 // Load palette data into the first palette
1474 set_sprite_palette(4, 1, exampleSprite_palettes)
1475
1476 // Set the OAM value for the sprite
1477 // These flags tell the sprite to use the first sprite palette (palette 4) and to flip the sprite both vertically and horizontally.
1478 set_sprite_prop(0, S_FLIPY | S_FLIPX);
1479 \endcode
1480
1481 @see S_PALETTE, S_FLIPX, S_FLIPY, S_PRIORITY
1482 */
1483 void set_sprite_prop(uint8_t nb, uint8_t prop) NO_OVERLAY_LOCALS;
1484
1485
1486 /** Returns the OAM Property Flags of sprite number __nb__.
1487
1488 @param nb Sprite number, range 0 - 39
1489 @see set_sprite_prop for property bitfield settings
1490 */
1491 uint8_t get_sprite_prop(uint8_t nb) NO_OVERLAY_LOCALS;
1492
1493
1494 /** Moves sprite number __nb__ to the __x__, __y__ position on the screen.
1495
1496 @param nb Sprite number, range 0 - 63
1497 @param x X Position. Specifies the sprites horizontal position on the screen (minus 8).
1498 @param y Y Position. Specifies the sprites vertical position on the screen (minus 16).
1499 \n An offscreen value (Y>=240) hides the sprite.
1500
1501 Moving the sprite to 0,0 (or similar off-screen location) will hide it.
1502 */
1503 void move_sprite(uint8_t nb, uint8_t x, uint8_t y) NO_OVERLAY_LOCALS;
1504
1505
1506 /** Moves sprite number __nb__ relative to its current position.
1507
1508 @param nb Sprite number, range 0 - 63
1509 @param x Number of pixels to move the sprite on the __X axis__
1510 \n Range: -128 - 127
1511 @param y Number of pixels to move the sprite on the __Y axis__
1512 \n Range: -128 - 127
1513
1514 @see move_sprite for more details about the X and Y position
1515 */
1516 void scroll_sprite(uint8_t nb, int8_t x, int8_t y) NO_OVERLAY_LOCALS;
1517
1518
1519 /** Hides sprite number __nb__ by moving it to Y position 240.
1520
1521 @param nb Sprite number, range 0 - 63
1522 */
1523 void hide_sprite(uint8_t nb) NO_OVERLAY_LOCALS;
1524
1525
1526
1527 /** Copies arbitrary data to an address in VRAM
1528 without taking into account the state of LCDC bits 3 or 4.
1529
1530 Copies __len__ bytes from a buffer at __data__ to VRAM starting at __vram_addr__.
1531
1532 @see set_bkg_data, set_win_data, set_bkg_tiles, set_win_tiles, set_tile_data, set_tiles
1533 */
1534 void set_data(uint8_t *vram_addr, const uint8_t *data, uint16_t len) NO_OVERLAY_LOCALS;
1535
1536
1537 /** Sets a rectangular region of Tile Map entries at a given VRAM Address.
1538
1539 @param x X Start position in Map tile coordinates. Range 0 - 31
1540 @param y Y Start position in Map tile coordinates. Range 0 - 31
1541 @param w Width of area to set in tiles. Range 1 - 32
1542 @param h Height of area to set in tiles. Range 1 - 32
1543 @param vram_addr Pointer to destination VRAM Address
1544 @param tiles Pointer to source Tile Map data
1545
1546 Entries are copied from __tiles__ to Tile Map at address vram_addr starting at
1547 __x__, __y__ writing across for __w__ tiles and down for __h__ tiles.
1548
1549 One byte per source tile map entry.
1550
1551 There are two 32x30 Tile Maps in VRAM at addresses 2000h-23FFh and 2400h-27FFh.
1552
1553 @see set_bkg_tiles
1554 */
1555 void set_tiles(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t *vram_addr, const uint8_t *tiles) NO_OVERLAY_LOCALS;
1556
1557 /** Sets VRAM Tile Pattern data starting from given base address
1558 without taking into account the state of PPUMASK.
1559
1560 @see set_bkg_data, set_data
1561 */
1562 inline void set_tile_data(uint16_t first_tile, uint8_t nb_tiles, const uint8_t *data) {
1563 if (first_tile < 256) {
1564 set_bkg_data(first_tile, nb_tiles, data);
1565 if(first_tile + nb_tiles > 256)
1566 set_sprite_data(first_tile - 256, nb_tiles, data);
1567 } else {
1568 set_sprite_data(first_tile - 256, nb_tiles, data);
1569 }
1570 }
1571
1572 /** Sets VRAM Tile Pattern data for the Background in the native format
1573
1574 @param first_tile Index of the first tile to write
1575 @param nb_tiles Number of tiles to write
1576 @param data Pointer to source tile data
1577
1578 Writes __nb_tiles__ tiles to VRAM starting at __first_tile__, tile data
1579 is sourced from __data__.
1580
1581 @see set_tile_data
1582 */
1583 void set_bkg_native_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
1584
1585 /** Sets VRAM Tile Pattern data for Sprites in the native format
1586
1587 @param first_tile Index of the first tile to write
1588 @param nb_tiles Number of tiles to write
1589 @param data Pointer to source tile data
1590
1591 Writes __nb_tiles__ tiles to VRAM starting at __first_tile__, tile data
1592 is sourced from __data__.
1593 */
1594 void set_sprite_native_data(uint8_t first_tile, uint8_t nb_tiles, const uint8_t *data) NO_OVERLAY_LOCALS;
1595
1596 /** Sets VRAM Tile Pattern data in the native format
1597
1598 @param first_tile Index of the first tile to write (0 - 511)
1599 @param nb_tiles Number of tiles to write
1600 @param data Pointer to source Tile Pattern data.
1601
1602 When `first_tile` is larger than 256 on the GB/AP, it
1603 will write to sprite data instead of background data.
1604
1605 The bit depth of the source Tile Pattern data depends
1606 on which console is being used:
1607 \li NES: loads 2bpp tiles data
1608 */
1609 inline void set_native_tile_data(uint16_t first_tile, uint8_t nb_tiles, const uint8_t *data) {
1610 if (first_tile < 256) {
1611 set_bkg_native_data(first_tile, nb_tiles, data);
1612 if(first_tile + nb_tiles > 256)
1613 set_sprite_native_data(first_tile - 256, nb_tiles, data);
1614 } else {
1615 set_sprite_native_data(first_tile - 256, nb_tiles, data);
1616 }
1617 }
1618
1619 /** Initializes the entire Background Tile Map with Tile Number __c__
1620 @param c Tile number to fill with
1621
1622 Note: This function avoids writes during modes 2 & 3
1623 */
1624 void init_bkg(uint8_t c) NO_OVERLAY_LOCALS;
1625
1626 /** Fills the VRAM memory region __s__ of size __n__ with Tile Number __c__
1627 @param s Start address in VRAM
1628 @param c Tile number to fill with
1629 @param n Size of memory region (in bytes) to fill
1630
1631 Note: This function avoids writes during modes 2 & 3
1632 */
1633 void vmemset (void *s, uint8_t c, size_t n) NO_OVERLAY_LOCALS;
1634
1635 /** Fills a rectangular region of Tile Map entries for the Background layer with tile.
1636
1637 @param x X Start position in Background Map tile coordinates. Range 0 - 31
1638 @param y Y Start position in Background Map tile coordinates. Range 0 - 31
1639 @param w Width of area to set in tiles. Range 1 - 32
1640 @param h Height of area to set in tiles. Range 1 - 32
1641 @param tile Fill value
1642 */
1643 void fill_bkg_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile) NO_OVERLAY_LOCALS;
1644 #define fill_rect fill_bkg_rect
1645
1646 /** Fills a rectangular region of Tile Map Attribute entries for the Background layer with attribute.
1647
1648 @param x X Start position in Background Map tile coordinates. Range 0 - 31
1649 @param y Y Start position in Background Map tile coordinates. Range 0 - 31
1650 @param w Width of area to set in tiles. Range 1 - 32
1651 @param h Height of area to set in tiles. Range 1 - 32
1652 @param tile Fill value
1653 */
1654 void fill_bkg_rect_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t attribute) NO_OVERLAY_LOCALS;
1655
1656 /** Fills a rectangular region of Tile Map entries for the Window layer with tile.
1657
1658 @param x X Start position in Window Map tile coordinates. Range 0 - 31
1659 @param y Y Start position in Window Map tile coordinates. Range 0 - 31
1660 @param w Width of area to set in tiles. Range 1 - 32
1661 @param h Height of area to set in tiles. Range 1 - 32
1662 @param tile Fill value
1663 */
1664 #if defined(NES_WINDOW_LAYER)
1665 void fill_win_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile) NO_OVERLAY_LOCALS;
1666 #else
1667 #define fill_win_rect fill_bkg_rect
1668 #endif
1669
1670 /** Fills a rectangular region of Tile Map Attribute entries for the Window layer with attribute.
1671
1672 @param x X Start position in Window Map tile coordinates. Range 0 - 31
1673 @param y Y Start position in Window Map tile coordinates. Range 0 - 31
1674 @param w Width of area to set in tiles. Range 1 - 32
1675 @param h Height of area to set in tiles. Range 1 - 32
1676 @param tile Fill value
1677 */
1678 #if defined(NES_WINDOW_LAYER)
1679 void fill_win_rect_attributes(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t attribute) NO_OVERLAY_LOCALS;
1680 #else
1681 #define fill_win_rect_attributes fill_bkg_rect_attributes
1682 #endif
1683
1684 /** "Flushes" the updates to the shadow attributes so they are written
1685 to the transfer buffer, and then written to PPU memory on next vblank.
1686
1687 This function must be called to see visible changes to attributes
1688 on the NES target. But it will automatically be called by @ref vsync(),
1689 so the use-cases for calling it manually are rare in practice.
1690 */
1691 void flush_shadow_attributes(void) NO_OVERLAY_LOCALS;
1692
1693 uint8_t _switch_prg0(uint8_t bank) NO_OVERLAY_LOCALS;
1694
1695 #endif /* _NES_H */
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.