view old/framebuffer/fb_test-1.c @ 979:e0c254a9a865

add rest
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 01 Oct 2010 22:13:11 +0900
parents
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;
    }
  }
}