Mercurial > repos > blastem
annotate vgm.c @ 1971:80920c21bb52
Add an event log soft flush and call it twice per frame in between hard flushes to netplay latency when there are insufficient hardware updates to flush packets in the middle of a frame
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 08 May 2020 11:40:30 -0700 |
parents | 508522f08e4d |
children | a9449608d0b0 |
rev | line source |
---|---|
1909
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 #include <stdlib.h> |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
2 #include <string.h> |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
3 #include <stddef.h> |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
4 #include "vgm.h" |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
5 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 vgm_writer *vgm_write_open(char *filename, uint32_t rate, uint32_t clock, uint32_t cycle) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 FILE *f = fopen(filename, "wb"); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 if (!f) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 return NULL; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 vgm_writer *writer = calloc(sizeof(vgm_writer), 1); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 memcpy(writer->header.ident, "Vgm ", 4); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 writer->header.version = 0x150; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 writer->header.data_offset = sizeof(writer->header) - offsetof(vgm_header, data_offset); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 writer->header.rate = rate; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 writer->f = f; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 if (1 != fwrite(&writer->header, sizeof(writer->header), 1, f)) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 free(writer); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 fclose(f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 return NULL; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 writer->master_clock = clock; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 writer->last_cycle = cycle; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 return writer; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 void vgm_sn76489_init(vgm_writer *writer, uint32_t clock, uint16_t feedback, uint8_t shift_reg_size, uint8_t flags) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 if (flags && writer->header.version < 0x151) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 writer->header.version = 0x151; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 writer->header.sn76489_clk = clock, |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 writer->header.sn76489_fb = feedback; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 writer->header.sn76489_shift = shift_reg_size; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 writer->header.sn76489_flags = flags; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 static void wait_commands(vgm_writer *writer, uint32_t delta) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 if (!delta) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 return; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
44 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 if (delta <= 0x10) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 fputc(CMD_WAIT_SHORT + (delta - 1), writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 } else if (delta >= 735 && delta <= (735 + 0x10)) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 fputc(CMD_WAIT_60, writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 wait_commands(writer, delta - 735); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 } else if (delta >= 882 && delta <= (882 + 0x10)) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 fputc(CMD_WAIT_50, writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 wait_commands(writer, delta - 882); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 } else if (delta > 0xFFFF) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 uint8_t cmd[3] = {CMD_WAIT, 0xFF, 0xFF}; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 fwrite(cmd, 1, sizeof(cmd), writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 wait_commands(writer, delta - 0xFFFF); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 } else { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 uint8_t cmd[3] = {CMD_WAIT, delta, delta >> 8}; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 fwrite(cmd, 1, sizeof(cmd), writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 static void add_wait(vgm_writer *writer, uint32_t cycle) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 uint64_t delta = cycle - writer->last_cycle; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 delta *= (uint64_t)44100; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 delta /= (uint64_t)writer->master_clock; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 uint32_t mclks_per_sample = writer->master_clock / 44100; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 writer->last_cycle += delta * mclks_per_sample; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 writer->header.num_samples += delta; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 wait_commands(writer, delta); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 void vgm_sn76489_write(vgm_writer *writer, uint32_t cycle, uint8_t value) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 add_wait(writer, cycle); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 uint8_t cmd[2] = {CMD_PSG, value}; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 fwrite(cmd, 1, sizeof(cmd), writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 void vgm_ym2612_init(vgm_writer *writer, uint32_t clock) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 writer->header.ym2612_clk = clock; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 void vgm_ym2612_part1_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 add_wait(writer, cycle); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 uint8_t cmd[3] = {CMD_YM2612_0, reg, value}; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 fwrite(cmd, 1, sizeof(cmd), writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 void vgm_ym2612_part2_write(vgm_writer *writer, uint32_t cycle, uint8_t reg, uint8_t value) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 add_wait(writer, cycle); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 uint8_t cmd[3] = {CMD_YM2612_1, reg, value}; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 fwrite(cmd, 1, sizeof(cmd), writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 void vgm_adjust_cycles(vgm_writer *writer, uint32_t deduction) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 if (deduction > writer->last_cycle) { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 writer->last_cycle = 0; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 } else { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 writer->last_cycle -= deduction; |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 } |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 void vgm_close(vgm_writer *writer) |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 { |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 writer->header.eof_offset = ftell(writer->f) - offsetof(vgm_header, eof_offset); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 fseek(writer->f, SEEK_SET, 0); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 fwrite(&writer->header, sizeof(writer->header), 1, writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 fclose(writer->f); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 free(writer); |
508522f08e4d
Initial stab at VGM logging support
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 } |