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
33typedef 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
40typedef 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
55typedef 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
91typedef struct
92{
93 bool active;
94 s32 frame;
95 s32 beat;
96} tic_jump_command;
97
98typedef 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
167typedef 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
200void tic_core_tick_io(tic_mem* memory);
201void tic_core_sound_tick_start(tic_mem* memory);
202void 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