-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvgm.c
121 lines (101 loc) · 3.74 KB
/
vgm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "vgm.h"
static const uint8_t header[] = {
/* 0x-0 0x-1 0x-2 0x-3 0x-4 0x-5 0x-6 0x-7 0x-8 0x-9 0x-a 0x-b 0x-c 0x-d 0x-e 0x-f */
/* 0x0- */ 0x56, 0x67, 0x6d, 0x20, 0x4a, 0x83, 0x01, 0x00, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x1- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x9a, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x2- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x3- */ 0x00, 0x09, 0x3d, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x4- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x5- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x6- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x7- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x8- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x9- */ 0x00, 0x12, 0x7a, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0xa- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0xb- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0xc- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0xd- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0xe- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0xf- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
int vgm_logger_begin(struct vgm_logger *l, char *filename) {
l->f = fopen(filename, "wb");
if(!l->f) return -1;
fwrite(header, 1, sizeof(header), l->f);
l->last_wait = 0;
l->size = 0;
return 0;
}
void vgm_logger_wait(struct vgm_logger *l, int samples) {
l->last_wait += samples;
l->total_samples += samples;
}
void vgm_logger_write_wait(struct vgm_logger *l, int samples) {
if(samples <= 0) return;
uint8_t buf[3];
int len = 0;
if(samples == 735) {
buf[0] = 0x62;
len = 1;
} else if(samples == 882) {
buf[0] = 0x63;
len = 1;
} else if(samples <= 16) {
buf[0] = 0x70 + samples - 1;
len = 1;
} else {
while(samples > 65535) {
buf[0] = 0x61;
buf[1] = 0xff;
buf[2] = 0xff;
fwrite(buf, 1, 3, l->f);
l->size += 3;
samples -= 65535;
}
buf[0] = 0x61;
buf[1] = samples & 0xff;
buf[2] = samples >> 8;
len = 3;
}
fwrite(buf, 1, len, l->f);
l->size += len;
}
void vgm_logger_write(struct vgm_logger *l, uint8_t *buf, int len) {
if(l->last_wait) {
vgm_logger_write_wait(l, l->last_wait);
l->last_wait = 0;
}
fwrite(buf, 1, len, l->f);
l->size += len;
}
void vgm_logger_write_ay(struct vgm_logger *l, uint8_t reg, uint8_t data) {
uint8_t buf[3];
buf[0] = 0xa0;
buf[1] = reg;
buf[2] = data;
vgm_logger_write(l, buf, 3);
}
void vgm_logger_write_ym2151(struct vgm_logger *l, uint8_t reg, uint8_t data) {
uint8_t buf[3];
buf[0] = 0x54;
buf[1] = reg;
buf[2] = data;
vgm_logger_write(l, buf, 3);
}
void vgm_logger_write_okim6258(struct vgm_logger *l, uint8_t reg, uint8_t data) {
uint8_t buf[3];
buf[0] = 0xb7;
buf[1] = reg;
buf[2] = data;
vgm_logger_write(l, buf, 3);
}
void vgm_logger_end(struct vgm_logger *l) {
if(l->last_wait)
vgm_logger_write_wait(l, l->last_wait);
fseek(l->f, 0x04, SEEK_SET);
l->size += sizeof(header) - 4;
fwrite(&l->size, 1, 4, l->f);
fseek(l->f, 0x18, SEEK_SET);
fwrite(&l->total_samples, 1, 4, l->f);
fclose(l->f);
}