1 | // MIT License |
2 | |
3 | // Copyright (c) 2017 Vadim Grigoruk @nesbox // grigoruk@gmail.com |
4 | |
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
6 | // of this software and associated documentation files (the "Software"), to deal |
7 | // in the Software without restriction, including without limitation the rights |
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
9 | // copies of the Software, and to permit persons to whom the Software is |
10 | // furnished to do so, subject to the following conditions: |
11 | |
12 | // The above copyright notice and this permission notice shall be included in all |
13 | // copies or substantial portions of the Software. |
14 | |
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
21 | // SOFTWARE. |
22 | |
23 | #pragma once |
24 | |
25 | #include "api.h" |
26 | #include "tools.h" |
27 | #include "blip_buf.h" |
28 | |
29 | #define CLOCKRATE (255<<13) |
30 | #define TIC_DEFAULT_COLOR 15 |
31 | #define TIC_SOUND_RINGBUF_LEN 12 // in worst case, this induces ~ 12 tick delay i.e. 200 ms |
32 | |
33 | typedef struct |
34 | { |
35 | s32 time; /* clock time of next delta */ |
36 | s32 phase; /* position within waveform */ |
37 | s32 amp; /* current amplitude in delta buffer */ |
38 | }tic_sound_register_data; |
39 | |
40 | typedef struct |
41 | { |
42 | s32 tick; |
43 | tic_sfx_pos* pos; |
44 | s32 index; |
45 | s32 note; |
46 | struct |
47 | { |
48 | u8 left:4; |
49 | u8 right:4; |
50 | } volume; |
51 | s8 speed:SFX_SPEED_BITS; |
52 | s32 duration; |
53 | } tic_channel_data; |
54 | |
55 | typedef struct |
56 | { |
57 | struct |
58 | { |
59 | s32 tick; |
60 | u8 note1:4; |
61 | u8 note2:4; |
62 | } chord; |
63 | |
64 | struct |
65 | { |
66 | s32 tick; |
67 | u8 period:4; |
68 | u8 depth:4; |
69 | } vibrato; |
70 | |
71 | struct |
72 | { |
73 | s32 tick; |
74 | u8 note; |
75 | s32 duration; |
76 | } slide; |
77 | |
78 | struct |
79 | { |
80 | s32 value; |
81 | } finepitch; |
82 | |
83 | struct |
84 | { |
85 | const tic_track_row* row; |
86 | s32 ticks; |
87 | } delay; |
88 | |
89 | } tic_command_data; |
90 | |
91 | typedef struct |
92 | { |
93 | bool active; |
94 | s32 frame; |
95 | s32 beat; |
96 | } tic_jump_command; |
97 | |
98 | typedef struct |
99 | { |
100 | |
101 | struct |
102 | { |
103 | tic80_gamepads previous; |
104 | tic80_gamepads now; |
105 | |
106 | u32 holds[sizeof(tic80_gamepads) * BITS_IN_BYTE]; |
107 | } gamepads; |
108 | |
109 | struct |
110 | { |
111 | tic80_keyboard previous; |
112 | tic80_keyboard now; |
113 | |
114 | u32 holds[tic_keys_count]; |
115 | } keyboard; |
116 | |
117 | struct |
118 | { |
119 | tic_sound_register_data left[TIC_SOUND_CHANNELS]; |
120 | tic_sound_register_data right[TIC_SOUND_CHANNELS]; |
121 | } registers; |
122 | |
123 | struct |
124 | { |
125 | tic_sound_register registers[TIC_SOUND_CHANNELS]; |
126 | tic_stereo_volume stereo; |
127 | } sound_ringbuf[TIC_SOUND_RINGBUF_LEN]; |
128 | |
129 | u32 sound_ringbuf_head; |
130 | u32 sound_ringbuf_tail; |
131 | |
132 | struct |
133 | { |
134 | tic_channel_data channels[TIC_SOUND_CHANNELS]; |
135 | } sfx; |
136 | |
137 | struct |
138 | { |
139 | s32 ticks; |
140 | tic_channel_data channels[TIC_SOUND_CHANNELS]; |
141 | tic_command_data commands[TIC_SOUND_CHANNELS]; |
142 | tic_sfx_pos sfxpos[TIC_SOUND_CHANNELS]; |
143 | tic_jump_command jump; |
144 | s32 tempo; |
145 | s32 speed; |
146 | } music; |
147 | |
148 | tic_tick tick; |
149 | tic_blit_callback callback; |
150 | |
151 | u32 synced; |
152 | |
153 | struct |
154 | { |
155 | s32 id; |
156 | tic_vram mem; |
157 | } vbank; |
158 | |
159 | struct ClipRect |
160 | { |
161 | s32 l, t, r, b; |
162 | } clip; |
163 | |
164 | bool initialized; |
165 | } tic_core_state_data; |
166 | |
167 | typedef struct |
168 | { |
169 | tic_mem memory; // it should be first |
170 | tic80_pixel_color_format screen_format; |
171 | |
172 | void* currentVM; |
173 | const tic_script_config* currentScript; |
174 | |
175 | struct |
176 | { |
177 | blip_buffer_t* left; |
178 | blip_buffer_t* right; |
179 | } blip; |
180 | |
181 | s32 samplerate; |
182 | tic_tick_data* data; |
183 | tic_core_state_data state; |
184 | |
185 | struct |
186 | { |
187 | tic_core_state_data state; |
188 | tic_ram ram; |
189 | u8 input; |
190 | |
191 | struct |
192 | { |
193 | clock_t start; |
194 | clock_t paused; |
195 | } time; |
196 | } pause; |
197 | |
198 | } tic_core; |
199 | |
200 | void tic_core_tick_io(tic_mem* memory); |
201 | void tic_core_sound_tick_start(tic_mem* memory); |
202 | void tic_core_sound_tick_end(tic_mem* memory); |
203 | |
204 | // mouse cursor is the same in both modes |
205 | // for backward compatibility |
206 | #define OVR_COMPAT(CORE, BANK) \ |
207 | tic_api_vbank(&CORE->memory, BANK), \ |
208 | CORE->memory.ram->vram.vars.cursor = CORE->state.vbank.mem.vars.cursor |
209 | |
210 | #define OVR(CORE) \ |
211 | s32 MACROVAR(_bank_) = CORE->state.vbank.id; \ |
212 | OVR_COMPAT(CORE, 1); \ |
213 | tic_api_cls(&CORE->memory, 0); \ |
214 | SCOPE(OVR_COMPAT(CORE, MACROVAR(_bank_))) |
215 | |