now parts need to call swap_buffers manually. This allows the
flexibility to have some parts write to video memory directly
(vmem_back) and then do an extremely fast page-flip by calling
swap_buffers(0). Other parts that prefer to write to a system-ram
framebuffer can continue to use fb_pixels, but they now have to call
swap_buffers(fb_pixels), to copy the result to vmem_front.
vmem_back and vmem_front at the moment point to the front buffer, until
I implement VBE page flipping, and in any case they may still both
point to the front buffer if there isn't enough memory for two pages,
so don't memcpy from one to the other manually. Use swap_buffers only.
#ifndef THREEDGFX_H_
#define THREEDGFX_H_
#ifndef THREEDGFX_H_
#define THREEDGFX_H_
struct g3d_vertex {
float x, y, z, w;
float nx, ny, nz;
struct g3d_vertex {
float x, y, z, w;
float nx, ny, nz;
int fb_width = 320;
int fb_height = 240;
int fb_bpp = 16;
int fb_width = 320;
int fb_height = 240;
int fb_bpp = 16;
+uint16_t *fb_pixels, *vmem_back, *vmem_front;
unsigned long time_msec;
int mouse_x, mouse_y;
unsigned int mouse_bmask;
unsigned long time_msec;
int mouse_x, mouse_y;
unsigned int mouse_bmask;
#ifndef DEMO_H_
#define DEMO_H_
#ifndef DEMO_H_
#define DEMO_H_
extern int fb_width, fb_height, fb_bpp;
extern int fb_width, fb_height, fb_bpp;
+extern uint16_t *fb_pixels; /* system-RAM pixel buffer: use swap_buffers(fb_pixels) */
+/* video memory pointers. might both point to the front buffer if there is not
+ * enough memory for page flipping. use swap_buffers(0) to flip. */
+extern uint16_t *vmem_back, *vmem_front;
+
extern unsigned long time_msec;
extern int mouse_x, mouse_y;
extern unsigned int mouse_bmask;
extern unsigned long time_msec;
extern int mouse_x, mouse_y;
extern unsigned int mouse_bmask;
void demo_keyboard(int key, int state);
void demo_keyboard(int key, int state);
/* defined in main_*.c */
void demo_quit(void);
unsigned long get_msec(void);
void set_palette(int idx, int r, int g, int b);
/* defined in main_*.c */
void demo_quit(void);
unsigned long get_msec(void);
void set_palette(int idx, int r, int g, int b);
+/* pass 0 to just swap vmem_back/vmem_front with page flipping
+ * pass a pointer to a system-ram pixel buffer to copy it to vmem_front,
+ * instead of flipping.
+ */
+void swap_buffers(void *pixels);
+
static int quit;
static int use_mouse;
static int quit;
static int use_mouse;
int main(int argc, char **argv)
{
int main(int argc, char **argv)
{
- void *vmem;
- long fbsize = fb_width * fb_height * fb_bpp / CHAR_BIT;
+ fbsize = fb_width * fb_height * fb_bpp / CHAR_BIT;
init_timer(100);
kb_init(32);
init_timer(100);
kb_init(32);
- if(!(vmem = set_video_mode(fb_width, fb_height, fb_bpp))) {
+ if(!(vmem_front = set_video_mode(fb_width, fb_height, fb_bpp))) {
+ /* TODO implement multiple video memory pages for flipping */
+ vmem_back = vmem_front;
if(demo_init(argc, argv) == -1) {
set_text_mode();
if(demo_init(argc, argv) == -1) {
set_text_mode();
time_msec = get_msec();
demo_draw();
time_msec = get_msec();
demo_draw();
-
- /*wait_vsync();*/
- memcpy(vmem, fb_pixels, fbsize);
+
+void swap_buffers(void *pixels)
+{
+ /* TODO implement page flipping */
+ if(pixels) {
+ /*wait_vsync();*/
+ memcpy(vmem_front, pixels, fbsize);
+ }
+}
-static long aspect_24x8 = (long)(1.3333333 * 256.0);
+/*static long aspect_24x8 = (long)(1.3333333 * 256.0);*/
static long xscale_24x8 = (long)(1.3333333 * 1.2 * 256.0);
static long yscale_24x8 = (long)(1.2 * 256.0);
static int cx, cy;
static long xscale_24x8 = (long)(1.3333333 * 1.2 * 256.0);
static long yscale_24x8 = (long)(1.2 * 256.0);
static int cx, cy;
}
pixels[mouse_y * fb_width + mouse_x] = 0xffe;
}
pixels[mouse_y * fb_width + mouse_x] = 0xffe;
+
+ swap_buffers(fb_pixels);
}
static long normalize_coord(long x, long range)
}
static long normalize_coord(long x, long range)
static void rleEncode(unsigned char *pixels, unsigned int w, unsigned int h);
static unsigned short *background = 0;
static void rleEncode(unsigned char *pixels, unsigned int w, unsigned int h);
static unsigned short *background = 0;
-static unsigned int backgroundW = 0;
-static unsigned int backgroundH = 0;
+static int backgroundW = 0;
+static int backgroundH = 0;
static unsigned int lastFrameTime = 0;
static float lastFrameDuration = 0.0f;
static unsigned int lastFrameTime = 0;
static float lastFrameDuration = 0.0f;
src += BB_SIZE;
dst += fb_width;
}
src += BB_SIZE;
dst += fb_width;
}
+
+ swap_buffers(fb_pixels);
}
/* src and dst can be the same */
}
/* src and dst can be the same */
zsort(&torus);
draw_mesh(&torus);
zsort(&torus);
draw_mesh(&torus);
+
+ swap_buffers(fb_pixels);
}
static void draw_mesh(struct mesh *mesh)
}
static void draw_mesh(struct mesh *mesh)
fprintf(stderr, "failed to allocate virtual framebuffer\n");
return 1;
}
fprintf(stderr, "failed to allocate virtual framebuffer\n");
return 1;
}
+ vmem_front = vmem_back = fb_pixels;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
if(!(fbsurf = SDL_SetVideoMode(xsz, ysz, fb_bpp, sdl_flags))) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
if(!(fbsurf = SDL_SetVideoMode(xsz, ysz, fb_bpp, sdl_flags))) {
+void swap_buffers(void *pixels)
+{
+ /* do nothing, all pointers point to the same buffer */
+}
+
static void handle_event(SDL_Event *ev)
{
switch(ev->type) {
static void handle_event(SDL_Event *ev)
{
switch(ev->type) {
static int count_bits(unsigned int x);
static int count_zeros(unsigned int x);
static int count_bits(unsigned int x);
static int count_zeros(unsigned int x);
-static unsigned int *gen_test_image(int *wptr, int *hptr);
-
static struct screen scr = {
"tunnel",
init,
static struct screen scr = {
"tunnel",
init,
int starty = i * num_lines;
int resty = starty + draw_lines;
int rest_lines = num_lines - draw_lines;
int starty = i * num_lines;
int resty = starty + draw_lines;
int rest_lines = num_lines - draw_lines;
- draw_tunnel_range((unsigned short*)fb_pixels, xoffs, yoffs, starty, draw_lines, time_msec);
+ draw_tunnel_range(vmem_back, xoffs, yoffs, starty, draw_lines, time_msec);
- memset((unsigned short*)fb_pixels + resty * fb_width, 0, rest_lines * fb_width * 2);
+ memset(vmem_back + resty * fb_width, 0, rest_lines * fb_width * 2);
}
static void tunnel_color(int *rp, int *gp, int *bp, long toffs, unsigned int tpacked, int fog)
}
static void tunnel_color(int *rp, int *gp, int *bp, long toffs, unsigned int tpacked, int fog)
static unsigned int *gen_test_image(int *wptr, int *hptr)
{
int i, j;
static unsigned int *gen_test_image(int *wptr, int *hptr)
{
int i, j;
*hptr = ysz;
return pixels;
}
*hptr = ysz;
return pixels;
}