mirror of
https://github.com/ctruLua/ctruLua.git
synced 2025-10-27 16:39:29 +00:00
Added missing dependicies
This commit is contained in:
parent
03baa21c10
commit
ebcd9f00ed
47 changed files with 18405 additions and 0 deletions
21
libs/sf2dlib/LICENSE
Normal file
21
libs/sf2dlib/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Sergi Granell (xerpi), xerpi.g.12@gmail.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.
|
||||
7
libs/sf2dlib/README.md
Normal file
7
libs/sf2dlib/README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
## SF2DLIB
|
||||
|
||||
|
||||
Simple and Fast 2D library for the Nintendo 3DS (using ctrulib)
|
||||
|
||||
### Documentation
|
||||
http://xerpi.github.io/sf2dlib/html/sf2d_8h.html
|
||||
2362
libs/sf2dlib/libsf2d/Doxyfile
Normal file
2362
libs/sf2dlib/libsf2d/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
142
libs/sf2dlib/libsf2d/Makefile
Normal file
142
libs/sf2dlib/libsf2d/Makefile
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/3ds_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := sf2d
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard
|
||||
|
||||
CFLAGS := -g -Wall -O2\
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(CTRULIB)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/lib/lib$(TARGET).a
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
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)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
lib:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
$(BUILD): lib
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) lib latex html
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
install: $(BUILD)
|
||||
@cp $(OUTPUT) $(CTRULIB)/lib
|
||||
@cp include/sf2d.h $(CTRULIB)/include
|
||||
@echo "Installed!"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
docs:
|
||||
@doxygen Doxyfile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(OUTPUT) : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
# WARNING: This is not the right way to do this! TODO: Do it right!
|
||||
#---------------------------------------------------------------------------------
|
||||
%_vsh.h %.vsh.o : %.vsh
|
||||
#---------------------------------------------------------------------------------
|
||||
@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
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
39
libs/sf2dlib/libsf2d/data/shader.vsh
Normal file
39
libs/sf2dlib/libsf2d/data/shader.vsh
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
; setup constants
|
||||
.const c20, 0.0, 0.0, 0.0, 1.0
|
||||
|
||||
; setup outmap
|
||||
.out o0, result.position, 0xF
|
||||
.out o1, result.texcoord0, 0x3
|
||||
.out o2, result.color, 0xF
|
||||
|
||||
; setup uniform map (not required)
|
||||
.uniform c0, c3, projection
|
||||
|
||||
.vsh vmain, end_vmain
|
||||
|
||||
;code
|
||||
vmain:
|
||||
; result.pos = projMtx * in.pos
|
||||
dp4 o0, c0, v0 (0x0)
|
||||
dp4 o0, c1, v0 (0x1)
|
||||
dp4 o0, c2, v0 (0x2)
|
||||
dp4 o0, c3, v0 (0x3)
|
||||
; result.texcoord = in.texcoord
|
||||
mov o1, v1 (0x5)
|
||||
; result.color = in.color
|
||||
mov o2, v1 (0x5)
|
||||
nop
|
||||
end
|
||||
end_vmain:
|
||||
|
||||
;operand descriptors
|
||||
.opdesc x___, xyzw, xyzw ; 0x0
|
||||
.opdesc _y__, xyzw, xyzw ; 0x1
|
||||
.opdesc __z_, xyzw, xyzw ; 0x2
|
||||
.opdesc ___w, xyzw, xyzw ; 0x3
|
||||
.opdesc xyz_, xyzw, xyzw ; 0x4
|
||||
.opdesc xyzw, xyzw, xyzw ; 0x5
|
||||
.opdesc x_zw, xyzw, xyzw ; 0x6
|
||||
.opdesc xyzw, yyyw, xyzw ; 0x7
|
||||
.opdesc xyz_, wwww, wwww ; 0x8
|
||||
.opdesc xyz_, yyyy, xyzw ; 0x9
|
||||
496
libs/sf2dlib/libsf2d/include/sf2d.h
Normal file
496
libs/sf2dlib/libsf2d/include/sf2d.h
Normal file
|
|
@ -0,0 +1,496 @@
|
|||
/**
|
||||
* @file sf2d.h
|
||||
* @author Sergi Granell (xerpi)
|
||||
* @date 22 March 2015
|
||||
* @brief sf2dlib header
|
||||
*/
|
||||
|
||||
#ifndef SF2D_H
|
||||
#define SF2D_H
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Defines
|
||||
|
||||
/**
|
||||
* @brief Creates a new RGBA8 color
|
||||
* @param r the red component of the color to create
|
||||
* @param g the green component of the color to create
|
||||
* @param b the blue component of the color to create
|
||||
* @param a the alpha component of the color to create
|
||||
*/
|
||||
#define RGBA8(r, g, b, a) ((((r)&0xFF)<<24) | (((g)&0xFF)<<16) | (((b)&0xFF)<<8) | (((a)&0xFF)<<0))
|
||||
|
||||
/**
|
||||
* @brief Default size of the GPU commands FIFO buffer
|
||||
*/
|
||||
#define SF2D_GPUCMD_DEFAULT_SIZE 0x80000
|
||||
|
||||
/**
|
||||
* @brief Default size of the temporary memory pool
|
||||
*/
|
||||
#define SF2D_TEMPPOOL_DEFAULT_SIZE 0x80000
|
||||
|
||||
/**
|
||||
* @brief Default depth (Z coordinate) to draw the textures to
|
||||
*/
|
||||
#define SF2D_DEFAULT_DEPTH 0.5f
|
||||
|
||||
// Enums
|
||||
|
||||
/**
|
||||
* @brief Represents a texture format
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
TEXFMT_RGBA8 = 0,
|
||||
TEXFMT_RGB8 = 1,
|
||||
TEXFMT_RGB5A1 = 2,
|
||||
TEXFMT_RGB565 = 3,
|
||||
TEXFMT_RGBA4 = 4,
|
||||
TEXFMT_IA8 = 5,
|
||||
|
||||
TEXFMT_I8 = 7,
|
||||
TEXFMT_A8 = 8,
|
||||
TEXFMT_IA4 = 9,
|
||||
TEXFMT_I4 = 10,
|
||||
TEXFMT_A4 = 11,
|
||||
TEXFMT_ETC1 = 12,
|
||||
TEXFMT_ETC1A4 = 13
|
||||
} sf2d_texfmt;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Data allocated on the RAM or VRAM
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
SF2D_PLACE_RAM, /**< RAM allocated */
|
||||
SF2D_PLACE_VRAM, /**< VRAM allocated */
|
||||
SF2D_PLACE_TEMP /**< Temporary memory pool allocated */
|
||||
} sf2d_place;
|
||||
|
||||
// Structs
|
||||
|
||||
/**
|
||||
* @brief Represents a two dimensional float vector
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
float u; /**< First component of the vector */
|
||||
float v; /**< Second component of the vector */
|
||||
} sf2d_vector_2f;
|
||||
|
||||
/**
|
||||
* @brief Represents a three dimensional float vector
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
float x; /**< First component of the vector */
|
||||
float y; /**< Second component of the vector */
|
||||
float z; /**< Third component of the vector */
|
||||
} sf2d_vector_3f;
|
||||
|
||||
/**
|
||||
* @brief Represents a four dimensional float vector
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
float r; /**< Red component of the vector/color */
|
||||
float g; /**< Green component of the vector/color */
|
||||
float b; /**< Blue component of the vector/color */
|
||||
float a; /**< Alpha component of the vector/color */
|
||||
} sf2d_vector_4f;
|
||||
|
||||
/**
|
||||
* @brief Represents a vertex containing position and color attributes
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
sf2d_vector_3f position; /**< Position of the vertex */
|
||||
sf2d_vector_4f color; /**< Color of the vertex */
|
||||
} sf2d_vertex_pos_col;
|
||||
|
||||
/**
|
||||
* @brief Represents a vertex containing position and texture coordinates
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
sf2d_vector_3f position; /**< Position of the vertex */
|
||||
sf2d_vector_2f texcoord; /**< Texture coordinates of the vertex */
|
||||
} sf2d_vertex_pos_tex;
|
||||
|
||||
/**
|
||||
* @brief Represents a texture
|
||||
*/
|
||||
|
||||
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 */
|
||||
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 */
|
||||
} sf2d_texture;
|
||||
|
||||
// Basic functions
|
||||
|
||||
/**
|
||||
* @brief Initializates the library
|
||||
* @return Whether the initialization has been successful or not
|
||||
*/
|
||||
int sf2d_init();
|
||||
|
||||
/**
|
||||
* @brief Initializates the library (with advanced settings)
|
||||
* @param gpucmd_size the size of the GPU FIFO
|
||||
* @param temppool_size the size of the temporary pool
|
||||
* @return Whether the initialization has been successful or not
|
||||
*/
|
||||
int sf2d_init_advanced(int gpucmd_size, int temppool_size);
|
||||
|
||||
/**
|
||||
* @brief Finishes the library
|
||||
* @return Whether the finalization has been successful or not
|
||||
*/
|
||||
int sf2d_fini();
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the 3D
|
||||
* @param enable whether to enable or disable the 3D
|
||||
*/
|
||||
void sf2d_set_3D(int enable);
|
||||
|
||||
/**
|
||||
* @brief Starts a frame
|
||||
* @param screen target screen
|
||||
* @param side target eye (only for top screen)
|
||||
*/
|
||||
void sf2d_start_frame(gfxScreen_t screen, gfx3dSide_t side);
|
||||
|
||||
/**
|
||||
* @brief Ends a frame, should be called on pair with sf2d_start_frame
|
||||
*/
|
||||
void sf2d_end_frame();
|
||||
|
||||
/**
|
||||
* @brief Swaps the framebuffers, should be called once after all the frames have been finished
|
||||
*/
|
||||
void sf2d_swapbuffers();
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the VBlank waiting
|
||||
* @param enable whether to enable or disable the VBlank waiting
|
||||
*/
|
||||
void sf2d_set_vblank_wait(int enable);
|
||||
|
||||
/**
|
||||
* @brief Returns the FPS (frames per second)
|
||||
* @return the current FPS
|
||||
*/
|
||||
float sf2d_get_fps();
|
||||
|
||||
/**
|
||||
* @brief Allocates memory from a temporary pool. The pool will be emptied after a sf2d_swapbuffers call
|
||||
* @param size the number of bytes to allocate
|
||||
*/
|
||||
void *sf2d_pool_malloc(u32 size);
|
||||
|
||||
/**
|
||||
* @brief Allocates aligned memory from a temporary pool. Works as sf2d_pool_malloc
|
||||
* @param size the number of bytes to allocate
|
||||
* @param alignment the alignment to where allocate the memory
|
||||
*/
|
||||
void *sf2d_pool_memalign(u32 size, u32 alignment);
|
||||
|
||||
/**
|
||||
* @brief Returns the temporary pool's free space
|
||||
* @return the temporary pool's free space
|
||||
*/
|
||||
unsigned int sf2d_pool_space_free();
|
||||
|
||||
/**
|
||||
* @brief Empties the temporary pool
|
||||
*/
|
||||
void sf2d_pool_reset();
|
||||
|
||||
/**
|
||||
* @brief Sets the screen clear color
|
||||
* @param color the color
|
||||
*/
|
||||
void sf2d_set_clear_color(u32 color);
|
||||
|
||||
// Draw functions
|
||||
/**
|
||||
* @brief Draws a line
|
||||
* @param x0 x coordinate of the first dot
|
||||
* @param y0 y coordinate of the first dot
|
||||
* @param x1 x coordinate of the second dot
|
||||
* @param y1 y coordinate of the sceond dot
|
||||
* @param color the color to draw the line
|
||||
*/
|
||||
void sf2d_draw_line(int x0, int y0, int x1, int y1, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Draws a rectangle
|
||||
* @param x x coordinate of the top left corner of the rectangle
|
||||
* @param y y coordinate of the top left corner of the rectangle
|
||||
* @param w rectangle width
|
||||
* @param h rectangle height
|
||||
* @param color the color to draw the rectangle
|
||||
*/
|
||||
void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Draws a rotated rectangle
|
||||
* @param x x coordinate of the top left corner of the rectangle
|
||||
* @param y y coordinate of the top left corner of the rectangle
|
||||
* @param w rectangle width
|
||||
* @param h rectangle height
|
||||
* @param color the color to draw the rectangle
|
||||
* @param rad rotation (in radians) to draw the rectangle
|
||||
*/
|
||||
void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad);
|
||||
|
||||
/**
|
||||
* @brief Draws a filled circle
|
||||
* @param x x coordinate of the center of the circle
|
||||
* @param y y coordinate of the center of the circle
|
||||
* @param radius the radius of the circle
|
||||
* @param color the color to draw the circle
|
||||
*/
|
||||
void sf2d_draw_fill_circle(int x, int y, int radius, u32 color);
|
||||
|
||||
// Texture
|
||||
|
||||
/**
|
||||
* @brief Creates an empty texture.
|
||||
* The returned texture has the data allocated,
|
||||
* this means that the raw pixel data can be filled
|
||||
* just after the return.
|
||||
* @param width the width of the texture
|
||||
* @param height the height of the texture
|
||||
* @param pixel_format the pixel_format of the texture
|
||||
* @param place where to allocate the texture
|
||||
* @return a pointer to the newly created texture
|
||||
*/
|
||||
sf2d_texture *sf2d_create_texture(int width, int height, sf2d_texfmt pixel_format, sf2d_place place);
|
||||
|
||||
/**
|
||||
* @brief Frees a texture
|
||||
* @param texture pointer to the texture to freeze
|
||||
*/
|
||||
void sf2d_free_texture(sf2d_texture *texture);
|
||||
|
||||
/**
|
||||
* @brief Fills an already allocated texture from a RGBA8 source
|
||||
* @param dst pointer to the destination texture to fill
|
||||
* @param rgba8 pointer to the RGBA8 data to fill from
|
||||
* @param source_w width (in pixels) of the RGAB8 source
|
||||
* @param source_h height (in pixels) of the RGAB8 source
|
||||
*/
|
||||
void sf2d_fill_texture_from_RGBA8(sf2d_texture *dst, const void *rgba8, int source_w, int source_h);
|
||||
|
||||
/**
|
||||
* @brief Creates a texture and fills it from a RGBA8 memory source.
|
||||
* The returned texture is already tiled.
|
||||
* @param src_buffer pointer to the RGBA8 data to fill from
|
||||
* @param src_w width (in pixels) of the RGAB8 source
|
||||
* @param src_h height (in pixels) of the RGAB8 source
|
||||
* @param pixel_format the pixel_format of the texture to create
|
||||
* @param place where to allocate the texture
|
||||
* @return a pointer to the newly created, filled, and tiled texture
|
||||
*/
|
||||
|
||||
sf2d_texture *sf2d_create_texture_mem_RGBA8(const void *src_buffer, int src_w, int src_h, sf2d_texfmt pixel_format, sf2d_place place);
|
||||
|
||||
/**
|
||||
* @brief Binds a texture to a GPU texture unit
|
||||
* @param texture the texture to bind
|
||||
* @param unit GPU texture unit to bind to
|
||||
*/
|
||||
void sf2d_bind_texture(const sf2d_texture *texture, GPU_TEXUNIT unit);
|
||||
|
||||
/**
|
||||
* @brief Binds a texture to a GPU texture unit with a constant color
|
||||
* @param texture the texture to bind
|
||||
* @param unit GPU texture unit to bind to
|
||||
* @param color the color the bind with the texture
|
||||
*/
|
||||
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 Draws a texture
|
||||
* @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
|
||||
*/
|
||||
void sf2d_draw_texture(const sf2d_texture *texture, int x, int y);
|
||||
|
||||
/**
|
||||
* @brief Draws a texture with rotation
|
||||
* @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
|
||||
*/
|
||||
void sf2d_draw_texture_rotate(const sf2d_texture *texture, int x, int y, float rad);
|
||||
|
||||
/**
|
||||
* @brief Draws a part of a texture
|
||||
* @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 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
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Draws a texture with scaling
|
||||
* @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 x_scale the x scale
|
||||
* @param y_scale the y scale
|
||||
*/
|
||||
void sf2d_draw_texture_scale(const sf2d_texture *texture, int x, int y, float x_scale, float y_scale);
|
||||
|
||||
/**
|
||||
* @brief Draws a part of a texture, with rotation and scaling
|
||||
* @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
|
||||
*/
|
||||
void sf2d_draw_texture_rotate_cut_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);
|
||||
|
||||
/**
|
||||
* @brief Draws a texture blended with a color
|
||||
* @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 color the color to blend with the texture
|
||||
*/
|
||||
void sf2d_draw_texture_blend(const sf2d_texture *texture, int x, int y, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Draws a part of a texture blended with a color
|
||||
* @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 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 color the color to blend with the texture
|
||||
*/
|
||||
void sf2d_draw_texture_part_blend(const sf2d_texture *texture, int x, int y, int tex_x, int tex_y, int tex_w, int tex_h, u32 color);
|
||||
|
||||
/**
|
||||
* @brief Draws a texture blended in a certain depth
|
||||
* @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 z the depth to draw the texture to
|
||||
* @note The z parameter is a value in the [-32768, +32767] range,
|
||||
* where -32768 is the deepest and +32767 the toppest.
|
||||
* By default, the textures are drawn at z = 0.
|
||||
* Keep in mind that this function won't do
|
||||
* Order-independent transparency (OIT), so you should use fully
|
||||
* opaque textures to get good results.
|
||||
*/
|
||||
void sf2d_draw_texture_depth(const sf2d_texture *texture, int x, int y, signed short z);
|
||||
|
||||
/**
|
||||
* @brief Draws a texture using custom texture coordinates and parameters
|
||||
* @param texture the texture to draw
|
||||
* @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
|
||||
* @param height the height to draw from the starting top coordinate
|
||||
* @param u0 the U texture coordinate of the left vertices
|
||||
* @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(const sf2d_texture *texture, float left, float top, float right, float bottom,
|
||||
float u0, float v0, float u1, float v1, unsigned int params);
|
||||
|
||||
/**
|
||||
* @brief Changes a pixel of the texture
|
||||
* @param texture the texture to change the pixel
|
||||
* @param x the x coordinate to change the pixel
|
||||
* @param y the y coordinate to change the pixel
|
||||
* @param new_color the new color to set to the pixel at (x, y)
|
||||
*/
|
||||
void sf2d_set_pixel(sf2d_texture *texture, int x, int y, u32 new_color);
|
||||
|
||||
/**
|
||||
* @brief Gets a pixel of the texture
|
||||
* @param texture the texture to get the pixel
|
||||
* @param x the x coordinate to get the pixel
|
||||
* @param y the y coordinate to get the pixel
|
||||
* @return the pixel at (x, y)
|
||||
*/
|
||||
u32 sf2d_get_pixel(sf2d_texture *texture, int x, int y);
|
||||
|
||||
/**
|
||||
* @brief Tiles a texture
|
||||
* @param texture the texture to tile
|
||||
*/
|
||||
void sf2d_texture_tile32(sf2d_texture *texture);
|
||||
|
||||
/**
|
||||
* @brief Sets the scissor test
|
||||
* @param mode the test mode (disable, invert or normal)
|
||||
* @param x the starting x coordinate of the scissor
|
||||
* @param y the starting y coordinate of the scissor
|
||||
* @param w the width of the scissor rectangle
|
||||
* @param h the height of the scissor rectangle
|
||||
* @note This function should be called after sf2d_start_frame.
|
||||
* The scissor will remain active until the sf2d_end_frame call.
|
||||
*/
|
||||
void sf2d_set_scissor_test(GPU_SCISSORMODE mode, u32 x, u32 y, u32 w, u32 h);
|
||||
|
||||
/**
|
||||
* @brief Returns the current screen (latest call to sf2d_start_frame)
|
||||
* @note The returned value can be GFX_TOP or GFX_BOTTOM.
|
||||
*/
|
||||
gfxScreen_t sf2d_get_current_screen();
|
||||
|
||||
/**
|
||||
* @brief Returns the current screen side (latest call to sf2d_start_frame)
|
||||
* @note The returned value can be GFX_LEFT or GFX_RIGHT.
|
||||
*/
|
||||
gfx3dSide_t sf2d_get_current_side();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
29
libs/sf2dlib/libsf2d/include/sf2d_private.h
Normal file
29
libs/sf2dlib/libsf2d/include/sf2d_private.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef SF2D_PRIVATE_H
|
||||
#define SF2D_PRIVATE_H
|
||||
|
||||
#include <3ds.h>
|
||||
#include "sf2d.h"
|
||||
|
||||
|
||||
void GPU_SetDummyTexEnv(u8 num);
|
||||
|
||||
// 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
|
||||
303
libs/sf2dlib/libsf2d/source/sf2d.c
Normal file
303
libs/sf2dlib/libsf2d/source/sf2d.c
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
#include "sf2d.h"
|
||||
#include "sf2d_private.h"
|
||||
#include "shader_vsh_shbin.h"
|
||||
|
||||
|
||||
static int sf2d_initialized = 0;
|
||||
static u32 clear_color = RGBA8(0x00, 0x00, 0x00, 0xFF);
|
||||
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
|
||||
static float current_fps = 0.0f;
|
||||
static unsigned int frames = 0;
|
||||
static u64 last_time = 0;
|
||||
//Current screen/side
|
||||
static gfxScreen_t cur_screen = GFX_TOP;
|
||||
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];
|
||||
//Apt hook cookie
|
||||
static aptHookCookie apt_hook_cookie;
|
||||
//Functions
|
||||
static void apt_hook_func(int hook, void* param);
|
||||
static void reset_gpu_apt_resume();
|
||||
|
||||
int sf2d_init()
|
||||
{
|
||||
return sf2d_init_advanced(
|
||||
SF2D_GPUCMD_DEFAULT_SIZE,
|
||||
SF2D_TEMPPOOL_DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//Setup the shader
|
||||
dvlb = DVLB_ParseFile((u32 *)shader_vsh_shbin, shader_vsh_shbin_size);
|
||||
shaderProgramInit(&shader);
|
||||
shaderProgramSetVsh(&shader, &dvlb->DVLE[0]);
|
||||
|
||||
//Get shader uniform descriptors
|
||||
projection_desc = shaderInstanceGetUniformLocation(shader.vertexShader, "projection");
|
||||
|
||||
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);
|
||||
|
||||
vblank_wait = 1;
|
||||
current_fps = 0.0f;
|
||||
frames = 0;
|
||||
last_time = osGetTime();
|
||||
|
||||
cur_screen = GFX_TOP;
|
||||
cur_side = GFX_LEFT;
|
||||
|
||||
GPUCMD_Finalize();
|
||||
GPUCMD_FlushAndRun(NULL);
|
||||
gspWaitForP3D();
|
||||
|
||||
sf2d_pool_reset();
|
||||
|
||||
sf2d_initialized = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sf2d_fini()
|
||||
{
|
||||
if (!sf2d_initialized) return 0;
|
||||
|
||||
aptUnhook(&apt_hook_cookie);
|
||||
|
||||
gfxExit();
|
||||
shaderProgramFree(&shader);
|
||||
DVLB_Free(dvlb);
|
||||
|
||||
linearFree(pool_addr);
|
||||
linearFree(gpu_cmd);
|
||||
vramFree(gpu_fb_addr);
|
||||
vramFree(gpu_depth_fb_addr);
|
||||
|
||||
sf2d_initialized = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sf2d_set_3D(int enable)
|
||||
{
|
||||
gfxSet3D(enable);
|
||||
}
|
||||
|
||||
void sf2d_start_frame(gfxScreen_t screen, gfx3dSide_t side)
|
||||
{
|
||||
sf2d_pool_reset();
|
||||
GPUCMD_SetBufferOffset(0);
|
||||
|
||||
// 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;
|
||||
} else {
|
||||
screen_w = 320;
|
||||
}
|
||||
GPU_SetViewport((u32 *)osConvertVirtToPhys((u32)gpu_depth_fb_addr),
|
||||
(u32 *)osConvertVirtToPhys((u32)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_KEEP, GPU_KEEP, GPU_KEEP);
|
||||
GPU_SetBlendingColor(0,0,0,0);
|
||||
GPU_SetDepthTestAndWriteMask(true, GPU_GEQUAL, GPU_WRITE_ALL);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0);
|
||||
GPUCMD_AddWrite(GPUREG_0118, 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_end_frame()
|
||||
{
|
||||
GPU_FinishDrawing();
|
||||
GPUCMD_Finalize();
|
||||
GPUCMD_FlushAndRun(NULL);
|
||||
gspWaitForP3D();
|
||||
|
||||
//Copy the GPU rendered FB to the screen FB
|
||||
if (cur_screen == GFX_TOP) {
|
||||
GX_SetDisplayTransfer(NULL, gpu_fb_addr, GX_BUFFER_DIM(240, 400),
|
||||
(u32 *)gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL),
|
||||
GX_BUFFER_DIM(240, 400), 0x1000);
|
||||
} else {
|
||||
GX_SetDisplayTransfer(NULL, 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_SetMemoryFill(NULL, gpu_fb_addr, clear_color, &gpu_fb_addr[0x2EE00],
|
||||
0x201, gpu_depth_fb_addr, 0x00000000, &gpu_depth_fb_addr[0x2EE00], 0x201);
|
||||
gspWaitForPSC0();
|
||||
}
|
||||
|
||||
void sf2d_swapbuffers()
|
||||
{
|
||||
gfxSwapBuffersGpu();
|
||||
if (vblank_wait) {
|
||||
gspWaitForEvent(GSPEVENT_VBlank0, false);
|
||||
}
|
||||
//Calculate FPS
|
||||
frames++;
|
||||
u64 delta_time = osGetTime() - last_time;
|
||||
if (delta_time >= 1000) {
|
||||
current_fps = frames/(delta_time/1000.0f);
|
||||
frames = 0;
|
||||
last_time = osGetTime();
|
||||
}
|
||||
}
|
||||
|
||||
void sf2d_set_vblank_wait(int enable)
|
||||
{
|
||||
vblank_wait = enable;
|
||||
}
|
||||
|
||||
float sf2d_get_fps()
|
||||
{
|
||||
return current_fps;
|
||||
}
|
||||
|
||||
void *sf2d_pool_malloc(u32 size)
|
||||
{
|
||||
if ((pool_index + size) < pool_size) {
|
||||
void *addr = (void *)((u32)pool_addr + pool_index);
|
||||
pool_index += size;
|
||||
return addr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *sf2d_pool_memalign(u32 size, u32 alignment)
|
||||
{
|
||||
u32 new_index = (pool_index + alignment - 1) & ~(alignment - 1);
|
||||
if ((new_index + size) < pool_size) {
|
||||
void *addr = (void *)((u32)pool_addr + new_index);
|
||||
pool_index = new_index + size;
|
||||
return addr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int sf2d_pool_space_free()
|
||||
{
|
||||
return pool_size - pool_index;
|
||||
}
|
||||
|
||||
void sf2d_pool_reset()
|
||||
{
|
||||
pool_index = 0;
|
||||
}
|
||||
|
||||
void sf2d_set_clear_color(u32 color)
|
||||
{
|
||||
clear_color = 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);
|
||||
} else {
|
||||
GPU_SetScissorTest(mode, 240 - (y + h), 320 - (x + w), 240 - y, 320 - x);
|
||||
}
|
||||
}
|
||||
|
||||
gfxScreen_t sf2d_get_current_screen()
|
||||
{
|
||||
return cur_screen;
|
||||
}
|
||||
|
||||
gfx3dSide_t sf2d_get_current_side()
|
||||
{
|
||||
return cur_side;
|
||||
}
|
||||
|
||||
static void apt_hook_func(int 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(NULL);
|
||||
gspWaitForP3D();
|
||||
}
|
||||
212
libs/sf2dlib/libsf2d/source/sf2d_draw.c
Normal file
212
libs/sf2dlib/libsf2d/source/sf2d_draw.c
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
#include "sf2d.h"
|
||||
#include "sf2d_private.h"
|
||||
#include <math.h>
|
||||
|
||||
void sf2d_draw_line(int x0, int y0, int x1, int y1, u32 color)
|
||||
{
|
||||
sf2d_vertex_pos_col *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_col));
|
||||
if (!vertices) return;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x0+1.0f, (float)y0+1.0f, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x0-1.0f, (float)y0-1.0f, SF2D_DEFAULT_DEPTH};
|
||||
vertices[2].position = (sf2d_vector_3f){(float)x1+1.0f, (float)y1+1.0f, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){(float)x1-1.0f, (float)y1-1.0f, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
u8 r = (color>>24) & 0xFF;
|
||||
u8 g = (color>>16) & 0xFF;
|
||||
u8 b = (color>>8) & 0xFF;
|
||||
u8 a = color & 0xFF;
|
||||
|
||||
vertices[0].color = (sf2d_vector_4f){r/255.0f, g/255.0f, b/255.0f, a/255.0f};
|
||||
vertices[1].color = vertices[0].color;
|
||||
vertices[2].color = vertices[0].color;
|
||||
vertices[3].color = vertices[0].color;
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, 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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color)
|
||||
{
|
||||
sf2d_vertex_pos_col *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_col));
|
||||
if (!vertices) return;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x+w, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
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};
|
||||
|
||||
u8 r = (color>>24) & 0xFF;
|
||||
u8 g = (color>>16) & 0xFF;
|
||||
u8 b = (color>>8) & 0xFF;
|
||||
u8 a = color & 0xFF;
|
||||
|
||||
vertices[0].color = (sf2d_vector_4f){r/255.0f, g/255.0f, b/255.0f, a/255.0f};
|
||||
vertices[1].color = vertices[0].color;
|
||||
vertices[2].color = vertices[0].color;
|
||||
vertices[3].color = vertices[0].color;
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, 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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad)
|
||||
{
|
||||
sf2d_vertex_pos_col *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_col));
|
||||
if (!vertices) return;
|
||||
|
||||
int w2 = w/2.0f;
|
||||
int h2 = h/2.0f;
|
||||
|
||||
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};
|
||||
|
||||
u8 r = (color>>24) & 0xFF;
|
||||
u8 g = (color>>16) & 0xFF;
|
||||
u8 b = (color>>8) & 0xFF;
|
||||
u8 a = color & 0xFF;
|
||||
|
||||
vertices[0].color = (sf2d_vector_4f){r/255.0f, g/255.0f, b/255.0f, a/255.0f};
|
||||
vertices[1].color = vertices[0].color;
|
||||
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};
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, 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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_fill_circle(int x, int y, int radius, u32 color)
|
||||
{
|
||||
static const int num_segments = 100;
|
||||
sf2d_vertex_pos_col *vertices = sf2d_pool_malloc((num_segments + 2) * sizeof(sf2d_vertex_pos_col));
|
||||
if (!vertices) return;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
u8 r = (color>>24) & 0xFF;
|
||||
u8 g = (color>>16) & 0xFF;
|
||||
u8 b = (color>>8) & 0xFF;
|
||||
u8 a = color & 0xFF;
|
||||
|
||||
vertices[0].color = (sf2d_vector_4f){r/255.0f, g/255.0f, b/255.0f, a/255.0f};
|
||||
|
||||
float theta = 2 * M_PI / (float)num_segments;
|
||||
float c = cosf(theta);
|
||||
float s = sinf(theta);
|
||||
float t;
|
||||
|
||||
float xx = radius;
|
||||
float yy = 0;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= num_segments; i++) {
|
||||
vertices[i].position = (sf2d_vector_3f){(float)(x + xx), (float)(y + yy), SF2D_DEFAULT_DEPTH};
|
||||
vertices[i].color = vertices[0].color;
|
||||
|
||||
t = xx;
|
||||
xx = c * xx - s * yy;
|
||||
yy = s * t + c * yy;
|
||||
}
|
||||
|
||||
vertices[num_segments + 1].position = vertices[1].position;
|
||||
vertices[num_segments + 1].color = vertices[1].color;
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)vertices),
|
||||
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, 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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_FAN, num_segments + 2);
|
||||
}
|
||||
155
libs/sf2dlib/libsf2d/source/sf2d_private.c
Normal file
155
libs/sf2dlib/libsf2d/source/sf2d_private.c
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "sf2d_private.h"
|
||||
|
||||
//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)
|
||||
{
|
||||
float mu[4*4];
|
||||
|
||||
int i, j;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
mu[i*4 + j] = m[i*4 + (3-j)];
|
||||
}
|
||||
}
|
||||
|
||||
GPU_SetFloatUniform(GPU_VERTEX_SHADER, startreg, (u32 *)mu, 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;
|
||||
}
|
||||
620
libs/sf2dlib/libsf2d/source/sf2d_texture.c
Normal file
620
libs/sf2dlib/libsf2d/source/sf2d_texture.c
Normal file
|
|
@ -0,0 +1,620 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sf2d.h"
|
||||
#include "sf2d_private.h"
|
||||
|
||||
#define TEX_MIN_SIZE 8
|
||||
|
||||
static unsigned int nibbles_per_pixel(sf2d_texfmt format)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
} 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?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sf2d_texture *texture = malloc(sizeof(*texture));
|
||||
|
||||
texture->tiled = 0;
|
||||
texture->place = place;
|
||||
texture->pixel_format = pixel_format;
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
texture->pow2_w = pow2_w;
|
||||
texture->pow2_h = pow2_h;
|
||||
texture->data_size = data_size;
|
||||
texture->data = data;
|
||||
|
||||
memset(texture->data, 0, texture->data_size);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
free(texture);
|
||||
}
|
||||
}
|
||||
|
||||
void sf2d_fill_texture_from_RGBA8(sf2d_texture *dst, const void *rgba8, int source_w, int source_h)
|
||||
{
|
||||
// TODO: add support for non-RGBA8 textures
|
||||
|
||||
u8 *tmp = linearAlloc(dst->pow2_w * dst->pow2_h * 4);
|
||||
int i, j;
|
||||
for (i = 0; i < source_h; i++) {
|
||||
for (j = 0; j < source_w; j++) {
|
||||
((u32 *)tmp)[i*dst->pow2_w + j] = ((u32 *)rgba8)[i*source_w + j];
|
||||
}
|
||||
}
|
||||
memcpy(dst->data, tmp, dst->pow2_w*dst->pow2_h*4);
|
||||
linearFree(tmp);
|
||||
|
||||
sf2d_texture_tile32(dst);
|
||||
}
|
||||
|
||||
sf2d_texture *sf2d_create_texture_mem_RGBA8(const void *src_buffer, int src_w, int src_h, sf2d_texfmt pixel_format, sf2d_place place)
|
||||
{
|
||||
sf2d_texture *tex = sf2d_create_texture(src_w, src_h, pixel_format, place);
|
||||
if (tex == NULL) return NULL;
|
||||
sf2d_fill_texture_from_RGBA8(tex, src_buffer, src_w, src_h);
|
||||
return tex;
|
||||
}
|
||||
|
||||
void sf2d_bind_texture(const sf2d_texture *texture, GPU_TEXUNIT unit)
|
||||
{
|
||||
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((u32)texture->data),
|
||||
texture->pow2_w,
|
||||
texture->pow2_h,
|
||||
GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST),
|
||||
texture->pixel_format
|
||||
);
|
||||
}
|
||||
|
||||
void sf2d_bind_texture_color(const sf2d_texture *texture, GPU_TEXUNIT unit, u32 color)
|
||||
{
|
||||
GPU_SetTextureEnable(unit);
|
||||
|
||||
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,
|
||||
__builtin_bswap32(color) //RGBA8 -> ABGR8
|
||||
);
|
||||
|
||||
GPU_SetTexture(
|
||||
unit,
|
||||
(u32 *)osConvertVirtToPhys((u32)texture->data),
|
||||
texture->pow2_w,
|
||||
texture->pow2_h,
|
||||
GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST),
|
||||
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((u32)texture->data),
|
||||
texture->pow2_w,
|
||||
texture->pow2_h,
|
||||
params,
|
||||
texture->pixel_format
|
||||
);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture(const sf2d_texture *texture, int x, int y)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
int w = texture->width;
|
||||
int h = texture->height;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x+w, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
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;
|
||||
|
||||
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};
|
||||
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_rotate(const sf2d_texture *texture, int x, int y, float rad)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
int w2 = texture->width/2.0f;
|
||||
int h2 = texture->height/2.0f;
|
||||
|
||||
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 u = texture->width/(float)texture->pow2_w;
|
||||
float v = texture->height/(float)texture->pow2_h;
|
||||
|
||||
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};
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 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)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x+tex_w, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
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;
|
||||
|
||||
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};
|
||||
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_scale(const sf2d_texture *texture, int x, int y, float x_scale, float y_scale)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
int ws = texture->width * x_scale;
|
||||
int hs = texture->height * y_scale;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x+ws, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
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;
|
||||
|
||||
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};
|
||||
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_rotate_cut_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_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
//Don't even try to understand what I'm doing here (because I don't even understand it).
|
||||
//Matrices are boring.
|
||||
|
||||
int w2 = (tex_w * x_scale)/2.0f;
|
||||
int h2 = (tex_h * y_scale)/2.0f;
|
||||
|
||||
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;
|
||||
|
||||
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};
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_blend(const sf2d_texture *texture, int x, int y, u32 color)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
int w = texture->width;
|
||||
int h = texture->height;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x+w, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
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;
|
||||
|
||||
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};
|
||||
|
||||
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_part_blend(const sf2d_texture *texture, int x, int y, int tex_x, int tex_y, int tex_w, int tex_h, u32 color)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x+tex_w, (float)y, SF2D_DEFAULT_DEPTH};
|
||||
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;
|
||||
|
||||
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};
|
||||
|
||||
sf2d_bind_texture_color(texture, GPU_TEXUNIT0, color);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void sf2d_draw_texture_depth(const sf2d_texture *texture, int x, int y, signed short z)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
int w = texture->width;
|
||||
int h = texture->height;
|
||||
float depth = z/32768.0f + 0.5f;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, depth};
|
||||
vertices[1].position = (sf2d_vector_3f){(float)x+w, (float)y, depth};
|
||||
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;
|
||||
|
||||
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};
|
||||
|
||||
sf2d_bind_texture(texture, GPU_TEXUNIT0);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 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, unsigned int params)
|
||||
{
|
||||
sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex));
|
||||
if (!vertices) return;
|
||||
|
||||
vertices[0].position = (sf2d_vector_3f){left, top, SF2D_DEFAULT_DEPTH};
|
||||
vertices[1].position = (sf2d_vector_3f){right, top, SF2D_DEFAULT_DEPTH};
|
||||
vertices[2].position = (sf2d_vector_3f){left, bottom, SF2D_DEFAULT_DEPTH};
|
||||
vertices[3].position = (sf2d_vector_3f){right, bottom, SF2D_DEFAULT_DEPTH};
|
||||
|
||||
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};
|
||||
|
||||
sf2d_bind_texture_parameters(texture, GPU_TEXUNIT0, params);
|
||||
|
||||
GPU_SetAttributeBuffers(
|
||||
2, // number of attributes
|
||||
(u32*)osConvertVirtToPhys((u32)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
|
||||
);
|
||||
|
||||
GPU_DrawArray(GPU_TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
// Grabbed from Citra Emulator (citra/src/video_core/utils.h)
|
||||
static inline u32 morton_interleave(u32 x, u32 y)
|
||||
{
|
||||
u32 i = (x & 7) | ((y & 7) << 8); // ---- -210
|
||||
i = (i ^ (i << 2)) & 0x1313; // ---2 --10
|
||||
i = (i ^ (i << 1)) & 0x1515; // ---2 -1-0
|
||||
i = (i | (i >> 7)) & 0x3F;
|
||||
return i;
|
||||
}
|
||||
|
||||
//Grabbed from Citra Emulator (citra/src/video_core/utils.h)
|
||||
static inline u32 get_morton_offset(u32 x, u32 y, u32 bytes_per_pixel)
|
||||
{
|
||||
u32 i = morton_interleave(x, y);
|
||||
unsigned int offset = (x & ~7) * 8;
|
||||
return (i + offset) * bytes_per_pixel;
|
||||
}
|
||||
|
||||
void sf2d_set_pixel(sf2d_texture *texture, int x, int y, u32 new_color)
|
||||
{
|
||||
y = (texture->pow2_h - 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) = __builtin_bswap32(new_color);
|
||||
} else {
|
||||
((u32 *)texture->data)[x + y * texture->pow2_w] = __builtin_bswap32(new_color);
|
||||
}
|
||||
}
|
||||
|
||||
u32 sf2d_get_pixel(sf2d_texture *texture, int x, int y)
|
||||
{
|
||||
y = (texture->pow2_h - 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 __builtin_bswap32(*(u32 *)(texture->data + offset));
|
||||
} else {
|
||||
return __builtin_bswap32(((u32 *)texture->data)[x + y * texture->pow2_w]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
int i, j;
|
||||
for (j = 0; j < texture->pow2_h; j++) {
|
||||
for (i = 0; i < texture->pow2_w; i++) {
|
||||
|
||||
u32 coarse_y = j & ~7;
|
||||
u32 dst_offset = get_morton_offset(i, j, 4) + coarse_y * texture->pow2_w * 4;
|
||||
|
||||
u32 v = ((u32 *)texture->data)[i + (texture->pow2_h - 1 - j)*texture->pow2_w];
|
||||
*(u32 *)(tmp + dst_offset) = __builtin_bswap32(v);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(texture->data, tmp, texture->pow2_w*texture->pow2_h*4);
|
||||
linearFree(tmp);
|
||||
|
||||
texture->tiled = 1;
|
||||
}
|
||||
199
libs/sf2dlib/sample/Makefile
Normal file
199
libs/sf2dlib/sample/Makefile
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITARM)/3ds_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#
|
||||
# NO_SMDH: if set to anything, no SMDH file is generated.
|
||||
# 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)
|
||||
# ICON is the filename of the icon (.png), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.png
|
||||
# - icon.png
|
||||
# - <libctru folder>/default_icon.png
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := sf2d_sample
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
APP_TITLE := SF2DLIB sample
|
||||
APP_DESCRIPTION := SF2DLIB sample
|
||||
APP_AUTHOR := xerpi
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard
|
||||
|
||||
CFLAGS := -g -Wall -O2 -mword-relocations \
|
||||
-fomit-frame-pointer -ffast-math \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
|
||||
|
||||
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
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(CTRULIB) $(CURDIR)/../libsf2d
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
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)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
ifeq ($(strip $(ICON)),)
|
||||
icons := $(wildcard *.png)
|
||||
ifneq (,$(findstring $(TARGET).png,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/$(TARGET).png
|
||||
else
|
||||
ifneq (,$(findstring icon.png,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/icon.png
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_ICON := $(TOPDIR)/$(ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_SMDH)),)
|
||||
export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf $(TARGET)-strip.elf $(TARGET).cia $(TARGET).3ds
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET)-strip.elf: $(BUILD)
|
||||
@$(STRIP) --strip-all $(TARGET).elf -o $(TARGET)-strip.elf
|
||||
#---------------------------------------------------------------------------------
|
||||
cci: $(TARGET)-strip.elf
|
||||
@makerom -f cci -rsf resources/$(TARGET).rsf -target d -exefslogo -elf $(TARGET)-strip.elf -o $(TARGET).3ds
|
||||
@echo "built ... sf2d_sample.3ds"
|
||||
#---------------------------------------------------------------------------------
|
||||
cia: $(TARGET)-strip.elf
|
||||
@makerom -f cia -o $(TARGET).cia -elf $(TARGET)-strip.elf -rsf resources/$(TARGET).rsf -icon resources/icon.icn -banner resources/banner.bnr -exefslogo -target t
|
||||
@echo "built ... sf2d_sample.cia"
|
||||
#---------------------------------------------------------------------------------
|
||||
send: $(BUILD)
|
||||
@3dslink $(TARGET).3dsx
|
||||
#---------------------------------------------------------------------------------
|
||||
run: $(BUILD)
|
||||
@citra $(TARGET).3dsx
|
||||
#---------------------------------------------------------------------------------
|
||||
copy_cia: $(TARGET).cia
|
||||
@cp $(TARGET).cia /mnt/GATEWAYNAND
|
||||
sync
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(NO_SMDH)),)
|
||||
$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh
|
||||
else
|
||||
$(OUTPUT).3dsx : $(OUTPUT).elf
|
||||
endif
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
# WARNING: This is not the right way to do this! TODO: Do it right!
|
||||
#---------------------------------------------------------------------------------
|
||||
%.vsh.o : %.vsh
|
||||
#---------------------------------------------------------------------------------
|
||||
@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
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
236
libs/sf2dlib/sample/resources/sf2d_sample.rsf
Normal file
236
libs/sf2dlib/sample/resources/sf2d_sample.rsf
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
BasicInfo:
|
||||
Title : "sf2dlibS"
|
||||
CompanyCode : "00"
|
||||
ProductCode : "CTR-N-S3DS"
|
||||
ContentType : Application # Application / SystemUpdate / Manual / Child / Trial
|
||||
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem
|
||||
|
||||
RomFs:
|
||||
# Specifies the root path of the file system to include in the ROM.
|
||||
# HostRoot : "$(ROMFS_ROOT)"
|
||||
|
||||
|
||||
TitleInfo:
|
||||
UniqueId : 0xf1001 # This was/is the first real homebrew app. I hope this TID range is not used by any retail game/app.
|
||||
Category : Application # Application / SystemApplication / Applet / Firmware / Base / DlpChild / Demo / Contents / SystemContents / SharedContents / AddOnContents / Patch / AutoUpdateContents
|
||||
|
||||
CardInfo:
|
||||
MediaSize : 128MB # 128MB / 256MB / 512MB / 1GB / 2GB / 4GB / 8GB / 16GB / 32GB
|
||||
MediaType : Card1 # Card1 / Card2
|
||||
CardDevice : None # NorFlash / None
|
||||
|
||||
|
||||
Option:
|
||||
UseOnSD : true # true if App is to be installed to SD
|
||||
EnableCompress : true # Compresses exefs code
|
||||
FreeProductCode : true # Removes limitations on ProductCode
|
||||
EnableCrypt : false # Enables encryption for NCCH and CIA
|
||||
MediaFootPadding : false # If true CCI files are created with padding
|
||||
|
||||
ExeFs: # these are the program segments from the ELF, check your elf for the appropriate segment names
|
||||
ReadOnly:
|
||||
- .rodata
|
||||
- RO
|
||||
ReadWrite:
|
||||
- .data
|
||||
- RO
|
||||
Text:
|
||||
- .init
|
||||
- .text
|
||||
- STUP_ENTRY
|
||||
|
||||
PlainRegion: # only used with SDK ELFs
|
||||
# - .module_id
|
||||
|
||||
AccessControlInfo:
|
||||
# UseOtherVariationSaveData : true
|
||||
# UseExtSaveData : true
|
||||
# ExtSaveDataId: 0xffffffff
|
||||
# SystemSaveDataId1: 0x220
|
||||
# SystemSaveDataId2: 0x00040010
|
||||
# OtherUserSaveDataId1: 0x220
|
||||
# OtherUserSaveDataId2: 0x330
|
||||
# OtherUserSaveDataId3: 0x440
|
||||
# UseExtendedSaveDataAccessControl: true
|
||||
# AccessibleSaveDataIds: [0x101, 0x202, 0x303, 0x404, 0x505, 0x606]
|
||||
FileSystemAccess:
|
||||
# - CategorySystemApplication
|
||||
# - CategoryHardwareCheck
|
||||
# - CategoryFileSystemTool
|
||||
- Debug
|
||||
# - TwlCardBackup
|
||||
# - TwlNandData
|
||||
# - Boss
|
||||
- DirectSdmc
|
||||
# - Core
|
||||
# - CtrNandRo
|
||||
# - CtrNandRw
|
||||
# - CtrNandRoWrite
|
||||
# - CategorySystemSettings
|
||||
# - CardBoard
|
||||
# - ExportImportIvs
|
||||
# - DirectSdmcWrite
|
||||
# - SwitchCleanup
|
||||
# - SaveDataMove
|
||||
# - Shop
|
||||
# - Shell
|
||||
# - CategoryHomeMenu
|
||||
IoAccessControl:
|
||||
# - FsMountNand
|
||||
# - FsMountNandRoWrite
|
||||
# - FsMountTwln
|
||||
# - FsMountWnand
|
||||
# - FsMountCardSpi
|
||||
# - UseSdif3
|
||||
# - CreateSeed
|
||||
# - UseCardSpi
|
||||
|
||||
IdealProcessor : 0
|
||||
AffinityMask : 1
|
||||
|
||||
Priority : 16
|
||||
|
||||
MaxCpu : 0x9E # Default
|
||||
|
||||
DisableDebug : true
|
||||
EnableForceDebug : false
|
||||
CanWriteSharedPage : true
|
||||
CanUsePrivilegedPriority : false
|
||||
CanUseNonAlphabetAndNumber : true
|
||||
PermitMainFunctionArgument : true
|
||||
CanShareDeviceMemory : true
|
||||
RunnableOnSleep : false
|
||||
SpecialMemoryArrange : true
|
||||
|
||||
CoreVersion : 2
|
||||
DescVersion : 2
|
||||
|
||||
ReleaseKernelMajor : "02"
|
||||
ReleaseKernelMinor : "33"
|
||||
MemoryType : Application # Application / System / Base
|
||||
HandleTableSize: 512
|
||||
IORegisterMapping:
|
||||
- 1ff50000-1ff57fff
|
||||
- 1ff70000-1ff77fff
|
||||
MemoryMapping:
|
||||
- 1f000000-1f5fffff:r
|
||||
SystemCallAccess:
|
||||
ArbitrateAddress: 34
|
||||
Break: 60
|
||||
CancelTimer: 28
|
||||
ClearEvent: 25
|
||||
ClearTimer: 29
|
||||
CloseHandle: 35
|
||||
ConnectToPort: 45
|
||||
ControlMemory: 1
|
||||
CreateAddressArbiter: 33
|
||||
CreateEvent: 23
|
||||
CreateMemoryBlock: 30
|
||||
CreateMutex: 19
|
||||
CreateSemaphore: 21
|
||||
CreateThread: 8
|
||||
CreateTimer: 26
|
||||
DuplicateHandle: 39
|
||||
ExitProcess: 3
|
||||
ExitThread: 9
|
||||
GetCurrentProcessorNumber: 17
|
||||
GetHandleInfo: 41
|
||||
GetProcessId: 53
|
||||
GetProcessIdOfThread: 54
|
||||
GetProcessIdealProcessor: 6
|
||||
GetProcessInfo: 43
|
||||
GetResourceLimit: 56
|
||||
GetResourceLimitCurrentValues: 58
|
||||
GetResourceLimitLimitValues: 57
|
||||
GetSystemInfo: 42
|
||||
GetSystemTick: 40
|
||||
GetThreadContext: 59
|
||||
GetThreadId: 55
|
||||
GetThreadIdealProcessor: 15
|
||||
GetThreadInfo: 44
|
||||
GetThreadPriority: 11
|
||||
MapMemoryBlock: 31
|
||||
OutputDebugString: 61
|
||||
QueryMemory: 2
|
||||
ReleaseMutex: 20
|
||||
ReleaseSemaphore: 22
|
||||
SendSyncRequest1: 46
|
||||
SendSyncRequest2: 47
|
||||
SendSyncRequest3: 48
|
||||
SendSyncRequest4: 49
|
||||
SendSyncRequest: 50
|
||||
SetThreadPriority: 12
|
||||
SetTimer: 27
|
||||
SignalEvent: 24
|
||||
SleepThread: 10
|
||||
UnmapMemoryBlock: 32
|
||||
WaitSynchronization1: 36
|
||||
WaitSynchronizationN: 37
|
||||
InterruptNumbers:
|
||||
ServiceAccessControl:
|
||||
- APT:U
|
||||
- $hioFIO
|
||||
- $hostio0
|
||||
- $hostio1
|
||||
- ac:u
|
||||
- boss:U
|
||||
- cam:u
|
||||
- cecd:u
|
||||
- cfg:u
|
||||
- dlp:FKCL
|
||||
- dlp:SRVR
|
||||
- dsp::DSP
|
||||
- frd:u
|
||||
- fs:USER
|
||||
- gsp::Gpu
|
||||
- hid:USER
|
||||
- http:C
|
||||
- mic:u
|
||||
- ndm:u
|
||||
- news:u
|
||||
- nwm::UDS
|
||||
- ptm:u
|
||||
- pxi:dev
|
||||
- soc:U
|
||||
- ssl:C
|
||||
- y2r:u
|
||||
- ldr:ro
|
||||
- ir:USER
|
||||
|
||||
|
||||
SystemControlInfo:
|
||||
SaveDataSize: 0KB # It doesn't use any save data.
|
||||
RemasterVersion: 2
|
||||
StackSize: 0x40000
|
||||
# JumpId: 0
|
||||
Dependency:
|
||||
ac: 0x0004013000002402L
|
||||
am: 0x0004013000001502L
|
||||
boss: 0x0004013000003402L
|
||||
camera: 0x0004013000001602L
|
||||
cecd: 0x0004013000002602L
|
||||
cfg: 0x0004013000001702L
|
||||
codec: 0x0004013000001802L
|
||||
csnd: 0x0004013000002702L
|
||||
dlp: 0x0004013000002802L
|
||||
dsp: 0x0004013000001a02L
|
||||
friends: 0x0004013000003202L
|
||||
gpio: 0x0004013000001b02L
|
||||
gsp: 0x0004013000001c02L
|
||||
hid: 0x0004013000001d02L
|
||||
http: 0x0004013000002902L
|
||||
i2c: 0x0004013000001e02L
|
||||
ir: 0x0004013000003302L
|
||||
mcu: 0x0004013000001f02L
|
||||
mic: 0x0004013000002002L
|
||||
ndm: 0x0004013000002b02L
|
||||
news: 0x0004013000003502L
|
||||
nim: 0x0004013000002c02L
|
||||
nwm: 0x0004013000002d02L
|
||||
pdn: 0x0004013000002102L
|
||||
ps: 0x0004013000003102L
|
||||
ptm: 0x0004013000002202L
|
||||
ro: 0x0004013000003702L
|
||||
socket: 0x0004013000002e02L
|
||||
spi: 0x0004013000002302L
|
||||
ssl: 0x0004013000002f02L
|
||||
2585
libs/sf2dlib/sample/source/citra_img.c
Normal file
2585
libs/sf2dlib/sample/source/citra_img.c
Normal file
File diff suppressed because it is too large
Load diff
2363
libs/sf2dlib/sample/source/dice_img.c
Normal file
2363
libs/sf2dlib/sample/source/dice_img.c
Normal file
File diff suppressed because it is too large
Load diff
83
libs/sf2dlib/sample/source/main.c
Normal file
83
libs/sf2dlib/sample/source/main.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <3ds.h>
|
||||
#include <sf2d.h>
|
||||
|
||||
extern const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel;
|
||||
unsigned char pixel_data[];
|
||||
} citra_img;
|
||||
|
||||
extern const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel;
|
||||
unsigned char pixel_data[];
|
||||
} dice_img;
|
||||
|
||||
int main()
|
||||
{
|
||||
// Set the random seed based on the time
|
||||
srand(time(NULL));
|
||||
|
||||
sf2d_init();
|
||||
sf2d_set_clear_color(RGBA8(0x40, 0x40, 0x40, 0xFF));
|
||||
|
||||
|
||||
sf2d_texture *tex1 = sf2d_create_texture_mem_RGBA8(dice_img.pixel_data, dice_img.width, dice_img.height, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
||||
sf2d_texture *tex2 = sf2d_create_texture_mem_RGBA8(citra_img.pixel_data, citra_img.width, citra_img.height, TEXFMT_RGBA8, SF2D_PLACE_RAM);
|
||||
|
||||
float rad = 0.0f;
|
||||
u16 touch_x = 320/2;
|
||||
u16 touch_y = 240/2;
|
||||
touchPosition touch;
|
||||
circlePosition circle;
|
||||
u32 held;
|
||||
|
||||
while (aptMainLoop()) {
|
||||
|
||||
hidScanInput();
|
||||
hidCircleRead(&circle);
|
||||
held = hidKeysHeld();
|
||||
|
||||
if (held & KEY_START) {
|
||||
break;
|
||||
} else if (held & KEY_TOUCH) {
|
||||
hidTouchRead(&touch);
|
||||
touch_x = touch.px;
|
||||
touch_y = touch.py;
|
||||
} else if (held & (KEY_L | KEY_R)) {
|
||||
sf2d_set_clear_color(RGBA8(rand()%255, rand()%255, rand()%255, 255));
|
||||
}
|
||||
|
||||
sf2d_start_frame(GFX_TOP, GFX_LEFT);
|
||||
sf2d_draw_rectangle_rotate(260, 20, 40, 40, RGBA8(0xFF, 0xFF, 0x00, 0xFF), -2.0f*rad);
|
||||
sf2d_draw_rectangle(20, 60, 40, 40, RGBA8(0xFF, 0x00, 0x00, 0xFF));
|
||||
sf2d_draw_rectangle(5, 5, 30, 30, RGBA8(0x00, 0xFF, 0xFF, 0xFF));
|
||||
sf2d_draw_texture_rotate(tex1, 320/2-tex1->width/2 + circle.dx, 240/2-tex1->height/2 - circle.dy, rad);
|
||||
sf2d_end_frame();
|
||||
|
||||
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
|
||||
sf2d_draw_rectangle_rotate(190, 160, 70, 60, RGBA8(0xFF, 0xFF, 0xFF, 0xFF), 3.0f*rad);
|
||||
sf2d_draw_rectangle(30, 100, 40, 60, RGBA8(0xFF, 0x00, 0xFF, 0xFF));
|
||||
sf2d_draw_texture_rotate(tex2, touch_x-tex1->width/2, touch_y-tex1->height/2, -rad);
|
||||
sf2d_draw_rectangle(160-15 + cosf(rad)*50.0f, 120-15 + sinf(rad)*50.0f, 30, 30, RGBA8(0x00, 0xFF, 0xFF, 0xFF));
|
||||
sf2d_draw_fill_circle(40, 40, 35, RGBA8(0x00, 0xFF, 0x00, 0xFF));
|
||||
sf2d_end_frame();
|
||||
|
||||
rad += 0.2f;
|
||||
|
||||
sf2d_swapbuffers();
|
||||
}
|
||||
|
||||
sf2d_free_texture(tex1);
|
||||
sf2d_free_texture(tex2);
|
||||
|
||||
sf2d_fini();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue