gu_draw.c.svn-base
来自「psp播放器PPA源码,在MSYS/CYGWIN环境下编译(GNU-C)」· SVN-BASE 代码 · 共 1,041 行 · 第 1/3 页
SVN-BASE
1,041 行
/*
PMP Mod
Copyright (C) 2006 jonny
Homepage: http://jonny.leffe.dnsalias.com
E-mail: jonny@leffe.dnsalias.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
gu routines
*/
#include "gu_draw.h"
#include <psprtc.h>
#include <png.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int __attribute__((aligned(16))) pmp_gu_list[262144];
static unsigned char __attribute__((aligned(64))) luminosity_textures[64 * number_of_luminosity_boosts] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 12, 12, 12, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 20, 20, 20, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 24, 24, 24, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 28, 28, 28, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 32, 32, 32, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 36, 36, 36, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 44, 44, 44, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0, 60, 60, 60, 0};
typedef void (*f_pmp_gu_draw)(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, void *);
//static unsigned char __attribute__((aligned(64))) static_rgb_buffer[0x1E0000];
void *pmp_gu_draw_buffer;
void *pmp_gu_rgb_buffer;
static unsigned int previous_aspect_ratio;static unsigned int previous_zoom;static unsigned int previous_subtitle;static unsigned int previous_info;
static unsigned int previous_interface;
static unsigned int output_left;
static unsigned int output_top;
static unsigned int output_width;
static unsigned int output_height;
static unsigned int output_inversion = 0;static f_pmp_gu_draw p_pmp_gu_draw;
void pmp_gu_draw_without_tvout_supported(unsigned int aspect_ratio, unsigned int zoom, unsigned int luminosity_boost, unsigned int show_interface, unsigned int show_subtitle, unsigned int subtitle_format, unsigned int frame_number, void *video_frame_buffer);
void pmp_gu_draw_psplcd(unsigned int aspect_ratio, unsigned int zoom, unsigned int luminosity_boost, unsigned int show_interface, unsigned int show_subtitle, unsigned int subtitle_format, unsigned int frame_number, void *video_frame_buffer);void pmp_gu_draw_tvout_interlace(unsigned int aspect_ratio, unsigned int zoom, unsigned int luminosity_boost, unsigned int show_interface, unsigned int show_subtitle, unsigned int subtitle_format, unsigned int frame_number, void *video_frame_buffer);
void pmp_gu_draw_tvout_progressive(unsigned int aspect_ratio, unsigned int zoom, unsigned int luminosity_boost, unsigned int show_interface, unsigned int show_subtitle, unsigned int subtitle_format, unsigned int frame_number, void *video_frame_buffer);
void gu_lcd_output_inversion_set()
{
output_inversion = (output_inversion+1) % 2;
}
void pmp_gu_init_previous_values() { previous_aspect_ratio = 0xffffffff; previous_zoom = 0xffffffff; previous_subtitle = 1; previous_info = 1;
previous_interface = 0; }
void pmp_gu_end()
{
sceGuStart(GU_DIRECT, pmp_gu_list);
sceGuClearColor(0); sceGuClear(GU_COLOR_BUFFER_BIT); sceGuFinish(); sceGuSync(0, 0);
}
void pmp_gu_start_without_tvout_supported()
{
p_pmp_gu_draw = pmp_gu_draw_without_tvout_supported;
pmp_gu_draw_buffer = (void *) 0x04000000;
pmp_gu_rgb_buffer = pmp_gu_draw_buffer + (4 * 512 * 272);
memset(pmp_gu_rgb_buffer, 0, 4 * 768 * 480);
// pmp_gu_rgb_buffer = static_rgb_buffer;
// memset(pmp_gu_rgb_buffer, 0, 4 * 1024 * 480);
sceKernelDcacheWritebackInvalidateAll();
}
void pmp_gu_start_psplcd()
{
p_pmp_gu_draw = pmp_gu_draw_psplcd;
pmp_gu_draw_buffer = (void *) (0x04000000);
pmp_gu_rgb_buffer = (void*)0x0a000000;
memset(pmp_gu_rgb_buffer, 0, 4 * 768 * 480);
// pmp_gu_rgb_buffer = static_rgb_buffer;
// memset(pmp_gu_rgb_buffer, 0, 4 * 1024 * 480);
sceKernelDcacheWritebackInvalidateAll();
}
void pmp_gu_start_tvout_interlace()
{
p_pmp_gu_draw = pmp_gu_draw_tvout_interlace;
pmp_gu_draw_buffer = (void *) (0x04000000);
pmp_gu_rgb_buffer = (void*)0x0a000000;
memset(pmp_gu_rgb_buffer, 0, 4 * 768 * 480);
// pmp_gu_rgb_buffer = static_rgb_buffer;
// memset(pmp_gu_rgb_buffer, 0, 4 * 1024 * 480);
sceKernelDcacheWritebackInvalidateAll();
}
void pmp_gu_start_tvout_progressive()
{
p_pmp_gu_draw = pmp_gu_draw_tvout_progressive;
pmp_gu_draw_buffer = (void *) (0x04000000);
pmp_gu_rgb_buffer = (void*)0x0a000000;
memset(pmp_gu_rgb_buffer, 0, 4 * 768 * 480);
// pmp_gu_rgb_buffer = static_rgb_buffer;
// memset(pmp_gu_rgb_buffer, 0, 4 * 1024 * 480);
sceKernelDcacheWritebackInvalidateAll();
}
void pmp_gu_start(int psp_type, int tv_aspectratio, int tv_overscan_left, int tv_overscan_top, int tv_overscan_right, int tv_overscan_bottom, int video_mode)
{
sceGuStart(GU_DIRECT, pmp_gu_list);
sceGuClearColor(0); sceGuClear(GU_COLOR_BUFFER_BIT); sceGuFinish(); sceGuSync(0, 0);
if (!m33IsTVOutSupported(psp_type))
{
output_left = 0;
output_top = 0;
output_width = 480;
output_height = 272;
gu_font_output_set(output_left, output_top, output_width, output_height);
pmp_gu_start_without_tvout_supported();
}
else
{
if (video_mode == 0 )
{
output_left = 0;
output_top = 0;
output_width = 480;
output_height = 272;
gu_font_output_set(output_left, output_top, output_width, output_height);
pmp_gu_start_psplcd();
}
else
{
output_left = tv_overscan_left;
output_top = tv_overscan_top;
output_width = 720 - tv_overscan_left - tv_overscan_right;
output_height = 480 - tv_overscan_top - tv_overscan_bottom;
gu_font_output_set(output_left, output_top, output_width, output_height);
if (video_mode == 1 || video_mode == 2)
{
pmp_gu_start_tvout_interlace();
}
else
{
pmp_gu_start_tvout_progressive();
}
}
}
}
void pmp_gu_wait()
{
sceGuSync(0, 0);
}
static void pmp_gu_load(void *image, int texture_width, int filter)
{
sceGuDisable(GU_BLEND);
sceGuTexMode(GU_PSM_8888, 0, 0, 0);
sceGuTexImage(0, 512, 512, texture_width, image);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
sceGuTexFilter(filter, filter);
sceGuTexWrap(GU_CLAMP, GU_CLAMP);
}
static void pmp_gu_load_luminosity_texture(void *image)
{
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xffffff, 0xffffff);
sceGuTexMode(GU_PSM_8888, 0, 0, 0);
sceGuTexImage(0, 4, 4, 4, image);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
sceGuTexWrap(GU_CLAMP, GU_CLAMP);
}
static void pmp_gu_load_interface_texture(void *image)
{
sceGuEnable(GU_BLEND); sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); sceGuTexMode(GU_PSM_8888, 0, 0, 0); sceGuTexImage(0, 512, 512, 512, image); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); sceGuTexFilter(GU_NEAREST, GU_NEAREST); sceGuTexWrap(GU_CLAMP, GU_CLAMP);
}
static void pmp_gu_draw_sprite(struct texture_subdivision_struct *t)
{
struct vertex_struct *v = sceGuGetMemory(2 * sizeof(struct vertex_struct));
v[0].texture_x = t->output_texture_x_start;
v[0].texture_y = t->output_texture_y_start;
v[0].vertex_x = (int) t->output_vertex_x_start;
v[0].vertex_y = t->output_vertex_y_start;
v[0].vertex_z = 0.0;
v[1].texture_x = t->output_texture_x_end;
v[1].texture_y = t->output_texture_y_end;
v[1].vertex_x = (int) t->output_vertex_x_end;
v[1].vertex_y = t->output_vertex_y_end;
v[1].vertex_z = 0.0;
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2, 0, v);
}
static void pmp_gu_draw_sprite_180(struct texture_subdivision_struct *t, int w, int h)
{
struct vertex_struct *v = sceGuGetMemory(2 * sizeof(struct vertex_struct));
v[0].texture_x = t->output_texture_x_start;
v[0].texture_y = t->output_texture_y_start;
v[0].vertex_x = (w) - (int) t->output_vertex_x_start;
v[0].vertex_y = (h) - t->output_vertex_y_start;
v[0].vertex_z = 0.0;
v[1].texture_x = t->output_texture_x_end;
v[1].texture_y = t->output_texture_y_end;
v[1].vertex_x = (w) - (int) t->output_vertex_x_end;
v[1].vertex_y = (h) - t->output_vertex_y_end;
v[1].vertex_z = 0.0;
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2, 0, v);
}
void pmp_gu_draw(unsigned int aspect_ratio, unsigned int zoom, unsigned int luminosity_boost, unsigned int show_interface, unsigned int show_subtitle, unsigned int subtitle_format, unsigned int frame_number, void *video_frame_buffer)
{
p_pmp_gu_draw(aspect_ratio, zoom, luminosity_boost, show_interface, show_subtitle, subtitle_format, frame_number, video_frame_buffer);
}
void pmp_gu_draw_without_tvout_supported(unsigned int aspect_ratio, unsigned int zoom, unsigned int luminosity_boost, unsigned int show_interface, unsigned int show_subtitle, unsigned int subtitle_format, unsigned int frame_number, void *video_frame_buffer)
{
short texture_width = aspect_ratios[0].width;
short texture_height = aspect_ratios[0].height;
int vertex_width = aspect_ratios[aspect_ratio].psp_width;
int vertex_height = aspect_ratios[aspect_ratio].psp_height;
vertex_width = zoom * vertex_width / 100;
vertex_height = zoom * vertex_height / 100;
int vertex_x = output_left + (output_width >> 1) - (vertex_width >> 1);
int vertex_y = output_top + (output_height >> 1) - (vertex_height >> 1);
int filter;
if ((texture_width == vertex_width) && (texture_height == vertex_height))
{
filter = GU_NEAREST;
}
else
{
filter = GU_LINEAR;
}
sceGuStart(GU_DIRECT, pmp_gu_list);
if ((previous_aspect_ratio != aspect_ratio) || (previous_zoom != zoom) || (previous_interface != show_interface) || ((vertex_width < output_width || vertex_height < output_height) && (previous_subtitle || previous_info))) {
sceGuClearColor(0); sceGuClear(GU_COLOR_BUFFER_BIT); previous_aspect_ratio = aspect_ratio; previous_zoom = zoom; previous_subtitle = 0; previous_info = 0;
previous_interface = show_interface; }
struct texture_subdivision_struct texture_subdivision;
if ( texture_width > 512 ) {
short texture_x = 0;
if ( texture_width == 720 && texture_height == 480 ) {
texture_width = 704;
texture_x = 8;
}
int part_width = 512 * vertex_width / texture_width;
pmp_gu_load(pmp_gu_rgb_buffer+texture_x*4, 768, filter);
texture_subdivision_constructor(&texture_subdivision, 512, texture_height, 16, part_width, vertex_height, vertex_x, vertex_y);
do
{
texture_subdivision_get(&texture_subdivision);
if ( output_inversion )
pmp_gu_draw_sprite_180(&texture_subdivision, 480, 272);
else
pmp_gu_draw_sprite(&texture_subdivision);
}
while (texture_subdivision.output_last == 0);
pmp_gu_load(pmp_gu_rgb_buffer+(texture_x+512)*4, 768, filter);
texture_subdivision_constructor(&texture_subdivision, texture_width-512, texture_height, 16, vertex_width-part_width, vertex_height, vertex_x+part_width, vertex_y);
do
{
texture_subdivision_get(&texture_subdivision);
if ( output_inversion )
pmp_gu_draw_sprite_180(&texture_subdivision, 480, 272);
else
pmp_gu_draw_sprite(&texture_subdivision);
}
while (texture_subdivision.output_last == 0);
}
else {
pmp_gu_load(pmp_gu_rgb_buffer, 512, filter);
texture_subdivision_constructor(&texture_subdivision, texture_width, texture_height, 16, vertex_width, vertex_height, vertex_x, vertex_y);
do
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?