-
Notifications
You must be signed in to change notification settings - Fork 12
/
dreamroq-player.c
150 lines (119 loc) · 3.98 KB
/
dreamroq-player.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
/*
* Dreamroq by Mike Melanson
*
* This is the sample Dreamcast player app, designed to be run under
* the KallistiOS operating system.
*/
#include "kos.h"
#include "dreamroqlib.h"
static pvr_ptr_t textures[2];
static int current_frame = 0;
static int render_cb(void *buf_ptr, int width, int height, int stride,
int texture_height, int colorspace)
{
pvr_poly_cxt_t cxt;
static pvr_poly_hdr_t hdr[2];
static pvr_vertex_t vert[4];
unsigned short *buf = (unsigned short*)buf_ptr;
float ratio;
/* screen coordinates of upper left and bottom right corners */
static int ul_x, ul_y, br_x, br_y;
static int graphics_initialized = 0;
if (colorspace != ROQ_RGB565)
return ROQ_RENDER_PROBLEM;
/* on first call, initialize textures and drawing coordinates */
if (!graphics_initialized)
{
textures[0] = pvr_mem_malloc(stride * texture_height * 2);
textures[1] = pvr_mem_malloc(stride * texture_height * 2);
if (!textures[0] || !textures[1])
{
return ROQ_RENDER_PROBLEM;
}
/* Precompile the poly headers */
pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED, stride, texture_height, textures[0], PVR_FILTER_NONE);
pvr_poly_compile(&hdr[0], &cxt);
pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED, stride, texture_height, textures[1], PVR_FILTER_NONE);
pvr_poly_compile(&hdr[1], &cxt);
/* this only works if width ratio <= height ratio */
ratio = 640.0 / width;
ul_x = 0;
br_x = (ratio * stride);
ul_y = ((480 - ratio * height) / 2);
br_y = ul_y + ratio * texture_height;
/* Things common to vertices */
vert[0].z = vert[1].z = vert[2].z = vert[3].z = 1.0f;
vert[0].argb = vert[1].argb = vert[2].argb = vert[3].argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
vert[0].oargb = vert[1].oargb = vert[2].oargb = vert[3].oargb = 0;
vert[0].flags = vert[1].flags = vert[2].flags = PVR_CMD_VERTEX;
vert[3].flags = PVR_CMD_VERTEX_EOL;
vert[0].x = ul_x;
vert[0].y = ul_y;
vert[0].u = 0.0;
vert[0].v = 0.0;
vert[1].x = br_x;
vert[1].y = ul_y;
vert[1].u = 1.0;
vert[1].v = 0.0;
vert[2].x = ul_x;
vert[2].y = br_y;
vert[2].u = 0.0;
vert[2].v = 1.0;
vert[3].x = br_x;
vert[3].y = br_y;
vert[3].u = 1.0;
vert[3].v = 1.0;
graphics_initialized = 1;
}
/* send the video frame as a texture over to video RAM */
pvr_txr_load(buf, textures[current_frame], stride * texture_height * 2);
pvr_wait_ready();
pvr_scene_begin();
pvr_list_begin(PVR_LIST_OP_POLY);
pvr_prim(&hdr[current_frame], sizeof(pvr_poly_hdr_t));
pvr_prim(&vert[0], sizeof(pvr_vertex_t));
pvr_prim(&vert[1], sizeof(pvr_vertex_t));
pvr_prim(&vert[2], sizeof(pvr_vertex_t));
pvr_prim(&vert[3], sizeof(pvr_vertex_t));
pvr_list_finish();
pvr_scene_finish();
if (current_frame)
current_frame = 0;
else
current_frame = 1;
return ROQ_SUCCESS;
}
int audio_cb(unsigned char *buf_rgb565, int samples, int channels)
{
return ROQ_SUCCESS;
}
static int quit_cb()
{
cont_cond_t cont;
/* check controller state */
if (cont_get_cond(maple_first_controller(), &cont))
{
/* controller read error */
return 1;
}
cont.buttons = ~cont.buttons;
return (cont.buttons & CONT_START);
}
int finish_cb()
{
return ROQ_SUCCESS;
}
int main()
{
int status;
roq_callbacks_t cbs;
cbs.render_cb = render_cb;
cbs.audio_cb = audio_cb;
cbs.quit_cb = quit_cb;
cbs.finish_cb = finish_cb;
vid_set_mode(DM_640x480_NTSC_IL, PM_RGB565);
pvr_init_defaults();
status = dreamroq_play("/cd/venuscubes.roq", ROQ_RGB565, 1, &cbs);
printf("dreamroq_play() status = %d\n", status);
return 0;
}