mirror of
https://github.com/ctruLua/ctruLua.git
synced 2025-10-28 08:49:30 +00:00
Updated all the libs, added citro3d, added ctr.swkbd (WIP, untested)
This commit is contained in:
parent
68a44645f7
commit
49c87e5526
97 changed files with 7341 additions and 944 deletions
13
libs/sf2dlib/.gitignore
vendored
13
libs/sf2dlib/.gitignore
vendored
|
|
@ -2,6 +2,13 @@
|
|||
*.o
|
||||
*.project
|
||||
*.cproject
|
||||
libsf2d/.settings/*
|
||||
libsf2d/build/*
|
||||
libsf2d/lib/*
|
||||
*.3dsx
|
||||
*.cia
|
||||
*.cxi
|
||||
*.ncch
|
||||
*.3ds
|
||||
*.elf
|
||||
*.smdh
|
||||
build/
|
||||
lib/
|
||||
.settings/
|
||||
|
|
|
|||
|
|
@ -24,18 +24,16 @@ INCLUDES := include
|
|||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||
|
||||
CFLAGS := -g -Wall -O2\
|
||||
$(ARCH)
|
||||
CFLAGS := -g -Wall -Werror -O2 -mword-relocations \
|
||||
-ffunction-sections -fno-strict-aliasing \
|
||||
-fomit-frame-pointer \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
|
||||
#CFLAGS += -std=c11
|
||||
|
||||
#WILL HAVE TO BE REMOVED SOON
|
||||
CFLAGS += -DLIBCTRU_NO_DEPRECATION
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
|
||||
|
|
@ -43,7 +41,8 @@ ASFLAGS := -g $(ARCH)
|
|||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(CTRULIB)
|
||||
LIBDIRS := $(CTRULIB) \
|
||||
$(CURDIR)/../../citro3d
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
|
@ -62,6 +61,8 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
|
|||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica)))
|
||||
SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
@ -79,6 +80,7 @@ endif
|
|||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
|
|
@ -128,18 +130,29 @@ $(OUTPUT) : $(OFILES)
|
|||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
# WARNING: This is not the right way to do this! TODO: Do it right!
|
||||
#---------------------------------------------------------------------------------
|
||||
%.vsh.o : %.vsh
|
||||
# rules for assembling GPU shaders
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@picasso -o $(notdir $<).shbin $<
|
||||
@bin2s $(notdir $<).shbin | $(PREFIX)as -o $@
|
||||
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
define shader-as
|
||||
$(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@)))
|
||||
picasso -o $(CURBIN) $1
|
||||
bin2s $(CURBIN) | $(AS) -o $@
|
||||
echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
|
||||
echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h
|
||||
echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h
|
||||
endef
|
||||
|
||||
sf2d.c: shader.vsh
|
||||
%.shbin.o : %.v.pica %.g.pica
|
||||
@echo $(notdir $^)
|
||||
@$(call shader-as,$^)
|
||||
|
||||
%.shbin.o : %.v.pica
|
||||
@echo $(notdir $<)
|
||||
@$(call shader-as,$<)
|
||||
|
||||
%.shbin.o : %.shlist
|
||||
@echo $(notdir $<)
|
||||
@$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file)))
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
; Outputs
|
||||
.out outpos position
|
||||
.out outtc0 texcoord0
|
||||
.out outclr color
|
||||
|
||||
; Inputs
|
||||
.alias inpos v0
|
||||
.alias inarg v1
|
||||
|
||||
; Uniforms
|
||||
.fvec projection[4]
|
||||
|
||||
; Constants
|
||||
.constf RGBA8_TO_FLOAT4(0.00392156862, 0, 0, 0)
|
||||
|
||||
.proc main
|
||||
; outpos = projection * in.pos
|
||||
dp4 outpos.x, projection[0].wzyx, inpos
|
||||
dp4 outpos.y, projection[1].wzyx, inpos
|
||||
dp4 outpos.z, projection[2].wzyx, inpos
|
||||
dp4 outpos.w, projection[3].wzyx, inpos
|
||||
|
||||
; outtc0 = in.texcoord
|
||||
mov outtc0, inarg
|
||||
|
||||
; outclr = RGBA8_TO_FLOAT4(in.color)
|
||||
mul outclr, RGBA8_TO_FLOAT4.xxxx, inarg
|
||||
|
||||
end
|
||||
.end
|
||||
|
|
@ -4,10 +4,9 @@
|
|||
* @date 22 March 2015
|
||||
* @brief sf2dlib header
|
||||
*/
|
||||
#ifndef SF2D_H
|
||||
#define SF2D_H
|
||||
|
||||
#pragma once
|
||||
#include <3ds.h>
|
||||
#include <citro3d.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -83,7 +82,6 @@ typedef enum {
|
|||
typedef enum {
|
||||
SF2D_PLACE_RAM, /**< RAM allocated */
|
||||
SF2D_PLACE_VRAM, /**< VRAM allocated */
|
||||
SF2D_PLACE_TEMP /**< Temporary memory pool allocated */
|
||||
} sf2d_place;
|
||||
|
||||
// Structs
|
||||
|
|
@ -131,21 +129,15 @@ typedef struct {
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
sf2d_place place; /**< Where the texture data resides, RAM or VRAM */
|
||||
int tiled; /**< Whether the tetxure is tiled or not */
|
||||
sf2d_texfmt pixel_format; /**< Pixel format */
|
||||
u32 params; /**< Texture filters and wrapping */
|
||||
int width; /**< Texture width */
|
||||
int height; /**< Texture height */
|
||||
int pow2_w; /**< Nearest power of 2 >= width */
|
||||
int pow2_h; /**< Nearest power of 2 >= height */
|
||||
int data_size; /**< Size of the raw texture data */
|
||||
void *data; /**< Pointer to the data */
|
||||
C3D_Tex tex; /**< citro3d texture object */
|
||||
int tiled; /**< Whether the texture is tiled or not */
|
||||
int width; /**< Actual texture width */
|
||||
int height; /**< Actual texture height */
|
||||
} sf2d_texture;
|
||||
|
||||
typedef struct {
|
||||
sf2d_texture texture; // "inherit"/extend standard texture
|
||||
float projection[4*4]; /**< Orthographic projection matrix for this target */
|
||||
C3D_RenderTarget* target; /**< citro3d render target object */
|
||||
C3D_Mtx projection; /**< Orthographic projection matrix for this target */
|
||||
} sf2d_rendertarget;
|
||||
|
||||
// Basic functions
|
||||
|
|
@ -176,6 +168,12 @@ int sf2d_fini();
|
|||
*/
|
||||
void sf2d_set_3D(int enable);
|
||||
|
||||
/**
|
||||
* @brief Sets a transformation matrix to apply to vertices
|
||||
* @param mtx Transformation matrix (or NULL to disable it)
|
||||
*/
|
||||
void sf2d_set_transform(C3D_Mtx* mtx);
|
||||
|
||||
/**
|
||||
* @brief Starts a frame
|
||||
* @param screen target screen
|
||||
|
|
@ -416,14 +414,6 @@ void sf2d_bind_texture(const sf2d_texture *texture, GPU_TEXUNIT unit);
|
|||
*/
|
||||
void sf2d_bind_texture_color(const sf2d_texture *texture, GPU_TEXUNIT unit, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Binds a texture to a GPU texture unit with custom parameters
|
||||
* @param texture the texture to bind
|
||||
* @param unit GPU texture unit to bind to
|
||||
* @param params the parameters the bind with the texture
|
||||
*/
|
||||
void sf2d_bind_texture_parameters(const sf2d_texture *texture, GPU_TEXUNIT unit, unsigned int params);
|
||||
|
||||
/**
|
||||
* @brief Changes the texture params (filters and wrapping)
|
||||
* @param texture the texture to change the params
|
||||
|
|
@ -633,24 +623,6 @@ void sf2d_draw_texture_part_rotate_scale(const sf2d_texture *texture, int x, int
|
|||
*/
|
||||
void sf2d_draw_texture_part_rotate_scale_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Draws a part of a texture, with rotation, scaling, color and hotspot
|
||||
* @param texture the texture to draw
|
||||
* @param x the x coordinate to draw the texture to
|
||||
* @param y the y coordinate to draw the texture to
|
||||
* @param rad rotation (in radians) to draw the texture
|
||||
* @param tex_x the starting point (x coordinate) where to start drawing
|
||||
* @param tex_y the starting point (y coordinate) where to start drawing
|
||||
* @param tex_w the width to draw from the starting point
|
||||
* @param tex_h the height to draw from the starting point
|
||||
* @param x_scale the x scale
|
||||
* @param y_scale the y scale
|
||||
* @param center_x the x position of the hotspot
|
||||
* @param center_y the y position of the hotspot
|
||||
* @param color the color to blend with the texture
|
||||
*/
|
||||
void sf2d_draw_texture_part_rotate_scale_hotspot_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, float center_x, float center_y, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Draws a texture blended in a certain depth
|
||||
* @param texture the texture to draw
|
||||
|
|
@ -683,8 +655,7 @@ void sf2d_draw_texture_depth(const sf2d_texture *texture, int x, int y, signed s
|
|||
void sf2d_draw_texture_depth_blend(const sf2d_texture *texture, int x, int y, signed short z, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Draws a texture using custom texture coordinates and parameters
|
||||
* @param texture the texture to draw
|
||||
* @brief Draws the currently-bound texture using custom texture coordinates
|
||||
* @param left the left coordinate of the texture to start drawing
|
||||
* @param top the top coordinate of the texture to start drawing
|
||||
* @param width the width to draw from the starting left coordinate
|
||||
|
|
@ -693,10 +664,24 @@ void sf2d_draw_texture_depth_blend(const sf2d_texture *texture, int x, int y, si
|
|||
* @param v0 the V texture coordinate of the top vertices
|
||||
* @param u1 the U texture coordinate of the right vertices
|
||||
* @param v1 the V texture coordinate of the bottom vertices
|
||||
* @param params the parameters to draw the texture with
|
||||
*/
|
||||
void sf2d_draw_quad_uv_current(float left, float top, float right, float bottom, float u0, float v0,
|
||||
float u1, float v1);
|
||||
|
||||
/**
|
||||
* @brief Like sf2d_draw_quad_uv_current, but binds the texture
|
||||
* @param texture the texture to draw
|
||||
**/
|
||||
void sf2d_draw_quad_uv(const sf2d_texture *texture, float left, float top, float right, float bottom,
|
||||
float u0, float v0, float u1, float v1, unsigned int params);
|
||||
float u0, float v0, float u1, float v1);
|
||||
|
||||
/**
|
||||
* @brief Like sf2d_draw_quad_uv_current, but binds the texture with the given blend color
|
||||
* @param texture the texture to draw
|
||||
* @param color the color to blend the texture with
|
||||
**/
|
||||
void sf2d_draw_quad_uv_blend(const sf2d_texture *texture, float left, float top, float right, float bottom,
|
||||
float u0, float v0, float u1, float v1, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Changes a pixel of the texture
|
||||
|
|
@ -749,5 +734,3 @@ gfx3dSide_t sf2d_get_current_side();
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef SF2D_PRIVATE_H
|
||||
#define SF2D_PRIVATE_H
|
||||
|
||||
#include <3ds.h>
|
||||
#include "sf2d.h"
|
||||
|
||||
|
||||
void GPU_SetDummyTexEnv(u8 num);
|
||||
|
||||
void sf2d_draw_rectangle_internal(const sf2d_vertex_pos_col *vertices);
|
||||
|
||||
// Vector operations
|
||||
|
||||
void vector_mult_matrix4x4(const float *msrc, const sf2d_vector_3f *vsrc, sf2d_vector_3f *vdst);
|
||||
|
||||
// Matrix operations
|
||||
|
||||
void matrix_copy(float *dst, const float *src);
|
||||
void matrix_identity4x4(float *m);
|
||||
void matrix_mult4x4(const float *src1, const float *src2, float *dst);
|
||||
void matrix_set_z_rotation(float *m, float rad);
|
||||
void matrix_rotate_z(float *m, float rad);
|
||||
void matrix_set_scaling(float *m, float x_scale, float y_scale, float z_scale);
|
||||
void matrix_swap_xy(float *m);
|
||||
|
||||
void matrix_init_orthographic(float *m, float left, float right, float bottom, float top, float near, float far);
|
||||
void matrix_gpu_set_uniform(const float *m, u32 startreg);
|
||||
|
||||
unsigned int next_pow2(unsigned int v);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,22 +1,13 @@
|
|||
#include <string.h>
|
||||
#include "sf2d.h"
|
||||
#include "sf2d_private.h"
|
||||
#include "shader_vsh_shbin.h"
|
||||
#include "shader_shbin.h"
|
||||
|
||||
|
||||
static int sf2d_initialized = 0;
|
||||
static u32 clear_color = 0;
|
||||
static u32 *gpu_cmd = NULL;
|
||||
//GPU init variables
|
||||
static int gpu_cmd_size = 0;
|
||||
// Temporary memory pool
|
||||
static void *pool_addr = NULL;
|
||||
static u32 pool_index = 0;
|
||||
static u32 pool_size = 0;
|
||||
//GPU framebuffer address
|
||||
static u32 *gpu_fb_addr = NULL;
|
||||
//GPU depth buffer address
|
||||
static u32 *gpu_depth_fb_addr = NULL;
|
||||
//VBlank wait
|
||||
static int vblank_wait = 1;
|
||||
//FPS calculation
|
||||
|
|
@ -29,19 +20,14 @@ static gfx3dSide_t cur_side = GFX_LEFT;
|
|||
//Shader stuff
|
||||
static DVLB_s *dvlb = NULL;
|
||||
static shaderProgram_s shader;
|
||||
static u32 projection_desc = -1;
|
||||
//Matrix
|
||||
static float ortho_matrix_top[4*4];
|
||||
static float ortho_matrix_bot[4*4];
|
||||
static int projection_desc = -1;
|
||||
static int transform_desc = -1;
|
||||
static int useTransform_desc = -1;
|
||||
//Rendertarget things
|
||||
static sf2d_rendertarget * currentRenderTarget = NULL;
|
||||
static void * targetDepthBuffer;
|
||||
static int targetDepthBufferLen = 0;
|
||||
//Apt hook cookie
|
||||
static aptHookCookie apt_hook_cookie;
|
||||
//Functions
|
||||
static void apt_hook_func(APT_HookType hook, void *param);
|
||||
static void reset_gpu_apt_resume();
|
||||
static sf2d_rendertarget * targetTopLeft;
|
||||
static sf2d_rendertarget * targetTopRight;
|
||||
static sf2d_rendertarget * targetBottom;
|
||||
static int in_render;
|
||||
|
||||
int sf2d_init()
|
||||
{
|
||||
|
|
@ -54,47 +40,43 @@ int sf2d_init_advanced(int gpucmd_size, int temppool_size)
|
|||
{
|
||||
if (sf2d_initialized) return 0;
|
||||
|
||||
gpu_fb_addr = vramMemAlign(400*240*8, 0x100);
|
||||
gpu_depth_fb_addr = vramMemAlign(400*240*8, 0x100);
|
||||
gpu_cmd = linearAlloc(gpucmd_size * 4);
|
||||
pool_addr = linearAlloc(temppool_size);
|
||||
pool_size = temppool_size;
|
||||
gpu_cmd_size = gpucmd_size;
|
||||
|
||||
gfxInitDefault();
|
||||
GPU_Init(NULL);
|
||||
gfxSet3D(false);
|
||||
GPU_Reset(NULL, gpu_cmd, gpucmd_size);
|
||||
C3D_Init(gpucmd_size*8);
|
||||
|
||||
//Setup rendertargets
|
||||
targetTopLeft = sf2d_create_rendertarget(400, 240);
|
||||
targetTopRight = sf2d_create_rendertarget(400, 240);
|
||||
targetBottom = sf2d_create_rendertarget(320, 240);
|
||||
sf2d_set_clear_color(0);
|
||||
C3D_RenderTargetSetOutput(targetTopLeft->target, GFX_TOP, GFX_LEFT, 0x1000);
|
||||
C3D_RenderTargetSetOutput(targetTopRight->target, GFX_TOP, GFX_RIGHT, 0x1000);
|
||||
C3D_RenderTargetSetOutput(targetBottom->target, GFX_BOTTOM, GFX_LEFT, 0x1000);
|
||||
|
||||
//Setup temp pool
|
||||
pool_addr = linearAlloc(temppool_size);
|
||||
pool_size = temppool_size;
|
||||
|
||||
//Setup the shader
|
||||
dvlb = DVLB_ParseFile((u32 *)shader_vsh_shbin, shader_vsh_shbin_size);
|
||||
dvlb = DVLB_ParseFile((u32 *)shader_shbin, shader_shbin_size);
|
||||
shaderProgramInit(&shader);
|
||||
shaderProgramSetVsh(&shader, &dvlb->DVLE[0]);
|
||||
|
||||
//Get shader uniform descriptors
|
||||
projection_desc = shaderInstanceGetUniformLocation(shader.vertexShader, "projection");
|
||||
transform_desc = shaderInstanceGetUniformLocation(shader.vertexShader, "transform");
|
||||
useTransform_desc = shaderInstanceGetUniformLocation(shader.vertexShader, "useTransform");
|
||||
|
||||
shaderProgramUse(&shader);
|
||||
|
||||
matrix_init_orthographic(ortho_matrix_top, 0.0f, 400.0f, 0.0f, 240.0f, 0.0f, 1.0f);
|
||||
matrix_init_orthographic(ortho_matrix_bot, 0.0f, 320.0f, 0.0f, 240.0f, 0.0f, 1.0f);
|
||||
matrix_gpu_set_uniform(ortho_matrix_top, projection_desc);
|
||||
|
||||
//Register the apt callback hook
|
||||
aptHook(&apt_hook_cookie, apt_hook_func, NULL);
|
||||
C3D_BindProgram(&shader);
|
||||
C3D_CullFace(GPU_CULL_NONE);
|
||||
C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL);
|
||||
C3D_BoolUnifSet(GPU_VERTEX_SHADER, useTransform_desc, false);
|
||||
|
||||
vblank_wait = 1;
|
||||
current_fps = 0.0f;
|
||||
frames = 0;
|
||||
last_time = osGetTime();
|
||||
|
||||
cur_screen = GFX_TOP;
|
||||
cur_side = GFX_LEFT;
|
||||
|
||||
GPUCMD_Finalize();
|
||||
GPUCMD_FlushAndRun();
|
||||
gspWaitForP3D();
|
||||
|
||||
sf2d_pool_reset();
|
||||
|
||||
sf2d_initialized = 1;
|
||||
|
|
@ -106,17 +88,12 @@ int sf2d_fini()
|
|||
{
|
||||
if (!sf2d_initialized) return 0;
|
||||
|
||||
aptUnhook(&apt_hook_cookie);
|
||||
linearFree(pool_addr);
|
||||
|
||||
gfxExit();
|
||||
shaderProgramFree(&shader);
|
||||
DVLB_Free(dvlb);
|
||||
|
||||
linearFree(pool_addr);
|
||||
linearFree(gpu_cmd);
|
||||
vramFree(gpu_fb_addr);
|
||||
vramFree(gpu_depth_fb_addr);
|
||||
linearFree(targetDepthBuffer);
|
||||
C3D_Fini();
|
||||
gfxExit();
|
||||
|
||||
sf2d_initialized = 0;
|
||||
|
||||
|
|
@ -128,143 +105,54 @@ void sf2d_set_3D(int enable)
|
|||
gfxSet3D(enable);
|
||||
}
|
||||
|
||||
void sf2d_set_transform(C3D_Mtx* mtx)
|
||||
{
|
||||
C3D_BoolUnifSet(GPU_VERTEX_SHADER, useTransform_desc, mtx != NULL);
|
||||
if (mtx) {
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, transform_desc, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
void sf2d_start_frame(gfxScreen_t screen, gfx3dSide_t side)
|
||||
{
|
||||
sf2d_pool_reset();
|
||||
GPUCMD_SetBufferOffset(0);
|
||||
cur_screen = screen;
|
||||
cur_side = side;
|
||||
|
||||
// Only upload the uniform if the screen changes
|
||||
if (screen != cur_screen) {
|
||||
if (screen == GFX_TOP) {
|
||||
matrix_gpu_set_uniform(ortho_matrix_top, projection_desc);
|
||||
} else {
|
||||
matrix_gpu_set_uniform(ortho_matrix_bot, projection_desc);
|
||||
}
|
||||
cur_screen = screen;
|
||||
}
|
||||
|
||||
int screen_w;
|
||||
if (screen == GFX_TOP) {
|
||||
screen_w = 400;
|
||||
cur_side = side;
|
||||
if (side == GFX_LEFT) {
|
||||
sf2d_start_frame_target(targetTopLeft);
|
||||
} else {
|
||||
sf2d_start_frame_target(targetTopRight);
|
||||
}
|
||||
} else {
|
||||
screen_w = 320;
|
||||
sf2d_start_frame_target(targetBottom);
|
||||
}
|
||||
GPU_SetViewport((u32 *)osConvertVirtToPhys(gpu_depth_fb_addr),
|
||||
(u32 *)osConvertVirtToPhys(gpu_fb_addr),
|
||||
0, 0, 240, screen_w);
|
||||
|
||||
GPU_DepthMap(-1.0f, 0.0f);
|
||||
GPU_SetFaceCulling(GPU_CULL_NONE);
|
||||
GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00);
|
||||
GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
|
||||
GPU_SetBlendingColor(0,0,0,0);
|
||||
GPU_SetDepthTestAndWriteMask(true, GPU_GEQUAL, GPU_WRITE_ALL);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_EARLYDEPTH_TEST1, 0x1, 0);
|
||||
GPUCMD_AddWrite(GPUREG_EARLYDEPTH_TEST2, 0);
|
||||
|
||||
GPU_SetAlphaBlending(
|
||||
GPU_BLEND_ADD,
|
||||
GPU_BLEND_ADD,
|
||||
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA,
|
||||
GPU_ONE, GPU_ZERO
|
||||
);
|
||||
|
||||
GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00);
|
||||
|
||||
GPU_SetDummyTexEnv(1);
|
||||
GPU_SetDummyTexEnv(2);
|
||||
GPU_SetDummyTexEnv(3);
|
||||
GPU_SetDummyTexEnv(4);
|
||||
GPU_SetDummyTexEnv(5);
|
||||
}
|
||||
|
||||
void sf2d_start_frame_target(sf2d_rendertarget *target)
|
||||
{
|
||||
sf2d_pool_reset();
|
||||
GPUCMD_SetBufferOffset(0);
|
||||
|
||||
// Upload saved uniform
|
||||
matrix_gpu_set_uniform(target->projection, projection_desc);
|
||||
|
||||
int bufferLen = target->texture.width * target->texture.height * 4; // apparently depth buffer is (or can be) 32bit?
|
||||
if (bufferLen > targetDepthBufferLen) { // expand depth buffer
|
||||
if (targetDepthBufferLen > 0) linearFree(targetDepthBuffer);
|
||||
targetDepthBuffer = linearAlloc(bufferLen);
|
||||
memset(targetDepthBuffer, 0, bufferLen);
|
||||
targetDepthBufferLen = bufferLen;
|
||||
if (!in_render) {
|
||||
sf2d_pool_reset();
|
||||
C3D_FrameBegin(vblank_wait ? C3D_FRAME_SYNCDRAW : 0);
|
||||
in_render = 1;
|
||||
}
|
||||
|
||||
GPU_SetViewport((u32 *)osConvertVirtToPhys(targetDepthBuffer),
|
||||
(u32 *)osConvertVirtToPhys(target->texture.data),
|
||||
0, 0, target->texture.height, target->texture.width);
|
||||
|
||||
currentRenderTarget = target;
|
||||
|
||||
GPU_DepthMap(-1.0f, 0.0f);
|
||||
GPU_SetFaceCulling(GPU_CULL_NONE);
|
||||
GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00);
|
||||
GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
|
||||
GPU_SetBlendingColor(0,0,0,0);
|
||||
GPU_SetDepthTestAndWriteMask(true, GPU_GEQUAL, GPU_WRITE_ALL);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_EARLYDEPTH_TEST1, 0x1, 0);
|
||||
GPUCMD_AddWrite(GPUREG_EARLYDEPTH_TEST2, 0);
|
||||
|
||||
GPU_SetAlphaBlending(
|
||||
GPU_BLEND_ADD,
|
||||
GPU_BLEND_ADD,
|
||||
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA,
|
||||
GPU_ONE, GPU_ZERO
|
||||
);
|
||||
|
||||
GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00);
|
||||
|
||||
GPU_SetDummyTexEnv(1);
|
||||
GPU_SetDummyTexEnv(2);
|
||||
GPU_SetDummyTexEnv(3);
|
||||
GPU_SetDummyTexEnv(4);
|
||||
GPU_SetDummyTexEnv(5);
|
||||
C3D_FrameDrawOn(target->target);
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, projection_desc, &target->projection);
|
||||
}
|
||||
|
||||
void sf2d_end_frame()
|
||||
{
|
||||
GPU_FinishDrawing();
|
||||
GPUCMD_Finalize();
|
||||
GPUCMD_FlushAndRun();
|
||||
gspWaitForP3D();
|
||||
|
||||
if (!currentRenderTarget) {
|
||||
//Copy the GPU rendered FB to the screen FB
|
||||
if (cur_screen == GFX_TOP) {
|
||||
GX_DisplayTransfer(gpu_fb_addr, GX_BUFFER_DIM(240, 400),
|
||||
(u32 *)gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL),
|
||||
GX_BUFFER_DIM(240, 400), 0x1000);
|
||||
} else {
|
||||
GX_DisplayTransfer(gpu_fb_addr, GX_BUFFER_DIM(240, 320),
|
||||
(u32 *)gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL),
|
||||
GX_BUFFER_DIM(240, 320), 0x1000);
|
||||
}
|
||||
gspWaitForPPF();
|
||||
|
||||
//Clear the screen
|
||||
GX_MemoryFill(
|
||||
gpu_fb_addr, clear_color, &gpu_fb_addr[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH,
|
||||
gpu_depth_fb_addr, 0, &gpu_depth_fb_addr[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH);
|
||||
gspWaitForPSC0();
|
||||
} else {
|
||||
//gspWaitForPPF();
|
||||
//gspWaitForPSC0();
|
||||
sf2d_texture_tile32(&(currentRenderTarget->texture));
|
||||
}
|
||||
currentRenderTarget = NULL;
|
||||
// Nothing
|
||||
}
|
||||
|
||||
void sf2d_swapbuffers()
|
||||
{
|
||||
gfxSwapBuffersGpu();
|
||||
if (vblank_wait) {
|
||||
gspWaitForEvent(GSPGPU_EVENT_VBlank0, false);
|
||||
}
|
||||
if (!in_render) return;
|
||||
|
||||
in_render = 0;
|
||||
C3D_FrameEnd(0);
|
||||
|
||||
//Calculate FPS
|
||||
frames++;
|
||||
u64 delta_time = osGetTime() - last_time;
|
||||
|
|
@ -323,19 +211,17 @@ void sf2d_pool_reset()
|
|||
|
||||
void sf2d_set_clear_color(u32 color)
|
||||
{
|
||||
// GX_SetMemoryFill wants the color inverted?
|
||||
clear_color = RGBA8_GET_R(color) << 24 |
|
||||
RGBA8_GET_G(color) << 16 |
|
||||
RGBA8_GET_B(color) << 8 |
|
||||
RGBA8_GET_A(color) << 0;
|
||||
sf2d_clear_target(targetTopLeft, color);
|
||||
sf2d_clear_target(targetTopRight, color);
|
||||
sf2d_clear_target(targetBottom, color);
|
||||
}
|
||||
|
||||
void sf2d_set_scissor_test(GPU_SCISSORMODE mode, u32 x, u32 y, u32 w, u32 h)
|
||||
{
|
||||
if (cur_screen == GFX_TOP) {
|
||||
GPU_SetScissorTest(mode, 240 - (y + h), 400 - (x + w), 240 - y, 400 - x);
|
||||
C3D_SetScissor(mode, 240 - (y + h), 400 - (x + w), 240 - y, 400 - x);
|
||||
} else {
|
||||
GPU_SetScissorTest(mode, 240 - (y + h), 320 - (x + w), 240 - y, 320 - x);
|
||||
C3D_SetScissor(mode, 240 - (y + h), 320 - (x + w), 240 - y, 320 - x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -348,26 +234,3 @@ gfx3dSide_t sf2d_get_current_side()
|
|||
{
|
||||
return cur_side;
|
||||
}
|
||||
|
||||
static void apt_hook_func(APT_HookType hook, void *param)
|
||||
{
|
||||
if (hook == APTHOOK_ONRESTORE) {
|
||||
reset_gpu_apt_resume();
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_gpu_apt_resume()
|
||||
{
|
||||
GPU_Reset(NULL, gpu_cmd, gpu_cmd_size); // Only required for custom GPU cmd sizes
|
||||
shaderProgramUse(&shader);
|
||||
|
||||
if (cur_screen == GFX_TOP) {
|
||||
matrix_gpu_set_uniform(ortho_matrix_top, projection_desc);
|
||||
} else {
|
||||
matrix_gpu_set_uniform(ortho_matrix_bot, projection_desc);
|
||||
}
|
||||
|
||||
GPUCMD_Finalize();
|
||||
GPUCMD_FlushAndRun();
|
||||
gspWaitForP3D();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "sf2d.h"
|
||||
#include "sf2d_private.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_PI
|
||||
|
|
@ -7,27 +6,19 @@
|
|||
#endif
|
||||
|
||||
void sf2d_setup_env_internal(const sf2d_vertex_pos_col* vertices) {
|
||||
GPU_SetTexEnv(
|
||||
0,
|
||||
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
|
||||
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_REPLACE, GPU_REPLACE,
|
||||
0xFFFFFFFF
|
||||
);
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, 0, 0);
|
||||
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
|
||||
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_UNSIGNED_BYTE, 4);
|
||||
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_col), 2, 0x10);
|
||||
}
|
||||
|
||||
void sf2d_draw_line(float x0, float y0, float x1, float y1, float width, u32 color)
|
||||
|
|
@ -64,21 +55,21 @@ void sf2d_draw_line(float x0, float y0, float x1, float y1, float width, u32 col
|
|||
|
||||
sf2d_setup_env_internal(vertices);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_rectangle_internal(const sf2d_vertex_pos_col *vertices)
|
||||
{
|
||||
sf2d_setup_env_internal(vertices);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_triangle_internal(const sf2d_vertex_pos_col *vertices)
|
||||
{
|
||||
sf2d_setup_env_internal(vertices);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLES, 0, 3);
|
||||
C3D_DrawArrays(GPU_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color)
|
||||
|
|
@ -133,17 +124,14 @@ void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad
|
|||
vertices[2].color = vertices[0].color;
|
||||
vertices[3].color = vertices[0].color;
|
||||
|
||||
float m[4*4];
|
||||
matrix_set_z_rotation(m, rad);
|
||||
sf2d_vector_3f rot[4];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
vector_mult_matrix4x4(m, &vertices[i].position, &rot[i]);
|
||||
vertices[i].position = (sf2d_vector_3f){rot[i].x + x + w2, rot[i].y + y + h2, rot[i].z};
|
||||
}
|
||||
C3D_Mtx m;
|
||||
Mtx_Identity(&m);
|
||||
Mtx_Translate(&m, x+w2, y+h2, 0, true);
|
||||
Mtx_RotateZ(&m, rad, true);
|
||||
|
||||
sf2d_set_transform(&m);
|
||||
sf2d_draw_rectangle_internal(vertices);
|
||||
sf2d_set_transform(NULL);
|
||||
}
|
||||
|
||||
void sf2d_draw_rectangle_gradient(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction)
|
||||
|
|
@ -182,17 +170,14 @@ void sf2d_draw_rectangle_gradient_rotate(int x, int y, int w, int h, u32 color1,
|
|||
vertices[2].color = (direction == SF2D_LEFT_TO_RIGHT) ? color1 : color2;
|
||||
vertices[3].color = color2;
|
||||
|
||||
float m[4*4];
|
||||
matrix_set_z_rotation(m, rad);
|
||||
sf2d_vector_3f rot[4];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
vector_mult_matrix4x4(m, &vertices[i].position, &rot[i]);
|
||||
vertices[i].position = (sf2d_vector_3f){rot[i].x + x + w2, rot[i].y + y + h2, rot[i].z};
|
||||
}
|
||||
C3D_Mtx m;
|
||||
Mtx_Identity(&m);
|
||||
Mtx_Translate(&m, x+w2, y+h2, 0, true);
|
||||
Mtx_RotateZ(&m, rad, true);
|
||||
|
||||
sf2d_set_transform(&m);
|
||||
sf2d_draw_rectangle_internal(vertices);
|
||||
sf2d_set_transform(NULL);
|
||||
}
|
||||
|
||||
void sf2d_draw_fill_circle(int x, int y, int radius, u32 color)
|
||||
|
|
@ -227,5 +212,5 @@ void sf2d_draw_fill_circle(int x, int y, int radius, u32 color)
|
|||
|
||||
sf2d_setup_env_internal(vertices);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_FAN, 0, num_segments + 2);
|
||||
C3D_DrawArrays(GPU_TRIANGLE_FAN, 0, num_segments + 2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,150 +0,0 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "sf2d_private.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
//stolen from staplebutt
|
||||
void GPU_SetDummyTexEnv(u8 num)
|
||||
{
|
||||
GPU_SetTexEnv(num,
|
||||
GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0),
|
||||
GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0),
|
||||
GPU_TEVOPERANDS(0,0,0),
|
||||
GPU_TEVOPERANDS(0,0,0),
|
||||
GPU_REPLACE,
|
||||
GPU_REPLACE,
|
||||
0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void vector_mult_matrix4x4(const float *msrc, const sf2d_vector_3f *vsrc, sf2d_vector_3f *vdst)
|
||||
{
|
||||
vdst->x = msrc[0*4 + 0]*vsrc->x + msrc[0*4 + 1]*vsrc->y + msrc[0*4 + 2]*vsrc->z + msrc[0*4 + 3];
|
||||
vdst->y = msrc[1*4 + 0]*vsrc->x + msrc[1*4 + 1]*vsrc->y + msrc[1*4 + 2]*vsrc->z + msrc[1*4 + 3];
|
||||
vdst->z = msrc[2*4 + 0]*vsrc->x + msrc[2*4 + 1]*vsrc->y + msrc[2*4 + 2]*vsrc->z + msrc[2*4 + 3];
|
||||
}
|
||||
|
||||
void matrix_gpu_set_uniform(const float *m, u32 startreg)
|
||||
{
|
||||
GPU_SetFloatUniform(GPU_VERTEX_SHADER, startreg, (u32 *)m, 4);
|
||||
}
|
||||
|
||||
void matrix_copy(float *dst, const float *src)
|
||||
{
|
||||
memcpy(dst, src, sizeof(float)*4*4);
|
||||
}
|
||||
|
||||
void matrix_identity4x4(float *m)
|
||||
{
|
||||
m[0] = m[5] = m[10] = m[15] = 1.0f;
|
||||
m[1] = m[2] = m[3] = 0.0f;
|
||||
m[4] = m[6] = m[7] = 0.0f;
|
||||
m[8] = m[9] = m[11] = 0.0f;
|
||||
m[12] = m[13] = m[14] = 0.0f;
|
||||
}
|
||||
|
||||
void matrix_mult4x4(const float *src1, const float *src2, float *dst)
|
||||
{
|
||||
int i, j, k;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
dst[i*4 + j] = 0.0f;
|
||||
for (k = 0; k < 4; k++) {
|
||||
dst[i*4 + j] += src1[i*4 + k]*src2[k*4 + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_set_z_rotation(float *m, float rad)
|
||||
{
|
||||
float c = cosf(rad);
|
||||
float s = sinf(rad);
|
||||
|
||||
matrix_identity4x4(m);
|
||||
|
||||
m[0] = c;
|
||||
m[1] = -s;
|
||||
m[4] = s;
|
||||
m[5] = c;
|
||||
}
|
||||
|
||||
void matrix_rotate_z(float *m, float rad)
|
||||
{
|
||||
float mr[4*4], mt[4*4];
|
||||
matrix_set_z_rotation(mr, rad);
|
||||
matrix_mult4x4(mr, m, mt);
|
||||
matrix_copy(m, mt);
|
||||
}
|
||||
|
||||
void matrix_set_scaling(float *m, float x_scale, float y_scale, float z_scale)
|
||||
{
|
||||
matrix_identity4x4(m);
|
||||
m[0] = x_scale;
|
||||
m[5] = y_scale;
|
||||
m[10] = z_scale;
|
||||
}
|
||||
|
||||
void matrix_swap_xy(float *m)
|
||||
{
|
||||
float ms[4*4], mt[4*4];
|
||||
matrix_identity4x4(ms);
|
||||
|
||||
ms[0] = 0.0f;
|
||||
ms[1] = 1.0f;
|
||||
ms[4] = 1.0f;
|
||||
ms[5] = 0.0f;
|
||||
|
||||
matrix_mult4x4(ms, m, mt);
|
||||
matrix_copy(m, mt);
|
||||
}
|
||||
|
||||
void matrix_init_orthographic(float *m, float left, float right, float bottom, float top, float near, float far)
|
||||
{
|
||||
float mo[4*4], mp[4*4];
|
||||
|
||||
mo[0x0] = 2.0f/(right-left);
|
||||
mo[0x1] = 0.0f;
|
||||
mo[0x2] = 0.0f;
|
||||
mo[0x3] = -(right+left)/(right-left);
|
||||
|
||||
mo[0x4] = 0.0f;
|
||||
mo[0x5] = 2.0f/(top-bottom);
|
||||
mo[0x6] = 0.0f;
|
||||
mo[0x7] = -(top+bottom)/(top-bottom);
|
||||
|
||||
mo[0x8] = 0.0f;
|
||||
mo[0x9] = 0.0f;
|
||||
mo[0xA] = -2.0f/(far-near);
|
||||
mo[0xB] = (far+near)/(far-near);
|
||||
|
||||
mo[0xC] = 0.0f;
|
||||
mo[0xD] = 0.0f;
|
||||
mo[0xE] = 0.0f;
|
||||
mo[0xF] = 1.0f;
|
||||
|
||||
matrix_identity4x4(mp);
|
||||
mp[0xA] = 0.5;
|
||||
mp[0xB] = -0.5;
|
||||
|
||||
//Convert Z [-1, 1] to [-1, 0] (PICA shiz)
|
||||
matrix_mult4x4(mp, mo, m);
|
||||
// Rotate 180 degrees
|
||||
matrix_rotate_z(m, M_PI);
|
||||
// Swap X and Y axis
|
||||
matrix_swap_xy(m);
|
||||
}
|
||||
|
||||
//Grabbed from: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
unsigned int next_pow2(unsigned int v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return v+1;
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "sf2d.h"
|
||||
#include "sf2d_private.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265358979323846)
|
||||
|
|
@ -10,159 +9,98 @@
|
|||
|
||||
#define TEX_MIN_SIZE 32
|
||||
|
||||
static unsigned int nibbles_per_pixel(sf2d_texfmt format)
|
||||
//Grabbed from: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
unsigned int next_pow2(unsigned int v)
|
||||
{
|
||||
switch (format) {
|
||||
case TEXFMT_RGBA8:
|
||||
return 8;
|
||||
case TEXFMT_RGB8:
|
||||
return 6;
|
||||
case TEXFMT_RGB5A1:
|
||||
case TEXFMT_RGB565:
|
||||
case TEXFMT_RGBA4:
|
||||
case TEXFMT_IA8:
|
||||
return 4;
|
||||
case TEXFMT_A4:
|
||||
return 1;
|
||||
case TEXFMT_I8:
|
||||
case TEXFMT_A8:
|
||||
case TEXFMT_IA4:
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int calc_buffer_size(sf2d_texfmt pixel_format, int width, int height)
|
||||
{
|
||||
return width * height * (nibbles_per_pixel(pixel_format)>>1);
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v >= TEX_MIN_SIZE ? v : TEX_MIN_SIZE;
|
||||
}
|
||||
|
||||
sf2d_texture *sf2d_create_texture(int width, int height, sf2d_texfmt pixel_format, sf2d_place place)
|
||||
{
|
||||
int pow2_w = next_pow2(width);
|
||||
int pow2_h = next_pow2(height);
|
||||
|
||||
if (pow2_w < TEX_MIN_SIZE) pow2_w = TEX_MIN_SIZE;
|
||||
if (pow2_h < TEX_MIN_SIZE) pow2_h = TEX_MIN_SIZE;
|
||||
|
||||
int data_size = calc_buffer_size(pixel_format, pow2_w, pow2_h);
|
||||
void *data;
|
||||
sf2d_texture *texture = calloc(1, sizeof(*texture));
|
||||
if (!texture) return NULL;
|
||||
|
||||
bool success = false;
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
if (place == SF2D_PLACE_RAM) {
|
||||
// If there's not enough linear heap space, return
|
||||
if (linearSpaceFree() < data_size) {
|
||||
return NULL;
|
||||
}
|
||||
data = linearMemAlign(data_size, 0x80);
|
||||
success = C3D_TexInit(&texture->tex, next_pow2(width), next_pow2(height), pixel_format);
|
||||
} else if (place == SF2D_PLACE_VRAM) {
|
||||
// If there's not enough VRAM heap space, return
|
||||
if (vramSpaceFree() < data_size) {
|
||||
return NULL;
|
||||
}
|
||||
data = vramMemAlign(data_size, 0x80);
|
||||
} else if (place == SF2D_PLACE_TEMP) {
|
||||
if (sf2d_pool_space_free() < data_size) {
|
||||
return NULL;
|
||||
}
|
||||
data = sf2d_pool_memalign(data_size, 0x80);
|
||||
} else {
|
||||
//wot?
|
||||
success = C3D_TexInitVRAM(&texture->tex, next_pow2(width), next_pow2(height), pixel_format);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
free(texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sf2d_texture *texture = malloc(sizeof(*texture));
|
||||
|
||||
texture->tiled = 0;
|
||||
texture->place = place;
|
||||
texture->pixel_format = pixel_format;
|
||||
texture->params = GPU_TEXTURE_MAG_FILTER(GPU_NEAREST)
|
||||
| GPU_TEXTURE_MIN_FILTER(GPU_NEAREST)
|
||||
| GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_BORDER)
|
||||
| GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_BORDER);
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
texture->pow2_w = pow2_w;
|
||||
texture->pow2_h = pow2_h;
|
||||
texture->data_size = data_size;
|
||||
texture->data = data;
|
||||
|
||||
if (place == SF2D_PLACE_VRAM) {
|
||||
GX_MemoryFill(texture->data, 0x00000000, (u32*)&((u8*)texture->data)[texture->data_size], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH,
|
||||
NULL, 0x00000000, NULL, 0);
|
||||
gspWaitForPSC0();
|
||||
} else {
|
||||
memset(texture->data, 0, texture->data_size);
|
||||
}
|
||||
|
||||
C3D_TexSetWrap(&texture->tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
|
||||
return texture;
|
||||
}
|
||||
|
||||
sf2d_rendertarget *sf2d_create_rendertarget(int width, int height)
|
||||
{
|
||||
sf2d_texture *tx = sf2d_create_texture(width, height, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
||||
sf2d_rendertarget *rt = malloc(sizeof(*rt));
|
||||
//memcpy(rt, tx, sizeof(*tx));
|
||||
rt->texture = *tx;
|
||||
free(tx);
|
||||
//tx = * rt->texture;
|
||||
//rt->projection
|
||||
sf2d_rendertarget *rt = calloc(1, sizeof(*rt));
|
||||
if (!rt) return NULL;
|
||||
|
||||
matrix_init_orthographic(rt->projection, 0.0f, width, height, 0.0f, 0.0f, 1.0f);
|
||||
matrix_rotate_z(rt->projection, M_PI / 2.0f);
|
||||
rt->target = C3D_RenderTargetCreate(height, width, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
if (!rt->target)
|
||||
{
|
||||
free(rt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Mtx_OrthoTilt(&rt->projection, 0.0f, width, height, 0.0f, 0.0f, 1.0f, true);
|
||||
return rt;
|
||||
}
|
||||
|
||||
void sf2d_free_texture(sf2d_texture *texture)
|
||||
{
|
||||
if (texture) {
|
||||
if (texture->place == SF2D_PLACE_RAM) {
|
||||
linearFree(texture->data);
|
||||
} else if (texture->place == SF2D_PLACE_VRAM) {
|
||||
vramFree(texture->data);
|
||||
}
|
||||
C3D_TexDelete(&texture->tex);
|
||||
free(texture);
|
||||
}
|
||||
}
|
||||
|
||||
void sf2d_free_target(sf2d_rendertarget *target)
|
||||
{
|
||||
sf2d_free_texture(&(target->texture));
|
||||
//free(target); // unnecessary since the texture is the start of the target struct
|
||||
C3D_RenderTargetDelete(target->target);
|
||||
free(target);
|
||||
}
|
||||
|
||||
void sf2d_clear_target(sf2d_rendertarget *target, u32 color) {
|
||||
if (color == 0) { // if fully transparent, take a shortcut
|
||||
memset(target->texture.data, 0, target->texture.width * target->texture.height * 4);
|
||||
sf2d_texture_tile32(&(target->texture));
|
||||
return;
|
||||
}
|
||||
|
||||
void sf2d_clear_target(sf2d_rendertarget *target, u32 color)
|
||||
{
|
||||
color = ((color>>24)&0x000000FF) | ((color>>8)&0x0000FF00) | ((color<<8)&0x00FF0000) | ((color<<24)&0xFF000000); // reverse byte order
|
||||
|
||||
int itarget = target->texture.width * target->texture.height;
|
||||
for (int i = 0; i < itarget; i++) { memcpy(target->texture.data + i*4, &color, 4); }
|
||||
|
||||
sf2d_texture_tile32(&(target->texture));
|
||||
C3D_RenderTargetSetClear(target->target, C3D_CLEAR_ALL, color, 0);
|
||||
}
|
||||
|
||||
void sf2d_texture_tile32_hardware(sf2d_texture *texture, const void *data, int w, int h)
|
||||
{
|
||||
if (texture->tiled) return;
|
||||
const u32 flags = (GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) |
|
||||
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) |
|
||||
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO));
|
||||
|
||||
const u32 flags = (GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) |
|
||||
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) |
|
||||
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO));
|
||||
|
||||
GSPGPU_FlushDataCache(data, (w*h)<<2);
|
||||
GX_DisplayTransfer(
|
||||
(u32*)data,
|
||||
GX_BUFFER_DIM(w, h),
|
||||
(u32*)texture->data,
|
||||
GX_BUFFER_DIM(texture->pow2_w, texture->pow2_h),
|
||||
flags
|
||||
);
|
||||
gspWaitForPPF();
|
||||
GSPGPU_InvalidateDataCache(texture->data, texture->data_size);
|
||||
GSPGPU_FlushDataCache(texture->tex.data, texture->tex.size);
|
||||
|
||||
C3D_SafeDisplayTransfer(
|
||||
(u32*)data,
|
||||
GX_BUFFER_DIM(w, h),
|
||||
(u32*)texture->tex.data,
|
||||
GX_BUFFER_DIM(texture->tex.width, texture->tex.height),
|
||||
flags
|
||||
);
|
||||
|
||||
gspWaitForPPF();
|
||||
texture->tiled = 1;
|
||||
}
|
||||
|
||||
|
|
@ -170,14 +108,14 @@ void sf2d_fill_texture_from_RGBA8(sf2d_texture *dst, const void *rgba8, int sour
|
|||
{
|
||||
// TODO: add support for non-RGBA8 textures
|
||||
|
||||
u8 *tmp = linearAlloc((dst->pow2_w * dst->pow2_h)<<2);
|
||||
u8 *tmp = linearAlloc((dst->tex.width * dst->tex.height)<<2);
|
||||
int i, j;
|
||||
for (i = 0; i < source_h; i++) {
|
||||
for (j = 0; j < source_w; j++) {
|
||||
((u32 *)tmp)[i*dst->pow2_w + j] = __builtin_bswap32(((u32 *)rgba8)[i*source_w + j]);
|
||||
((u32 *)tmp)[i*dst->tex.width + j] = __builtin_bswap32(((u32 *)rgba8)[i*source_w + j]);
|
||||
}
|
||||
}
|
||||
sf2d_texture_tile32_hardware(dst, tmp, dst->pow2_w, dst->pow2_h);
|
||||
sf2d_texture_tile32_hardware(dst, tmp, dst->tex.width, dst->tex.height);
|
||||
linearFree(tmp);
|
||||
|
||||
}
|
||||
|
|
@ -190,86 +128,45 @@ sf2d_texture *sf2d_create_texture_mem_RGBA8(const void *src_buffer, int src_w, i
|
|||
return tex;
|
||||
}
|
||||
|
||||
static inline int sf2d_get_texunit(GPU_TEXUNIT unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case GPU_TEXUNIT0: return 0;
|
||||
case GPU_TEXUNIT1: return 1;
|
||||
case GPU_TEXUNIT2: return 2;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void sf2d_bind_texture(const sf2d_texture *texture, GPU_TEXUNIT unit)
|
||||
{
|
||||
GPU_SetTextureEnable(unit);
|
||||
C3D_TexBind(sf2d_get_texunit(unit), (C3D_Tex*)&texture->tex);
|
||||
|
||||
GPU_SetTexEnv(
|
||||
0,
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_REPLACE, GPU_REPLACE,
|
||||
0xFFFFFFFF
|
||||
);
|
||||
|
||||
GPU_SetTexture(
|
||||
unit,
|
||||
(u32 *)osConvertVirtToPhys(texture->data),
|
||||
texture->pow2_w,
|
||||
texture->pow2_h,
|
||||
texture->params,
|
||||
texture->pixel_format
|
||||
);
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0);
|
||||
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
|
||||
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
|
||||
}
|
||||
|
||||
void sf2d_bind_texture_color(const sf2d_texture *texture, GPU_TEXUNIT unit, u32 color)
|
||||
{
|
||||
GPU_SetTextureEnable(unit);
|
||||
C3D_TexBind(sf2d_get_texunit(unit), (C3D_Tex*)&texture->tex);
|
||||
|
||||
GPU_SetTexEnv(
|
||||
0,
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_CONSTANT),
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_CONSTANT),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_MODULATE, GPU_MODULATE,
|
||||
color
|
||||
);
|
||||
|
||||
GPU_SetTexture(
|
||||
unit,
|
||||
(u32 *)osConvertVirtToPhys(texture->data),
|
||||
texture->pow2_w,
|
||||
texture->pow2_h,
|
||||
texture->params,
|
||||
texture->pixel_format
|
||||
);
|
||||
}
|
||||
|
||||
void sf2d_bind_texture_parameters(const sf2d_texture *texture, GPU_TEXUNIT unit, unsigned int params)
|
||||
{
|
||||
GPU_SetTextureEnable(unit);
|
||||
|
||||
GPU_SetTexEnv(
|
||||
0,
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_TEVOPERANDS(0, 0, 0),
|
||||
GPU_REPLACE, GPU_REPLACE,
|
||||
0xFFFFFFFF
|
||||
);
|
||||
|
||||
GPU_SetTexture(
|
||||
unit,
|
||||
(u32 *)osConvertVirtToPhys(texture->data),
|
||||
texture->pow2_w,
|
||||
texture->pow2_h,
|
||||
params,
|
||||
texture->pixel_format
|
||||
);
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_CONSTANT, 0);
|
||||
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
|
||||
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
|
||||
C3D_TexEnvColor(env, color);
|
||||
}
|
||||
|
||||
void sf2d_texture_set_params(sf2d_texture *texture, u32 params)
|
||||
{
|
||||
texture->params = params;
|
||||
texture->tex.param = params;
|
||||
}
|
||||
|
||||
int sf2d_texture_get_params(const sf2d_texture *texture)
|
||||
{
|
||||
return texture->params;
|
||||
return texture->tex.param;
|
||||
}
|
||||
|
||||
static inline void sf2d_draw_texture_generic(const sf2d_texture *texture, int x, int y)
|
||||
|
|
@ -285,27 +182,24 @@ static inline void sf2d_draw_texture_generic(const sf2d_texture *texture, int x,
|
|||
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+h, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){(float)x+w, (float)y+h, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
float u = texture->width/(float)texture->pow2_w;
|
||||
float v = texture->height/(float)texture->pow2_h;
|
||||
float u = texture->width/(float)texture->tex.width;
|
||||
float v = texture->height/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
|
||||
vertices[2].texcoord = (sf2d_vector_2f){0.0f, v};
|
||||
vertices[3].texcoord = (sf2d_vector_2f){u, v};
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture(const sf2d_texture *texture, int x, int y)
|
||||
|
|
@ -344,8 +238,8 @@ static inline void sf2d_draw_texture_rotate_hotspot_generic(const sf2d_texture *
|
|||
vertices[3].position.y = h - center_y;
|
||||
vertices[3].position.z = SF2D_DEFAULT_DEPTH;
|
||||
|
||||
float u = w/(float)texture->pow2_w;
|
||||
float v = h/(float)texture->pow2_h;
|
||||
float u = w/(float)texture->tex.width;
|
||||
float v = h/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
|
||||
|
|
@ -362,19 +256,16 @@ static inline void sf2d_draw_texture_rotate_hotspot_generic(const sf2d_texture *
|
|||
vertices[i].position.y = _x*s + _y*c + y;
|
||||
}
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_rotate_hotspot(const sf2d_texture *texture, int x, int y, float rad, float center_x, float center_y)
|
||||
|
|
@ -428,8 +319,8 @@ static inline void sf2d_draw_texture_rotate_scale_hotspot_generic(const sf2d_tex
|
|||
vertices[3].position.y = h - center_y * scale_y;
|
||||
vertices[3].position.z = SF2D_DEFAULT_DEPTH;
|
||||
|
||||
float u = w/(float)texture->pow2_w;
|
||||
float v = h/(float)texture->pow2_h;
|
||||
float u = w/(float)texture->tex.width;
|
||||
float v = h/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
|
||||
|
|
@ -446,19 +337,16 @@ static inline void sf2d_draw_texture_rotate_scale_hotspot_generic(const sf2d_tex
|
|||
vertices[i].position.y = _x*s + _y*c + y;
|
||||
}
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_rotate_scale_hotspot(const sf2d_texture *texture, int x, int y, float rad, float scale_x, float scale_y, float center_x, float center_y)
|
||||
|
|
@ -483,29 +371,26 @@ static inline void sf2d_draw_texture_part_generic(const sf2d_texture *texture, i
|
|||
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){(float)x+tex_w, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
float u0 = tex_x/(float)texture->pow2_w;
|
||||
float v0 = tex_y/(float)texture->pow2_h;
|
||||
float u1 = (tex_x+tex_w)/(float)texture->pow2_w;
|
||||
float v1 = (tex_y+tex_h)/(float)texture->pow2_h;
|
||||
float u0 = tex_x/(float)texture->tex.width;
|
||||
float v0 = tex_y/(float)texture->tex.height;
|
||||
float u1 = (tex_x+tex_w)/(float)texture->tex.width;
|
||||
float v1 = (tex_y+tex_h)/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){u0, v0};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u1, v0};
|
||||
vertices[2].texcoord = (sf2d_vector_2f){u0, v1};
|
||||
vertices[3].texcoord = (sf2d_vector_2f){u1, v1};
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_part(const sf2d_texture *texture, int x, int y, int tex_x, int tex_y, int tex_w, int tex_h)
|
||||
|
|
@ -533,27 +418,24 @@ static inline void sf2d_draw_texture_scale_generic(const sf2d_texture *texture,
|
|||
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+hs, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){(float)x+ws, (float)y+hs, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
float u = texture->width/(float)texture->pow2_w;
|
||||
float v = texture->height/(float)texture->pow2_h;
|
||||
float u = texture->width/(float)texture->tex.width;
|
||||
float v = texture->height/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
|
||||
vertices[2].texcoord = (sf2d_vector_2f){0.0f, v};
|
||||
vertices[3].texcoord = (sf2d_vector_2f){u, v};
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_scale(const sf2d_texture *texture, int x, int y, float x_scale, float y_scale)
|
||||
|
|
@ -573,10 +455,10 @@ static inline void sf2d_draw_texture_part_scale_generic(const sf2d_texture *text
|
|||
sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8);
|
||||
if (!vertices) return;
|
||||
|
||||
float u0 = tex_x/(float)texture->pow2_w;
|
||||
float v0 = tex_y/(float)texture->pow2_h;
|
||||
float u1 = (tex_x+tex_w)/(float)texture->pow2_w;
|
||||
float v1 = (tex_y+tex_h)/(float)texture->pow2_h;
|
||||
float u0 = tex_x/(float)texture->tex.width;
|
||||
float v0 = tex_y/(float)texture->tex.height;
|
||||
float u1 = (tex_x+tex_w)/(float)texture->tex.width;
|
||||
float v1 = (tex_y+tex_h)/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){u0, v0};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u1, v0};
|
||||
|
|
@ -591,19 +473,16 @@ static inline void sf2d_draw_texture_part_scale_generic(const sf2d_texture *text
|
|||
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){(float)x+tex_w, (float)y+tex_h, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_part_scale(const sf2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale)
|
||||
|
|
@ -618,23 +497,23 @@ void sf2d_draw_texture_part_scale_blend(const sf2d_texture *texture, float x, fl
|
|||
sf2d_draw_texture_part_scale_generic(texture, x, y, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale);
|
||||
}
|
||||
|
||||
static inline void sf2d_draw_texture_part_rotate_scale_hotspot_generic(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, float center_x, float center_y)
|
||||
static inline void sf2d_draw_texture_part_rotate_scale_generic(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8);
|
||||
if (!vertices) return;
|
||||
|
||||
int w = tex_w;
|
||||
int h = tex_h;
|
||||
int w2 = (tex_w * x_scale)/2.0f;
|
||||
int h2 = (tex_h * y_scale)/2.0f;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)-center_x * x_scale, (float)-center_y * y_scale, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float) (w - center_x) * x_scale, (float)-center_y * y_scale, SF2D_DEFAULT_DEPTH};
|
||||
vertices[2].position = (sf2d_vector_3f){(float)-center_x * x_scale, (float) (h - center_y) * y_scale, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){(float) (w - center_x) * x_scale, (float) h - center_y * y_scale, SF2D_DEFAULT_DEPTH};
|
||||
vertices[0].position = (sf2d_vector_3f){(float)-w2, (float)-h2, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float) w2, (float)-h2, SF2D_DEFAULT_DEPTH};
|
||||
vertices[2].position = (sf2d_vector_3f){(float)-w2, (float) h2, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){(float) w2, (float) h2, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
float u0 = tex_x/(float)texture->pow2_w;
|
||||
float v0 = tex_y/(float)texture->pow2_h;
|
||||
float u1 = (tex_x+tex_w)/(float)texture->pow2_w;
|
||||
float v1 = (tex_y+tex_h)/(float)texture->pow2_h;
|
||||
float u0 = tex_x/(float)texture->tex.width;
|
||||
float v0 = tex_y/(float)texture->tex.height;
|
||||
float u1 = (tex_x+tex_w)/(float)texture->tex.width;
|
||||
float v1 = (tex_y+tex_h)/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){u0, v0};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u1, v0};
|
||||
|
|
@ -651,37 +530,28 @@ static inline void sf2d_draw_texture_part_rotate_scale_hotspot_generic(const sf2
|
|||
vertices[i].position.y = _x*s + _y*c + y;
|
||||
}
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_part_rotate_scale(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale)
|
||||
{
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
sf2d_draw_texture_part_rotate_scale_hotspot_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, tex_w/2.0f, tex_h/2.0f);
|
||||
sf2d_draw_texture_part_rotate_scale_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_part_rotate_scale_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, u32 color)
|
||||
{
|
||||
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
|
||||
sf2d_draw_texture_part_rotate_scale_hotspot_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, tex_w/2.0f, tex_h/2.0f);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_part_rotate_scale_hotspot_blend(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale, float center_x, float center_y, u32 color)
|
||||
{
|
||||
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
|
||||
sf2d_draw_texture_part_rotate_scale_hotspot_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, center_x, center_y);
|
||||
sf2d_draw_texture_part_rotate_scale_generic(texture, x, y, rad, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale);
|
||||
}
|
||||
|
||||
static inline void sf2d_draw_texture_depth_generic(const sf2d_texture *texture, int x, int y, signed short z)
|
||||
|
|
@ -698,27 +568,24 @@ static inline void sf2d_draw_texture_depth_generic(const sf2d_texture *texture,
|
|||
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+h, depth};
|
||||
vertices[3].position = (sf2d_vector_3f){(float)x+w, (float)y+h, depth};
|
||||
|
||||
float u = texture->width/(float)texture->pow2_w;
|
||||
float v = texture->height/(float)texture->pow2_h;
|
||||
float u = texture->width/(float)texture->tex.width;
|
||||
float v = texture->height/(float)texture->tex.height;
|
||||
|
||||
vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f};
|
||||
vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f};
|
||||
vertices[2].texcoord = (sf2d_vector_2f){0.0f, v};
|
||||
vertices[3].texcoord = (sf2d_vector_2f){u, v};
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_depth(const sf2d_texture *texture, int x, int y, signed short z)
|
||||
|
|
@ -733,8 +600,7 @@ void sf2d_draw_texture_depth_blend(const sf2d_texture *texture, int x, int y, si
|
|||
sf2d_draw_texture_depth_generic(texture, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
void sf2d_draw_quad_uv(const sf2d_texture *texture, float left, float top, float right, float bottom, float u0, float v0, float u1, float v1, unsigned int params)
|
||||
void sf2d_draw_quad_uv_current(float left, float top, float right, float bottom, float u0, float v0, float u1, float v1)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_tex), 8);
|
||||
if (!vertices) return;
|
||||
|
|
@ -749,21 +615,28 @@ void sf2d_draw_quad_uv(const sf2d_texture *texture, float left, float top, float
|
|||
vertices[2].texcoord = (sf2d_vector_2f){u0, v1};
|
||||
vertices[3].texcoord = (sf2d_vector_2f){u1, v1};
|
||||
|
||||
sf2d_bind_texture_parameters(texture, GPU_TEXUNIT0, params);
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
AttrInfo_Init(attrInfo);
|
||||
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys(vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT),
|
||||
0xFFFC, //0b1100
|
||||
0x10,
|
||||
1, //number of buffers
|
||||
(u32[]){0x0}, // buffer offsets (placeholders)
|
||||
(u64[]){0x10}, // attribute permutations for each buffer
|
||||
(u8[]){2} // number of attributes for each buffer
|
||||
);
|
||||
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufInfo);
|
||||
BufInfo_Add(bufInfo, vertices, sizeof(sf2d_vertex_pos_tex), 2, 0x10);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_quad_uv(const sf2d_texture *texture, float left, float top, float right, float bottom, float u0, float v0, float u1, float v1)
|
||||
{
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
sf2d_draw_quad_uv_current(left, top, right, bottom, u0, v0, u1, v1);
|
||||
}
|
||||
|
||||
void sf2d_draw_quad_uv_blend(const sf2d_texture *texture, float left, float top, float right, float bottom, float u0, float v0, float u1, float v1, u32 color)
|
||||
{
|
||||
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
|
||||
sf2d_draw_quad_uv_current(left, top, right, bottom, u0, v0, u1, v1);
|
||||
}
|
||||
|
||||
// Grabbed from Citra Emulator (citra/src/video_core/utils.h)
|
||||
|
|
@ -786,25 +659,25 @@ static inline u32 get_morton_offset(u32 x, u32 y, u32 bytes_per_pixel)
|
|||
|
||||
void sf2d_set_pixel(sf2d_texture *texture, int x, int y, u32 new_color)
|
||||
{
|
||||
y = (texture->pow2_h - 1 - y);
|
||||
y = (texture->tex.height - 1 - y);
|
||||
if (texture->tiled) {
|
||||
u32 coarse_y = y & ~7;
|
||||
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->pow2_w * 4;
|
||||
*(u32 *)(texture->data + offset) = new_color;
|
||||
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->tex.width * 4;
|
||||
*(u32 *)(texture->tex.data + offset) = new_color;
|
||||
} else {
|
||||
((u32 *)texture->data)[x + y * texture->pow2_w] = new_color;
|
||||
((u32 *)texture->tex.data)[x + y * texture->tex.width] = new_color;
|
||||
}
|
||||
}
|
||||
|
||||
u32 sf2d_get_pixel(sf2d_texture *texture, int x, int y)
|
||||
{
|
||||
y = (texture->pow2_h - 1 - y);
|
||||
y = (texture->tex.height - 1 - y);
|
||||
if (texture->tiled) {
|
||||
u32 coarse_y = y & ~7;
|
||||
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->pow2_w * 4;
|
||||
return *(u32 *)(texture->data + offset);
|
||||
u32 offset = get_morton_offset(x, y, 4) + coarse_y * texture->tex.width * 4;
|
||||
return *(u32 *)(texture->tex.data + offset);
|
||||
} else {
|
||||
return ((u32 *)texture->data)[x + y * texture->pow2_w];
|
||||
return ((u32 *)texture->tex.data)[x + y * texture->tex.width];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -814,21 +687,21 @@ void sf2d_texture_tile32(sf2d_texture *texture)
|
|||
if (texture->tiled) return;
|
||||
|
||||
// TODO: add support for non-RGBA8 textures
|
||||
u8 *tmp = linearAlloc(texture->pow2_w * texture->pow2_h * 4);
|
||||
u8 *tmp = linearAlloc(texture->tex.width * texture->tex.height * 4);
|
||||
|
||||
int i, j;
|
||||
for (j = 0; j < texture->pow2_h; j++) {
|
||||
for (i = 0; i < texture->pow2_w; i++) {
|
||||
for (j = 0; j < texture->tex.height; j++) {
|
||||
for (i = 0; i < texture->tex.width; i++) {
|
||||
|
||||
u32 coarse_y = j & ~7;
|
||||
u32 dst_offset = get_morton_offset(i, j, 4) + coarse_y * texture->pow2_w * 4;
|
||||
u32 dst_offset = get_morton_offset(i, j, 4) + coarse_y * texture->tex.width * 4;
|
||||
|
||||
u32 v = ((u32 *)texture->data)[i + (texture->pow2_h - 1 - j)*texture->pow2_w];
|
||||
u32 v = ((u32 *)texture->tex.data)[i + (texture->tex.height - 1 - j)*texture->tex.width];
|
||||
*(u32 *)(tmp + dst_offset) = __builtin_bswap32(v); /* RGBA8 -> ABGR8 */
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(texture->data, tmp, texture->pow2_w*texture->pow2_h*4);
|
||||
memcpy(texture->tex.data, tmp, texture->tex.width*texture->tex.height*4);
|
||||
linearFree(tmp);
|
||||
|
||||
texture->tiled = 1;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ include $(DEVKITARM)/3ds_rules
|
|||
# INCLUDES is a list of directories containing header files
|
||||
#
|
||||
# NO_SMDH: if set to anything, no SMDH file is generated.
|
||||
# ROMFS is the directory which contains the RomFS, relative to the Makefile (Optional)
|
||||
# APP_TITLE is the name of the app stored in the SMDH file (Optional)
|
||||
# APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the SMDH file (Optional)
|
||||
|
|
@ -31,6 +32,7 @@ BUILD := build
|
|||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
#ROMFS := romfs
|
||||
|
||||
APP_TITLE := SF2DLIB sample
|
||||
APP_DESCRIPTION := SF2DLIB sample
|
||||
|
|
@ -39,10 +41,10 @@ APP_AUTHOR := xerpi
|
|||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||
|
||||
CFLAGS := -g -Wall -O2 -mword-relocations \
|
||||
-fomit-frame-pointer -ffast-math \
|
||||
-fomit-frame-pointer -ffunction-sections \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
|
||||
|
|
@ -52,7 +54,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
|||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lsf2d -lctru -lm
|
||||
LIBS := -lsf2d -lcitro3d -lctru -lm
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
|
@ -79,6 +81,8 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
|
|||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica)))
|
||||
SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
@ -96,6 +100,7 @@ endif
|
|||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
|
|
@ -121,6 +126,10 @@ ifeq ($(strip $(NO_SMDH)),)
|
|||
export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
|
||||
endif
|
||||
|
||||
ifneq ($(ROMFS),)
|
||||
export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
@ -180,17 +189,29 @@ $(OUTPUT).elf : $(OFILES)
|
|||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
# WARNING: This is not the right way to do this! TODO: Do it right!
|
||||
#---------------------------------------------------------------------------------
|
||||
%.vsh.o : %.vsh
|
||||
# rules for assembling GPU shaders
|
||||
#---------------------------------------------------------------------------------
|
||||
define shader-as
|
||||
$(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@)))
|
||||
picasso -o $(CURBIN) $1
|
||||
bin2s $(CURBIN) | $(AS) -o $@
|
||||
echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
|
||||
echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h
|
||||
echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h
|
||||
endef
|
||||
|
||||
%.shbin.o : %.v.pica %.g.pica
|
||||
@echo $(notdir $^)
|
||||
@$(call shader-as,$^)
|
||||
|
||||
%.shbin.o : %.v.pica
|
||||
@echo $(notdir $<)
|
||||
@python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin
|
||||
@bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@
|
||||
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h
|
||||
@rm ../$(notdir $<).shbin
|
||||
@$(call shader-as,$<)
|
||||
|
||||
%.shbin.o : %.shlist
|
||||
@echo $(notdir $<)
|
||||
@$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file)))
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue