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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }