-
Notifications
You must be signed in to change notification settings - Fork 12
/
test-dreamroq.c
173 lines (152 loc) · 4.97 KB
/
test-dreamroq.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
* Dreamroq by Mike Melanson
*
* This is a simple, sample program that helps test the Dreamroq library.
*/
#include <stdio.h>
#include "dreamroqlib.h"
int quit_cb()
{
/* big, fat no-op for command line tool */
return 0;
}
int render_cb(void *buf, int width, int height, int stride,
int texture_height, int colorspace)
{
static int count = 0;
FILE *out;
char filename[20];
int x, y;
unsigned int pixel;
unsigned short *buf_rgb565 = (unsigned short*)buf;
unsigned int *buf_rgba = (unsigned int*)buf;
sprintf(filename, "%04d.pnm", count);
printf("writing frame %d to file %s\n", count, filename);
count++;
out = fopen(filename, "wb");
if (!out)
return ROQ_CLIENT_PROBLEM;
fprintf(out, "P6\n%d %d\n255\n", width, height);
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
if (colorspace == ROQ_RGB565)
{
pixel = *buf_rgb565++;
fputc(((pixel >> 11) << 3) & 0xFF, out); /* red */
fputc(((pixel >> 5) << 2) & 0xFF, out); /* green */
fputc(((pixel >> 0) << 3) & 0xFF, out); /* blue */
}
else if (colorspace == ROQ_RGBA)
{
pixel = *buf_rgba++;
fputc((pixel >> 24) & 0xFF, out); /* red */
fputc((pixel >> 16) & 0xFF, out); /* green */
fputc((pixel >> 8) & 0xFF, out); /* blue */
}
}
if (colorspace == ROQ_RGB565)
buf_rgb565 += (stride - width);
else if (colorspace == ROQ_RGBA)
buf_rgba += (stride - width);
}
fclose(out);
return ROQ_SUCCESS;
}
#define AUDIO_FILENAME "roq-audio.wav"
static char wav_header[] = {
'R', 'I', 'F', 'F', /* RIFF header */
0, 0, 0, 0, /* file size will be filled in later */
'W', 'A', 'V', 'E', /* more header stuff */
'f', 'm', 't', 0x20,
0x10, 0, 0, 0, /* length of format chunk */
1, 0, /* format = 1 (PCM) */
0, 0, /* channel count will be filled in later */
0x22, 0x56, 0, 0, /* frequency is always 0x5622 = 22050 Hz */
0, 0, 0, 0, /* byte rate will be filled in later */
1, 0, 0x10, 0, /* data alignment and bits per sample */
'd', 'a', 't', 'a', /* start of data chunk */
0, 0, 0, 0 /* data block size will be filled in later */
};
#define WAV_HEADER_SIZE 44
#define SAMPLE_RATE 22050
static FILE *wav_output;
static int data_size = 0;
static int audio_output_initialized = 0;
int audio_cb(unsigned char *buf_rgb565, int samples, int channels)
{
int byte_rate;
if (!audio_output_initialized)
{
wav_output = fopen(AUDIO_FILENAME, "wb");
if (!wav_output)
return ROQ_CLIENT_PROBLEM;
/* fill in channels and data rate fields */
if (channels != 1 && channels != 2)
return ROQ_CLIENT_PROBLEM;
wav_header[22] = channels;
byte_rate = SAMPLE_RATE * 2 * channels;
wav_header[0x1C] = (byte_rate >> 0) & 0xFF;
wav_header[0x1D] = (byte_rate >> 8) & 0xFF;
wav_header[0x1E] = (byte_rate >> 16) & 0xFF;
wav_header[0x1F] = (byte_rate >> 24) & 0xFF;
/* write the header */
if (fwrite(wav_header, WAV_HEADER_SIZE, 1, wav_output) != 1)
{
fclose(wav_output);
return ROQ_CLIENT_PROBLEM;
}
audio_output_initialized = 1;
}
/* dump the data and account for the amount */
if (fwrite(buf_rgb565, samples, 1, wav_output) != 1)
{
fclose(wav_output);
return ROQ_CLIENT_PROBLEM;
}
data_size += samples;
return ROQ_SUCCESS;
}
int finish_cb()
{
if (audio_output_initialized)
{
/* rewind and rewrite the header with the known parameters */
printf("Wrote %d (0x%X) bytes to %s\n", data_size, data_size,
AUDIO_FILENAME);
fseek(wav_output, 0, SEEK_SET);
wav_header[40] = (data_size >> 0) & 0xFF;
wav_header[41] = (data_size >> 8) & 0xFF;
wav_header[42] = (data_size >> 16) & 0xFF;
wav_header[43] = (data_size >> 24) & 0xFF;
data_size += WAV_HEADER_SIZE - 8;
wav_header[4] = (data_size >> 0) & 0xFF;
wav_header[5] = (data_size >> 8) & 0xFF;
wav_header[6] = (data_size >> 16) & 0xFF;
wav_header[7] = (data_size >> 24) & 0xFF;
if (fwrite(wav_header, WAV_HEADER_SIZE, 1, wav_output) != 1)
{
fclose(wav_output);
return ROQ_CLIENT_PROBLEM;
}
}
return ROQ_SUCCESS;
}
int main(int argc, char *argv[])
{
int status;
roq_callbacks_t cbs;
if (argc < 2)
{
printf("USAGE: test-dreamroq <file.roq>\n");
return 1;
}
cbs.render_cb = render_cb;
cbs.audio_cb = audio_cb;
cbs.quit_cb = quit_cb;
cbs.finish_cb = finish_cb;
status = dreamroq_play(argv[1], ROQ_RGBA, 0, &cbs);
printf("final status = %d\n", status);
return status;
}