llvm-mos-sdk
nesdoug.h
Go to the documentation of this file.
1 #ifndef _NESDOUG_H_
2 #define _NESDOUG_H_
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 // Written by Doug Fraker
9 // version 1.2, 1/1/2022
10 
11 // Why am I doing so much with a vram_buffer? This is an automated system, which
12 // works when the screen is on. You can write to the buffer at any time.
13 // During NMI / v-blank, it automatically writes to the PPU.
14 // You don't have to worry about timing those writes. And, more importantly,
15 // you shouldn't have to turn the screen off...
16 // allowing us to make smooth scrolling games.
17 
18 // sets the vram update to point to the vram_buffer. VRAM_BUF defined in crt0.s
19 // this can be undone by set_vram_update(NULL)
20 void set_vram_buffer(void);
21 
22 // to push a single byte write to the vram_buffer
23 __attribute__((leaf)) void one_vram_buffer(char data, int ppu_address);
24 
25 // to push multiple writes as one sequential horizontal write to the vram_buffer
26 __attribute__((leaf)) void multi_vram_buffer_horz(const void *data, char len,
27  int ppu_address);
28 
29 // to push multiple writes as one sequential vertical write to the vram_buffer
30 __attribute__((leaf)) void multi_vram_buffer_vert(const void *data, char len,
31  int ppu_address);
32 
33 // pad 0 or 1, use AFTER pad_poll() to get the trigger / new button presses
34 // more efficient than pad_trigger, which runs the entire pad_poll code again
35 char get_pad_new(char pad);
36 
37 // use this internal value to time events, this ticks up every frame
38 char get_frame_count(void);
39 
40 // this will alter the tempo of music, range 1-12 are reasonable, low is faster
41 // default is 6
42 // music_play also sets the tempo, and any Fxx effect in the song will too
43 // you will probably have to repeatedly set_music_speed() every frame
44 // music_stop() and music_pause() also overwrite this value
45 void set_music_speed(char tempo);
46 
47 // expects an object (struct) where the first 4 bytes are X, Y, width, height
48 // you will probably have to pass the address of the object like &object
49 // the struct can be bigger than 4 bytes, as long as the first 4 bytes are X, Y,
50 // width, height
51 __attribute__((leaf)) char check_collision(void *object1, void *object2);
52 
53 // adapted from Shiru's "Chase" game code
54 // values must be 0-8, 0 = all black, 8 = all white, 4 = normal
55 __attribute__((leaf)) void pal_fade_to(char from, char to);
56 
57 // x can be in the range 0-0x1ff, but any value would be fine, it discards
58 // higher bits
59 void set_scroll_x(unsigned x);
60 
61 // y can be in the range 0-0x1ff, but any value would be fine, it discards
62 // higher bits NOTE - different system than neslib (which needs y in range
63 // 0-0x1df) the advantage here, is you can set Y scroll to 0xff (-1) to shift
64 // the screen down 1, which aligns it with sprites, which are shifted down 1
65 // pixel
66 void set_scroll_y(unsigned y);
67 
68 // add a value to y scroll, keep the low byte in the 0-0xef range
69 // returns y scroll, which will have to be passed to set_scroll_y
70 __attribute__((leaf)) int add_scroll_y(char add, unsigned scroll);
71 
72 // subtract a value from y scroll, keep the low byte in the 0-0xef range
73 // returns y scroll, which will have to be passed to set_scroll_y
74 __attribute__((leaf)) int sub_scroll_y(char sub, unsigned scroll);
75 
76 // gets a ppu address from x and y coordinates (in pixels)
77 // x is screen pixels 0-255, y is screen pixels 0-239, nt is nametable 0-3
78 __attribute__((leaf)) int get_ppu_addr(char nt, char x, char y);
79 
80 // gets a ppu address in the attribute table from x and y coordinates (in
81 // pixels) x is screen pixels 0-255, y is screen pixels 0-239, nt is nametable
82 // 0-3
83 __attribute__((leaf)) int get_at_addr(char nt, char x, char y);
84 
85 // the next 4 functions are for my metatile system, as described in my tutorial
86 // nesdoug.com
87 
88 // for the metatile system, pass it the addresses of the room data
89 // room data should be exactly 240 bytes (16x15)
90 // each byte represents a 16x16 px block of the screen
91 void set_data_pointer(const void *data);
92 
93 // for the metatile system, pass it the addresses of the metatile data
94 // a metatile is a 16x16 px block
95 // metatiles is variable length, 5 bytes per metatile...
96 // TopL, TopR, BottomL, BottomR, then 1 byte of palette 0-3
97 // max metatiles = 51 (because 51 x 5 = 255)
98 void set_mt_pointer(const void *metatiles);
99 
100 // will push 1 metatile and 0 attribute bytes to the vram_buffer
101 // make sure to set_vram_buffer(), and clear_vram_buffer(),
102 // and set_mt_pointer()
103 // "metatile" should be 0-50, like the metatile data
104 __attribute__((leaf)) void buffer_1_mt(int ppu_address, char metatile);
105 
106 // will push 4 metatiles (2x2 box) and 1 attribute byte to the vram_buffer
107 // this affects a 32x32 px area of the screen, and pushes 17 bytes to the
108 // vram_buffer. make sure to set_vram_buffer(), and clear_vram_buffer(),
109 // set_data_pointer(), and set_mt_pointer()
110 // "index" is which starting byte in the room data, to convert to tiles.
111 // use index = (y & 0xf0) + (x >> 4); where x 0-255 and y 0-239;
112 // index should be 0-239, like the room data it represents
113 __attribute__((leaf)) void buffer_4_mt(int ppu_address, char index);
114 
115 // same as flush_vram_update, but assumes that a pointer to the vram has been
116 // set already this is for when the screen is OFF, but you still want to write
117 // to the PPU with the vram_buffer system
118 __attribute__((leaf)) void flush_vram_update2(void);
119 
120 // change the PPU's color emphasis bits
121 void color_emphasis(char color);
122 
123 #define COL_EMP_BLUE 0x80
124 #define COL_EMP_GREEN 0x40
125 #define COL_EMP_RED 0x20
126 #define COL_EMP_NORMAL 0x00
127 #define COL_EMP_DARK 0xe0
128 
129 // a version of split that actually changes the y scroll midscreen
130 // requires a sprite zero hit, or will crash
131 __attribute__((leaf)) void xy_split(unsigned x, unsigned y);
132 
133 // For debugging. Insert at the end of the game loop, to see how much frame is
134 // left. Will print a gray line on the screen. Distance to the bottom = how much
135 // is left. No line, possibly means that you are in v-blank.
136 __attribute__((leaf)) void gray_line(void);
137 
138 // for getting or modifying just 1 byte of an int
139 
140 #define high_byte(a) *((char *)&a + 1)
141 #define low_byte(a) *((char *)&a)
142 
143 #include <peekpoke.h>
144 
145 // get from the frame count. You can use a button (start on title screen) to
146 // trigger
147 void seed_rng(void);
148 
149 #ifdef __cplusplus
150 }
151 #endif
152 
153 #endif // _NESDOUG_H_
set_scroll_y
void set_scroll_y(unsigned y)
data
char const void * data
Definition: neslib.h:92
color_emphasis
void color_emphasis(char color)
seed_rng
void seed_rng(void)
get_pad_new
char get_pad_new(char pad)
x
char x
Definition: nesdoug.h:78
peekpoke.h
to
char to
Definition: nesdoug.h:55
y
char char y
Definition: nesdoug.h:78
index
char index
Definition: nesdoug.h:113
set_data_pointer
void set_data_pointer(const void *data)
object2
void * object2
Definition: nesdoug.h:51
scroll
unsigned scroll
Definition: nesdoug.h:70
ppu_address
int ppu_address
Definition: nesdoug.h:23
metatile
char metatile
Definition: nesdoug.h:104
set_mt_pointer
void set_mt_pointer(const void *metatiles)
get_frame_count
char get_frame_count(void)
set_scroll_x
void set_scroll_x(unsigned x)
set_vram_buffer
void set_vram_buffer(void)
set_music_speed
void set_music_speed(char tempo)
len
char len
Definition: nesdoug.h:26