Mercurial > hg > Game > Cerium
view old/framebuffer/fb_test.c @ 996:bac3b0afc3e8 draft
add sdl_test file
author | yutaka@charles.cr.ie.u-ryukyu.ac.jp |
---|---|
date | Mon, 11 Oct 2010 18:56:51 +0900 |
parents | 8fe33c0c2b8f |
children |
line wrap: on
line source
// fb_test.c // Simple test application. Draw something to the frame buffer. // // Copyright (c) 2006, Mike Acton <macton@cellperformance.com> // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated // documentation files (the "Software"), to deal in the Software without restriction, including without // limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial // portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. #include <stdint.h> #include <stdio.h> #include <string.h> #include <math.h> #include "cp_vt.h" #include "cp_fb.h" void write_hline_gouraud_ABGR8888( int32_t x0, int32_t x1, uint32_t left_rgba, uint32_t right_rgba, void* dest_buffer, uint16_t stride ); int main( void ) { cp_vt vt; cp_fb fb; cp_vt_open_graphics(&vt); cp_fb_open(&fb); uint32_t frame_ndx = 0; float sprite_t = 0.0f; float sprite_prev_t[2] = { 0.0f, 0.0f }; // A little example display. for (uint32_t y_last = 1; y_last < fb.h; y_last++) { uint32_t* const restrict frame_top = (uint32_t*)fb.draw_addr[ frame_ndx ]; // Clear the background memset( frame_top, 0x00, fb.h * fb.stride * 4 ); // Draw a rectangle that grows from top to bottom for (uint32_t y = 0; y < y_last; y++ ) { uint32_t* const restrict next_line = frame_top + ( fb.stride * y ); write_hline_gouraud_ABGR8888( 0, 64-1, 0x00ff0000, 0x00f0f000, next_line, fb.w ); write_hline_gouraud_ABGR8888( 64, fb.w-64-1, 0x0000ff00, 0x000000ff, next_line, fb.w ); write_hline_gouraud_ABGR8888( fb.w-64, fb.w-1, 0x00ff00ff, 0x0000f0f0, next_line, fb.w ); } // Draw a little sprite on a sine wave. sprite_t += 0.08f; // Update position sprite_prev_t [ frame_ndx ] = sprite_t; { float sprite_amp = sinf( sprite_t ); uint32_t sprite_left = (uint32_t)(sprite_t * 0.03f * (float)fb.w); uint32_t sprite_top = (fb.h>>1) + (uint32_t)(sprite_amp * (float)((fb.h-128)>>1)); uint32_t sprite_right = sprite_left + 64; uint32_t sprite_bottom = sprite_top + 64; uint32_t sprite_middle = sprite_left + (( sprite_right - sprite_left ) >> 1); uint32_t sprite_cr = ( (uint32_t)(sprite_amp * 127.0f) + 128 ) & 0x000000ff; uint32_t sprite_cg = ( (uint32_t)(sprite_amp * 127.0f) + 128 ) & 0x000000ff; uint32_t sprite_cb = ( (uint32_t)(sprite_amp * 127.0f) + 128 ) & 0x000000ff; uint32_t sprite_crgb = sprite_cr | ( sprite_cg << 8 ) | ( sprite_cb << 16 ); for (uint32_t y = sprite_top;y < sprite_bottom;y++) { uint32_t* const restrict next_line = frame_top + ( fb.stride * y ); write_hline_gouraud_ABGR8888( sprite_left, sprite_middle-1, 0x007f1e00, sprite_crgb, next_line, fb.w ); write_hline_gouraud_ABGR8888( sprite_middle, sprite_right-1, sprite_crgb, 0x001e7f00, next_line, fb.w ); } } // At the vsync, the previous frame is finished sending to the CRT cp_fb_wait_vsync( &fb ); // Send the frame just drawn to the CRT by the next vblank cp_fb_flip( &fb, frame_ndx ); frame_ndx = frame_ndx ^ 0x01; } cp_vt_close(&vt); cp_fb_close(&fb); return (0); } void write_hline_gouraud_ABGR8888( int32_t x0, int32_t x1, uint32_t left_rgba, uint32_t right_rgba, void* dest_buffer, uint16_t width ) { uint32_t left_r; uint32_t left_g; uint32_t left_b; uint32_t left_a; uint32_t step_r; uint32_t step_g; uint32_t step_b; uint32_t step_a; if ( (x1-x0+1) == 0 ) { return; } /* Setup rgbas */ { uint32_t right_r; uint32_t right_g; uint32_t right_b; uint32_t right_a; uint32_t step_scale; left_r = ( ( left_rgba ) & 0x000000ff ); left_g = ( ( left_rgba >> 8 ) & 0x000000ff ); left_b = ( ( left_rgba >> 16 ) & 0x000000ff ); left_a = ( ( left_rgba >> 24 ) & 0x000000ff ); right_r = ( ( right_rgba ) & 0x000000ff ); right_g = ( ( right_rgba >> 8 ) & 0x000000ff ); right_b = ( ( right_rgba >> 16 ) & 0x000000ff ); right_a = ( ( right_rgba >> 24 ) & 0x000000ff ); step_scale = (1<<16) / (x1-x0+1); step_r = ( ( right_r - left_r ) * step_scale ); step_g = ( ( right_g - left_g ) * step_scale ); step_b = ( ( right_b - left_b ) * step_scale ); step_a = ( ( right_a - left_a ) * step_scale ); left_r <<= 16; left_g <<= 16; left_b <<= 16; left_a <<= 16; left_r += (1<<16)>>1; left_g += (1<<16)>>1; left_b += (1<<16)>>1; left_a += (1<<16)>>1; } /* Write to buffer */ { uint32_t* restrict dest_pixel; int32_t x; if ( x0 < 0 ) { left_r += step_r * (-x0); left_g += step_g * (-x0); left_b += step_b * (-x0); left_a += step_a * (-x0); x0 = 0; } if ( x1 >= (int32_t)width ) { x1 = width-1; } dest_pixel = (uint32_t*)dest_buffer + x0; for (x=x0;x<=x1;x++) { uint32_t rgba; rgba = ( ( left_b >> 16 ) & 0x000000ff ); rgba |= ( ( left_g >> 16 ) & 0x000000ff ) << 8; rgba |= ( ( left_r >> 16 ) & 0x000000ff ) << 16; rgba |= ( ( left_a >> 16 ) & 0x000000ff ) << 24; *dest_pixel = rgba; dest_pixel++; left_r += step_r; left_g += step_g; left_b += step_b; left_a += step_a; } } }