diff --git a/extern/lib/libdeflatestatic.lib b/extern/lib/libdeflatestatic.lib index 0cc709c5..d7ccbf5f 100644 Binary files a/extern/lib/libdeflatestatic.lib and b/extern/lib/libdeflatestatic.lib differ diff --git a/extern/lib/libogg.lib b/extern/lib/libogg.lib new file mode 100644 index 00000000..21130191 Binary files /dev/null and b/extern/lib/libogg.lib differ diff --git a/extern/lib/libogg.pdb b/extern/lib/libogg.pdb new file mode 100644 index 00000000..218f8bf9 Binary files /dev/null and b/extern/lib/libogg.pdb differ diff --git a/extern/lib/liboggd.lib b/extern/lib/liboggd.lib new file mode 100644 index 00000000..b4e201f3 Binary files /dev/null and b/extern/lib/liboggd.lib differ diff --git a/extern/lib/liboggd.pdb b/extern/lib/liboggd.pdb new file mode 100644 index 00000000..d1af509b Binary files /dev/null and b/extern/lib/liboggd.pdb differ diff --git a/extern/lib/libvorbis.lib b/extern/lib/libvorbis.lib new file mode 100644 index 00000000..f62912dc Binary files /dev/null and b/extern/lib/libvorbis.lib differ diff --git a/extern/lib/libvorbis.pdb b/extern/lib/libvorbis.pdb new file mode 100644 index 00000000..7c5cba00 Binary files /dev/null and b/extern/lib/libvorbis.pdb differ diff --git a/extern/lib/libvorbisd.lib b/extern/lib/libvorbisd.lib new file mode 100644 index 00000000..8f21d65e Binary files /dev/null and b/extern/lib/libvorbisd.lib differ diff --git a/extern/lib/libvorbisd.pdb b/extern/lib/libvorbisd.pdb new file mode 100644 index 00000000..116f0c82 Binary files /dev/null and b/extern/lib/libvorbisd.pdb differ diff --git a/extern/lib/libvorbisfile.lib b/extern/lib/libvorbisfile.lib new file mode 100644 index 00000000..14286a1b Binary files /dev/null and b/extern/lib/libvorbisfile.lib differ diff --git a/extern/lib/libvorbisfile.pdb b/extern/lib/libvorbisfile.pdb new file mode 100644 index 00000000..7f603bf6 Binary files /dev/null and b/extern/lib/libvorbisfile.pdb differ diff --git a/extern/lib/libvorbisfiled.lib b/extern/lib/libvorbisfiled.lib new file mode 100644 index 00000000..cae3e83d Binary files /dev/null and b/extern/lib/libvorbisfiled.lib differ diff --git a/extern/lib/libvorbisfiled.pdb b/extern/lib/libvorbisfiled.pdb new file mode 100644 index 00000000..f10ea527 Binary files /dev/null and b/extern/lib/libvorbisfiled.pdb differ diff --git a/extern/src/libdeflate.h b/extern/src/libdeflate.h index a13ac71e..74c65bea 100644 --- a/extern/src/libdeflate.h +++ b/extern/src/libdeflate.h @@ -10,15 +10,15 @@ extern "C" { #endif #define LIBDEFLATE_VERSION_MAJOR 1 -#define LIBDEFLATE_VERSION_MINOR 12 -#define LIBDEFLATE_VERSION_STRING "1.12" +#define LIBDEFLATE_VERSION_MINOR 14 +#define LIBDEFLATE_VERSION_STRING "1.14" #include #include /* * On Windows, if you want to link to the DLL version of libdeflate, then - * #define LIBDEFLATE_DLL. Note that the calling convention is "stdcall". + * #define LIBDEFLATE_DLL. Note that the calling convention is "cdecl". */ #ifdef LIBDEFLATE_DLL # ifdef BUILDING_LIBDEFLATE @@ -31,12 +31,6 @@ extern "C" { # define LIBDEFLATEEXPORT #endif -#if defined(_WIN32) && !defined(_WIN64) && defined(LIBDEFLATE_DLL) -# define LIBDEFLATEAPI_ABI __stdcall -#else -# define LIBDEFLATEAPI_ABI -#endif - #if defined(BUILDING_LIBDEFLATE) && defined(__GNUC__) && \ defined(_WIN32) && !defined(_WIN64) /* @@ -44,13 +38,11 @@ extern "C" { * Realign the stack when entering libdeflate to avoid crashing in SSE/AVX * code when called from an MSVC-compiled application. */ -# define LIBDEFLATEAPI_STACKALIGN __attribute__((force_align_arg_pointer)) +# define LIBDEFLATEAPI __attribute__((force_align_arg_pointer)) #else -# define LIBDEFLATEAPI_STACKALIGN +# define LIBDEFLATEAPI #endif -#define LIBDEFLATEAPI LIBDEFLATEAPI_ABI LIBDEFLATEAPI_STACKALIGN - /* ========================================================================== */ /* Compression */ /* ========================================================================== */ diff --git a/extern/src/ogg/ogg.h b/extern/src/ogg/ogg.h new file mode 100644 index 00000000..c4325aa7 --- /dev/null +++ b/extern/src/ogg/ogg.h @@ -0,0 +1,209 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern int oggpack_writecheck(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern int oggpackB_writecheck(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_check(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_check(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(const ogg_page *og); +extern int ogg_page_continued(const ogg_page *og); +extern int ogg_page_bos(const ogg_page *og); +extern int ogg_page_eos(const ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); +extern int ogg_page_serialno(const ogg_page *og); +extern long ogg_page_pageno(const ogg_page *og); +extern int ogg_page_packets(const ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/extern/src/ogg/os_types.h b/extern/src/ogg/os_types.h new file mode 100644 index 00000000..e655a1d6 --- /dev/null +++ b/extern/src/ogg/os_types.h @@ -0,0 +1,158 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: Define a consistent set of types on each platform. + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# elif defined(__MINGW32__) +# include + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else +# if defined(_MSC_VER) && (_MSC_VER >= 1800) /* MSVC 2013 and newer */ +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef unsigned __int64 ogg_uint64_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif +# endif + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef u_int64_t ogg_uint64_t; + +#elif defined(__HAIKU__) + + /* Haiku */ +# include + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef unsigned long ogg_uint64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + typedef unsigned long long int ogg_uint64_t; + +#elif defined(__TMS320C6X__) + + /* TI C64x compiler */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + typedef unsigned long long int ogg_uint64_t; + +#else + +# include + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/extern/src/vorbis/codec.h b/extern/src/vorbis/codec.h new file mode 100644 index 00000000..f8a912bc --- /dev/null +++ b/extern/src/vorbis/codec.h @@ -0,0 +1,242 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation https://xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independent from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, const char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + const char *tag, const char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +extern const char *vorbis_version_string(void); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_idheader(ogg_packet *op); +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/extern/src/vorbis/vorbisenc.h b/extern/src/vorbis/vorbisenc.h new file mode 100644 index 00000000..085b15e6 --- /dev/null +++ b/extern/src/vorbis/vorbisenc.h @@ -0,0 +1,435 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation https://xiph.org/ * + * * + ******************************************************************** + + function: vorbis encode-engine setup + + ********************************************************************/ + +/** \file + * Libvorbisenc is a convenient API for setting up an encoding + * environment using libvorbis. Libvorbisenc encapsulates the + * actions needed to set up the encoder properly. + */ + +#ifndef _OV_ENC_H_ +#define _OV_ENC_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "codec.h" + +/** + * This is the primary function within libvorbisenc for setting up managed + * bitrate modes. + * + * Before this function is called, the \ref vorbis_info + * struct should be initialized by using vorbis_info_init() from the libvorbis + * API. After encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step bitrate-managed encode + * setup. It functions similarly to the one-step setup performed by \ref + * vorbis_encode_init but allows an application to make further encode setup + * tweaks using \ref vorbis_encode_ctl before finally calling \ref + * vorbis_encode_setup_init to complete the setup process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step variable bitrate + * (quality-based) encode setup. It functions similarly to the one-step setup + * performed by \ref vorbis_encode_init_vbr() but allows an application to + * make further encode setup tweaks using \ref vorbis_encode_ctl() before + * finally calling \ref vorbis_encode_setup_init to complete the setup + * process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using \ref vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + + float quality + ); + +/** + * This is the primary function within libvorbisenc for setting up variable + * bitrate ("quality" based) modes. + * + * + * Before this function is called, the vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * + * \return Zero for success, or a negative number for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality + ); + +/** + * This function performs the last stage of three-step encoding setup, as + * described in the API overview under managed bitrate modes. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API, one of + * \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to + * initialize the high-level encoding setup, and \ref vorbis_encode_ctl() + * called if necessary to make encoding setup changes. + * vorbis_encode_setup_init() finalizes the highlevel encoding structure into + * a complete encoding setup after which the application may make no further + * setup changes. + * + * After encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * + * \retval OV_EINVAL Attempt to use vorbis_encode_setup_init() without first + * calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to + * initialize the high-level encoding setup + * + */ +extern int vorbis_encode_setup_init(vorbis_info *vi); + +/** + * This function implements a generic interface to miscellaneous encoder + * settings similar to the classic UNIX 'ioctl()' system call. Applications + * may use vorbis_encode_ctl() to query or set bitrate management or quality + * mode details by using one of several \e request arguments detailed below. + * vorbis_encode_ctl() must be called after one of + * vorbis_encode_setup_managed() or vorbis_encode_setup_vbr(). When used + * to modify settings, \ref vorbis_encode_ctl() must be called before \ref + * vorbis_encode_setup_init(). + * + * \param vi Pointer to an initialized vorbis_info struct. + * + * \param number Specifies the desired action; See \ref encctlcodes "the list + * of available requests". + * + * \param arg void * pointing to a data structure matching the request + * argument. + * + * \retval 0 Success. Any further return information (such as the result of a + * query) is placed into the storage pointed to by *arg. + * + * \retval OV_EINVAL Invalid argument, or an attempt to modify a setting after + * calling vorbis_encode_setup_init(). + * + * \retval OV_EIMPL Unimplemented or unknown request + */ +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg); + +/** + * \deprecated This is a deprecated interface. Please use vorbis_encode_ctl() + * with the \ref ovectl_ratemanage2_arg struct and \ref + * OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code. + * + * The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl() + * and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref + * OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. +*/ +struct ovectl_ratemanage_arg { + int management_active; /**< nonzero if bitrate management is active*/ +/** hard lower limit (in kilobits per second) below which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_min; +/** hard upper limit (in kilobits per second) above which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_max; +/** the window period (in seconds) used to regulate the hard bitrate minimum + and maximum*/ + double bitrate_hard_window; +/** soft lower limit (in kilobits per second) below which the average bitrate + tracker will start nudging the bitrate higher.*/ + long bitrate_av_lo; +/** soft upper limit (in kilobits per second) above which the average bitrate + tracker will start nudging the bitrate lower.*/ + long bitrate_av_hi; +/** the window period (in seconds) used to regulate the average bitrate + minimum and maximum.*/ + double bitrate_av_window; +/** Regulates the relative centering of the average and hard windows; in + libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but + followed the average window regulation. In libvorbis 1.1 a bit-reservoir + interface replaces the old windowing interface; the older windowing + interface is simulated and this field has no effect.*/ + double bitrate_av_window_center; +}; + +/** + * \name struct ovectl_ratemanage2_arg + * + * The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and + * the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. + * +*/ +struct ovectl_ratemanage2_arg { + int management_active; /**< nonzero if bitrate management is active */ +/** Lower allowed bitrate limit in kilobits per second */ + long bitrate_limit_min_kbps; +/** Upper allowed bitrate limit in kilobits per second */ + long bitrate_limit_max_kbps; + long bitrate_limit_reservoir_bits; /**struct ovectl_ratemanage2_arg * + * + * Used to query the current encoder bitrate management setting. Also used to + * initialize fields of an ovectl_ratemanage2_arg structure for use with + * \ref OV_ECTL_RATEMANAGE2_SET. + */ +#define OV_ECTL_RATEMANAGE2_GET 0x14 + +/** + * Set the current encoder bitrate management settings. + * + * Argument: struct ovectl_ratemanage2_arg * + * + * Used to set the current encoder bitrate management settings to the values + * listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable + * bitrate management. +*/ +#define OV_ECTL_RATEMANAGE2_SET 0x15 + +/** + * Returns the current encoder hard-lowpass setting (kHz) in the double + * pointed to by arg. + * + * Argument: double * +*/ +#define OV_ECTL_LOWPASS_GET 0x20 + +/** + * Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid + * lowpass settings range from 2 to 99. + * + * Argument: double * +*/ +#define OV_ECTL_LOWPASS_SET 0x21 + +/** + * Returns the current encoder impulse block setting in the double pointed + * to by arg. + * + * Argument: double * +*/ +#define OV_ECTL_IBLOCK_GET 0x30 + +/** + * Sets the impulse block bias to the the value pointed to by arg. + * + * Argument: double * + * + * Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will + * direct to encoder to use more bits when incoding short blocks that contain + * strong impulses, thus improving the accuracy of impulse encoding. + */ +#define OV_ECTL_IBLOCK_SET 0x31 + +/** + * Returns the current encoder coupling setting in the int pointed + * to by arg. + * + * Argument: int * +*/ +#define OV_ECTL_COUPLING_GET 0x40 + +/** + * Enables/disables channel coupling in multichannel encoding according to arg. + * + * Argument: int * + * + * Zero disables channel coupling for multichannel inputs, nonzer enables + * channel coupling. Setting has no effect on monophonic encoding or + * multichannel counts that do not offer coupling. At present, coupling is + * available for stereo and 5.1 encoding. + */ +#define OV_ECTL_COUPLING_SET 0x41 + + /* deprecated rate management supported only for compatibility */ + +/** + * Old interface to querying bitrate management settings. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead. + * + * Argument: struct ovectl_ratemanage_arg * + */ +#define OV_ECTL_RATEMANAGE_GET 0x10 +/** + * Old interface to modifying bitrate management settings. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: struct ovectl_ratemanage_arg * + */ +#define OV_ECTL_RATEMANAGE_SET 0x11 +/** + * Old interface to setting average-bitrate encoding mode. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: struct ovectl_ratemanage_arg * + */ +#define OV_ECTL_RATEMANAGE_AVG 0x12 +/** + * Old interface to setting bounded-bitrate encoding modes. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: struct ovectl_ratemanage_arg * + */ +#define OV_ECTL_RATEMANAGE_HARD 0x13 + +/*@}*/ + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/extern/src/vorbis/vorbisfile.h b/extern/src/vorbis/vorbisfile.h new file mode 100644 index 00000000..3d65393f --- /dev/null +++ b/extern/src/vorbis/vorbisfile.h @@ -0,0 +1,205 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation https://xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#ifndef OV_EXCLUDE_STATIC_CALLBACKS + +/* a few sets of convenient callbacks, especially for use under + * Windows where ov_open_callbacks() should always be used instead of + * ov_open() to avoid problems with incompatible crt.o version linking + * issues. */ + +static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + +#ifdef __MINGW32__ + return fseeko64(f,off,whence); +#elif defined (_WIN32) + return _fseeki64(f,off,whence); +#else + return fseek(f,off,whence); +#endif +} + +/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as + * static data. That means that every file which includes this header + * will get its own copy of these structs whether it uses them or + * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS. + * These static symbols are essential on platforms such as Windows on + * which several different versions of stdio support may be linked to + * by different DLLs, and we need to be certain we know which one + * we're using (the same one as the main application). + */ + +static ov_callbacks OV_CALLBACKS_DEFAULT = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) NULL, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) fclose, + (long (*)(void *)) NULL +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) NULL, + (long (*)(void *)) NULL +}; + +#endif + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatibility; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_fopen(const char *path,OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream, + void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/src/CRE/Glitter/curve.cpp b/src/CRE/Glitter/curve.cpp index a88dbe3a..fd7c6e0e 100644 --- a/src/CRE/Glitter/curve.cpp +++ b/src/CRE/Glitter/curve.cpp @@ -275,7 +275,7 @@ namespace Glitter { bool has_error = false; bool has_error_lerp = false; for (size_t j = 1; j < left_count; j++) { - float_t val = lerp(a[0], a[left_count - 1], (float_t)j / (float_t)left_count); + float_t val = lerp_def(a[0], a[left_count - 1], (float_t)j / (float_t)left_count); if (fabsf(val - a[0]) > reverse_bias[0]) { has_error = true; if (fabsf(val - a[j]) > reverse_bias[1]) { @@ -312,7 +312,7 @@ namespace Glitter { for (size_t j = 1; j < i - 1; j++) { float_t _t1 = 0.0f; float_t _t2 = 0.0f; - interpolate_chs_reverse_step_value(a, left_count, &_t1, &_t2, 0, i, j, step); + interpolate_chs_reverse_step_value(a, left_count, _t1, _t2, 0, i, j, step); tt1 += _t1; tt2 += _t2; } @@ -326,7 +326,7 @@ namespace Glitter { for (size_t j = 1; j < i; j++) { float_t val = interpolate_chs_value(a[0], a[i], t1, t2, 0.0f, (float_t)(i * step), (float_t)(j * step)); - float_t val_lerp = lerp(a[0], a[i], (float_t)j / (float_t)i); + float_t val_lerp = lerp_def(a[0], a[i], (float_t)j / (float_t)i); if (fabsf(val - a[0]) > reverse_bias[0]) { has_error = true; constant = false; @@ -342,7 +342,7 @@ namespace Glitter { constant = true; } - if (fabsf(t1) > 1.0f || fabsf(t2) > 1.0f) + if (fabsf(t1) > 0.5f || fabsf(t2) > 0.5f) has_error_hermite = true; if (!has_error_hermite) { @@ -401,8 +401,8 @@ namespace Glitter { key.tangent2 = 0.0f; key.random_range = arr_b[count - 1]; keys_rev.push_back(key); - free(arr_a); - free(arr_b); + free_def(arr_a); + free_def(arr_b); Recalculate(GLT_VAL); } diff --git a/src/CRE/Glitter/effect.cpp b/src/CRE/Glitter/effect.cpp index b47b9c3a..ed00a1ed 100644 --- a/src/CRE/Glitter/effect.cpp +++ b/src/CRE/Glitter/effect.cpp @@ -31,166 +31,3 @@ namespace Glitter { delete i; } } - -/* -#include "effect.hpp" -#include "animation.hpp" -#include "emitter.hpp" - -static bool glitter_effect_pack_file(GLT, f2_struct* st, glitter_effect* a3); - -glitter_effect::glitter_effect(GLT) : name(), translation(), rotation(), data() { -} - -glitter_effect::~glitter_effect() { - free(data.ext_anim); - for (glitter_emitter*& i : emitters) - delete i; -} - -bool glitter_effect_parse_file(EffectGroup* a1, - f2_struct* st, std::vector* vec, object_database* obj_db) { - glitter_effect* effect; - - if (!st || !st->header.data_size) - return false; - - effect = new glitter_effect(a1->type); - effect->version = st->header.version; - if (!glitter_effect_unpack_file(a1->type, st->data.data(), - effect, st->header.use_big_endian, obj_db)) { - delete effect; - return false; - } - - for (f2_struct& i : st->sub_structs) { - if (!i.header.data_size) - continue; - - if (i.header.signature == reverse_endianness_uint32_t('ANIM')) - glitter_animation_parse_file(a1->type, &i, &effect->animation, glitter_effect_curve_flags); - else if (i.header.signature == reverse_endianness_uint32_t('EMIT')) - glitter_emitter_parse_file(a1, &i, &effect->emitters, effect); - } - vec->push_back(effect); - return true; -} - -static bool glitter_effect_pack_file(GLT, f2_struct* st, glitter_effect* a2) { - size_t l; - size_t d; - glitter_effect_ext_anim* ext_anim; - glitter_effect_file_flag flags; - - if (a2->version != 6 && a2->version != 7) - return false; - - ext_anim = a2->data.ext_anim; - l = 0; - - uint32_t o; - enrs e; - enrs_entry ee; - - ee = { 0, 2, 56, 1 }; - ee.append(0, 1, ENRS_QWORD); - ee.append(0, 12, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 56; - - if (a2->version == 7) { - ee = { 0, 1, 4, 1 }; - ee.append(0, 1, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 4; - } - - ee = { 0, 1, 4, 1 }; - ee.append(0, 1, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 4; - - if (~a2->data.flags & EFFECT_LOCAL && ext_anim) - if (ext_anim->flags & EFFECT_EXT_ANIM_CHARA_ANIM) { - ee = { 0, 1, 12, 1 }; - ee.append(0, 3, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 12; - } - else { - ee = { 0, 2, 140, 1 }; - ee.append(0, 1, ENRS_QWORD); - ee.append(0, 1, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 140; - } - - l = align_val(l, 0x10); - st->data.resize(l); - d = (size_t)st->data.data(); - st->enrs = e; - - flags = (glitter_effect_file_flag)0; - if (a2->data.flags & EFFECT_ALPHA) - enum_or(flags, EFFECT_FILE_ALPHA); - - if (a2->data.flags & EFFECT_FOG) - enum_or(flags, EFFECT_FILE_FOG); - else if (a2->data.flags & EFFECT_FOG_HEIGHT) - enum_or(flags, EFFECT_FILE_FOG_HEIGHT); - - if (a2->data.flags & EFFECT_EMISSION) - enum_or(flags, EFFECT_FILE_EMISSION); - - *(uint64_t*)d = GLT_VAL != Glitter::FT - ? hash_utf8_murmurhash(a2->name) - : hash_utf8_fnv1a64m(a2->name); - *(int32_t*)(d + 8) = a2->data.appear_time; - *(int32_t*)(d + 12) = a2->data.life_time; - *(int32_t*)(d + 16) = a2->data.start_time; - *(int32_t*)(d + 20) = 0xFFFFFFFF; - *(int32_t*)(d + 24) = a2->data.flags & EFFECT_LOOP ? 1 : 0; - *(vec3*)(d + 28) = a2->translation; - *(vec3*)(d + 40) = a2->rotation; - *(int32_t*)(d + 52) = flags; - d += 56; - - if (a2->version == 7) { - *(float_t*)d = a2->data.emission; - d += 4; - } - - if (a2->data.flags & EFFECT_LOCAL) { - *(int32_t*)d = 1; - d += 4; - } - else if (ext_anim) - if (ext_anim->flags & EFFECT_EXT_ANIM_CHARA_ANIM) { - *(int32_t*)d = 2; - d += 4; - glitter_effect_ext_anim_flag ext_anim_flag - = (glitter_effect_ext_anim_flag)(ext_anim->flags & ~EFFECT_EXT_ANIM_CHARA_ANIM); - *(int32_t*)d = ext_anim->chara_index; - *(int32_t*)(d + 4) = ext_anim_flag; - *(int32_t*)(d + 8) = ext_anim->node_index; - } - else { - *(int32_t*)d = 3; - d += 4; - *(uint64_t*)d = ext_anim->object_hash; - *(int32_t*)(d + 8) = ext_anim->flags; - memcpy((uint8_t*)(d + 12), ext_anim->mesh_name, 128); - } - else { - *(int32_t*)d = 0; - d += 4; - } - - st->header.signature = reverse_endianness_uint32_t('EFCT'); - st->header.length = 0x20; - st->header.use_big_endian = false; - st->header.use_section_size = true; - st->header.version = a2->version; - return true; -} -*/ \ No newline at end of file diff --git a/src/CRE/Glitter/effect_group.cpp b/src/CRE/Glitter/effect_group.cpp index 082a1814..ff0a38ef 100644 --- a/src/CRE/Glitter/effect_group.cpp +++ b/src/CRE/Glitter/effect_group.cpp @@ -23,7 +23,7 @@ namespace Glitter { if (resources) { for (texture** i = resources; *i; i++) texture_free(*i); - free(resources); + free_def(resources); resources = 0; } diff --git a/src/CRE/Glitter/effect_inst.cpp b/src/CRE/Glitter/effect_inst.cpp index 3a525f3e..6bf1af52 100644 --- a/src/CRE/Glitter/effect_inst.cpp +++ b/src/CRE/Glitter/effect_inst.cpp @@ -110,7 +110,7 @@ namespace Glitter { random_ptr = &GPM_VAL->random; ext_anim = 0; - if (~eff->data.flags & EFFECT_LOCAL && data.ext_anim) { + if (!(eff->data.flags & EFFECT_LOCAL) && data.ext_anim) { F2EffectInst::ExtAnim* inst_ext_anim = new F2EffectInst::ExtAnim; if (inst_ext_anim) { Effect::ExtAnim* ext_anim = data.ext_anim; @@ -240,7 +240,7 @@ namespace Glitter { } bool F2EffectInst::HasEnded(bool a2) { - if (~flags & EFFECT_INST_FREE) + if (!(flags & EFFECT_INST_FREE)) return false; else if (!a2) return true; @@ -256,7 +256,7 @@ namespace Glitter { frame1 = 0.0; flags = (EffectInstFlag)0; - if (~data.flags & EFFECT_LOCAL && data.ext_anim) { + if (!(data.flags & EFFECT_LOCAL) && data.ext_anim) { if (ext_anim) { Effect::ExtAnim* ext_anim = data.ext_anim; if (ext_anim->flags & EFFECT_EXT_ANIM_SET_ONCE) @@ -328,7 +328,7 @@ namespace Glitter { } void F2EffectInst::CtrlMat(GPM, GLT) { - if (~flags & EFFECT_INST_JUST_INIT) + if (!(flags & EFFECT_INST_JUST_INIT)) return; vec3 trans = translation; @@ -359,12 +359,10 @@ namespace Glitter { if (!ext_anim || !data.ext_anim) return; - if (~flags & EFFECT_INST_HAS_EXT_ANIM || (flags & EFFECT_INST_SET_EXT_ANIM_ONCE + if (!(flags & EFFECT_INST_HAS_EXT_ANIM) || (flags & EFFECT_INST_SET_EXT_ANIM_ONCE && flags & EFFECT_INST_HAS_EXT_ANIM_TRANS)) return; - mat4* obj_mat = 0; - mat4 temp; mat4 mat; int32_t chara_id; @@ -398,8 +396,69 @@ namespace Glitter { ext_anim->mat = mat; goto SetFlags; } + else if (flags & EFFECT_INST_GET_EXT_ANIM_MAT) { + mat4 temp; + mat4* obj_mat = 0; + if (ext_anim->a3da_id != -1) + obj_mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, + ext_anim->object_index, ext_anim->object_is_hrc, &temp); - if (~flags & EFFECT_INST_GET_EXT_ANIM_MAT) { + if (!obj_mat) { + ext_anim->a3da_id = auth_3d_data_get_auth_3d_id(ext_anim->object, + &ext_anim->object_index, &ext_anim->object_is_hrc); + if (ext_anim->a3da_id == -1) + return; + + ext_anim->mesh_index = -1; + obj_mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, + ext_anim->object_index, ext_anim->object_is_hrc, &temp); + if (!obj_mat) + return; + } + + mat = mat4_identity; + chara_id = auth_3d_data_get_chara_id(ext_anim->a3da_id); + if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) { + rob_chara* rob_chr = rob_chara_array_get(chara_id); + if (rob_chr) { + mat = rob_chr->data.adjust_data.mat; + + vec3 scale; + mat4_get_scale(&mat, &scale); + vec3_sub_scalar(scale, 1.0f, ext_anim_scale); + ext_anim_scale.z = 0.0f; + enum_or(flags, EFFECT_INST_HAS_EXT_ANIM_SCALE); + } + } + + if (ext_anim->mesh_name) { + if (ext_anim->mesh_index == -1) + ext_anim->mesh_index = object_storage_get_obj_mesh_index( + ext_anim->object, ext_anim->mesh_name); + + if (ext_anim->mesh_index != -1) { + obj_mesh* mesh = object_storage_get_obj_mesh_by_index( + ext_anim->object, ext_anim->mesh_index); + if (mesh) { + mat4_mult(obj_mat, &mat, &mat); + ext_anim->mat = mat; + ext_anim->translation = mesh->bounding_sphere.center; + goto SetFlags; + } + } + } + else { + mat4_mult(obj_mat, &mat, &mat); + if (flags & EFFECT_INST_EXT_ANIM_TRANS_ONLY) { + ext_anim->mat = mat4_identity; + mat4_get_translation(&mat, &ext_anim->translation); + } + else + ext_anim->mat = mat; + goto SetFlags; + } + } + else { if (ext_anim->mesh_index == -1) { if (!ext_anim->mesh_name) return; @@ -416,66 +475,6 @@ namespace Glitter { goto SetFlags; } } - return; - } - - if (ext_anim->a3da_id != -1) - obj_mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, - ext_anim->object_index, ext_anim->object_is_hrc, &temp); - - if (!obj_mat) { - ext_anim->a3da_id = auth_3d_data_get_auth_3d_id(ext_anim->object, - &ext_anim->object_index, &ext_anim->object_is_hrc, 0); - if (ext_anim->a3da_id == -1) - return; - - ext_anim->mesh_index = -1; - obj_mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, - ext_anim->object_index, ext_anim->object_is_hrc, &temp); - if (!obj_mat) - return; - } - - mat = mat4_identity; - chara_id = auth_3d_data_get_chara_id(ext_anim->a3da_id); - if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) { - rob_chara* rob_chr = rob_chara_array_get(chara_id); - if (rob_chr) { - mat = rob_chr->data.adjust_data.mat; - - vec3 scale; - mat4_get_scale(&mat, &scale); - vec3_sub_scalar(scale, 1.0f, ext_anim_scale); - ext_anim_scale.z = 0.0f; - enum_or(flags, EFFECT_INST_HAS_EXT_ANIM_SCALE); - } - } - - if (ext_anim->mesh_name) { - if (ext_anim->mesh_index == -1) - ext_anim->mesh_index = object_storage_get_obj_mesh_index( - ext_anim->object, ext_anim->mesh_name); - - if (ext_anim->mesh_index != -1) { - obj_mesh* mesh = object_storage_get_obj_mesh_by_index( - ext_anim->object, ext_anim->mesh_index); - if (mesh) { - mat4_mult(obj_mat, &mat, &mat); - ext_anim->mat = mat; - ext_anim->translation = mesh->bounding_sphere.center; - goto SetFlags; - } - } - } - else { - mat4_mult(obj_mat, &mat, &mat); - if (flags & EFFECT_INST_EXT_ANIM_TRANS_ONLY) { - ext_anim->mat = mat4_identity; - mat4_get_translation(&mat, &ext_anim->translation); - } - else - ext_anim->mat = mat; - goto SetFlags; } return; @@ -487,7 +486,7 @@ namespace Glitter { } bool F2EffectInst::GetExtAnimMat(mat4* mat) { - if (~flags & EFFECT_INST_HAS_EXT_ANIM_TRANS || !ext_anim) + if (!(flags & EFFECT_INST_HAS_EXT_ANIM_TRANS) || !ext_anim) return false; vec3 trans = ext_anim->translation; @@ -496,7 +495,7 @@ namespace Glitter { } void F2EffectInst::GetExtColor(float_t& r, float_t& g, float_t& b, float_t& a) { - if (~flags & EFFECT_INST_EXT_COLOR) + if (!(flags & EFFECT_INST_EXT_COLOR)) return; if (flags & EFFECT_INST_SET_EXT_COLOR) { @@ -623,7 +622,7 @@ namespace Glitter { random = GPM_VAL->CounterGet(); random_shared.value = random; - if (~eff->data.flags & EFFECT_LOCAL && data.ext_anim_x) { + if (!(eff->data.flags & EFFECT_LOCAL) && data.ext_anim_x) { XEffectInst::ExtAnim* inst_ext_anim = new XEffectInst::ExtAnim; if (inst_ext_anim) { Effect::ExtAnimX* ext_anim = data.ext_anim_x; @@ -777,7 +776,7 @@ namespace Glitter { } bool XEffectInst::HasEnded(bool a2) { - if (~flags & EFFECT_INST_FREE) + if (!(flags & EFFECT_INST_FREE)) return false; else if (!a2) return true; @@ -793,7 +792,7 @@ namespace Glitter { frame1 = 0.0; flags = (EffectInstFlag)0; - if (~data.flags & EFFECT_LOCAL && data.ext_anim_x) { + if (!(data.flags & EFFECT_LOCAL) && data.ext_anim_x) { if (ext_anim) { Effect::ExtAnimX* ext_anim = data.ext_anim_x; if (ext_anim->flags & EFFECT_EXT_ANIM_SET_ONCE) @@ -876,7 +875,7 @@ namespace Glitter { } void XEffectInst::CtrlMat(GPM) { - if (~flags & EFFECT_INST_JUST_INIT) + if (!(flags & EFFECT_INST_JUST_INIT)) return; vec3 trans = translation; @@ -911,7 +910,7 @@ namespace Glitter { if (!ext_anim || !data.ext_anim_x) return; - if (~flags & EFFECT_INST_HAS_EXT_ANIM || (flags & EFFECT_INST_SET_EXT_ANIM_ONCE + if (!(flags & EFFECT_INST_HAS_EXT_ANIM) || (flags & EFFECT_INST_SET_EXT_ANIM_ONCE && flags & EFFECT_INST_HAS_EXT_ANIM_TRANS)) return; @@ -925,10 +924,10 @@ namespace Glitter { if (!rob_chr) return; - mat4& mat = rob_chr->data.adjust_data.mat; + mat4* mat = &rob_chr->data.adjust_data.mat; vec3 scale; - mat4_get_scale(&mat, &scale); + mat4_get_scale(mat, &scale); vec3_sub_scalar(scale, 1.0f, ext_anim_scale); ext_anim_scale.z = 0.0f; enum_or(flags, EFFECT_INST_HAS_EXT_ANIM_SCALE); @@ -942,19 +941,19 @@ namespace Glitter { if (bone_index != -1) { mat4* bone_mat = rob_chr->get_bone_data_mat(bone_index); if (bone_mat) - SetExtAnim(&mat, bone_mat, 0, set_flags); + SetExtAnim(mat, bone_mat, 0, set_flags); } else - SetExtAnim(&mat, 0, 0, set_flags); + SetExtAnim(mat, 0, 0, set_flags); } else if (flags & EFFECT_INST_GET_EXT_ANIM_MAT) { mat4 temp; - mat4* mat = 0; + mat4* obj_mat = 0; if (ext_anim->a3da_id != -1) - mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, + obj_mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, ext_anim->object_index, ext_anim->object_is_hrc, &temp); - if (!mat) { + if (!obj_mat) { ext_anim->a3da_id = auth_3d_data_get_auth_3d_id( ext_anim->file_name_hash, ext_anim->object_hash, &ext_anim->object_index, &ext_anim->object_is_hrc, ext_anim->instance_id); @@ -962,18 +961,22 @@ namespace Glitter { return; ext_anim->mesh_index = -1; - mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, + obj_mat = auth_3d_data_get_auth_3d_object_mat(ext_anim->a3da_id, ext_anim->object_index, ext_anim->object_is_hrc, &temp); - if (!mat) + if (!obj_mat) return; } + const mat4* mat = &mat4_identity; + int32_t chara_id = auth_3d_data_get_chara_id(ext_anim->a3da_id); if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) { rob_chara* rob_chr = rob_chara_array_get(chara_id); if (rob_chr) { + mat = &rob_chr->data.adjust_data.mat; + vec3 scale; - mat4_get_scale(&rob_chr->data.adjust_data.mat, &scale); + mat4_get_scale(mat, &scale); vec3_sub_scalar(scale, 1.0f, ext_anim_scale); ext_anim_scale.z = 0.0f; enum_or(flags, EFFECT_INST_HAS_EXT_ANIM_SCALE); @@ -990,12 +993,12 @@ namespace Glitter { ext_anim->object_hash, ext_anim->mesh_index); if (mesh) { vec3* trans = &mesh->bounding_sphere.center; - SetExtAnim(mat, 0, trans, true); + SetExtAnim(mat, obj_mat, trans, true); } } } else - SetExtAnim(mat, 0, 0, true); + SetExtAnim(mat, obj_mat, 0, true); } else if (ext_anim->object_hash != hash_murmurhash_empty) { @@ -1019,7 +1022,7 @@ namespace Glitter { } bool XEffectInst::GetExtAnimMat(mat4* mat) { - if (~flags & EFFECT_INST_HAS_EXT_ANIM_TRANS || !ext_anim) + if (!(flags & EFFECT_INST_HAS_EXT_ANIM_TRANS) || !ext_anim) return false; vec3 trans = ext_anim->translation; @@ -1028,7 +1031,7 @@ namespace Glitter { } void XEffectInst::GetExtColor(float_t& r, float_t& g, float_t& b, float_t& a) { - if (~flags & EFFECT_INST_EXT_COLOR) + if (!(flags & EFFECT_INST_EXT_COLOR)) return; if (flags & EFFECT_INST_SET_EXT_COLOR) { @@ -1125,7 +1128,7 @@ namespace Glitter { } } - void XEffectInst::SetExtAnim(mat4* a2, mat4* a3, vec3* trans, bool set_flags) { + void XEffectInst::SetExtAnim(const mat4* a2, const mat4* a3, const vec3* trans, bool set_flags) { EffectInstFlag flags = this->flags; if (a2) { mat4 mat = *a2; diff --git a/src/CRE/Glitter/emitter.cpp b/src/CRE/Glitter/emitter.cpp index 7886cd21..81f8e5f3 100644 --- a/src/CRE/Glitter/emitter.cpp +++ b/src/CRE/Glitter/emitter.cpp @@ -40,148 +40,3 @@ namespace Glitter { delete i; } } - -/* -#include "emitter.hpp" -#include "animation.hpp" -#include "curve.hpp" -#include "particle.hpp" - -static bool glitter_emitter_pack_file(GLT, f2_struct* st, glitter_emitter* a2); - -bool glitter_emitter_unparse_file(GLT, EffectGroup* a1, - f2_struct* st, glitter_emitter* a3, glitter_effect* effect) { - if (!glitter_emitter_pack_file(GLT_VAL, st, a3)) - return false; - - f2_struct s; - if (glitter_animation_unparse_file(GLT_VAL, &s, &a3->animation, glitter_emitter_curve_flags)) - st->sub_structs.push_back(s); - - for (glitter_particle*& i : a3->particles) { - if (!i) - continue; - - f2_struct s; - if (glitter_particle_unparse_file(GLT_VAL, a1, &s, i, effect)) - st->sub_structs.push_back(s); - } - return true; -} - -static bool glitter_emitter_pack_file(GLT, f2_struct* st, glitter_emitter* a2) { - size_t l; - size_t d; - - if (a2->version != 1 && a2->version != 2) - return false; - - switch (a2->data.type) { - case EMITTER_BOX: - case EMITTER_CYLINDER: - case EMITTER_SPHERE: - case EMITTER_POLYGON: - break; - default: - return false; - } - - l = 0; - - uint32_t o; - enrs e; - enrs_entry ee; - - ee = { 0, 5, 96, 1 }; - ee.append(0, 5, ENRS_DWORD); - ee.append(0, 2, ENRS_WORD); - ee.append(0, 2, ENRS_DWORD); - ee.append(0, 2, ENRS_WORD); - ee.append(0, 15, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 96; - - switch (a2->data.type) { - case EMITTER_BOX: - ee = { o, 1, 12, 1 }; - ee.append(0, 3, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 12; - break; - case EMITTER_CYLINDER: - ee = { o, 1, 20, 1 }; - ee.append(0, 5, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 20; - break; - case EMITTER_SPHERE: - ee = { o, 1, 16, 1 }; - ee.append(0, 4, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 16; - break; - case EMITTER_POLYGON: - ee = { o, 1, 8, 1 }; - ee.append(0, 2, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 8; - break; - } - - l = align_val(l, 0x10); - st->data.resize(l); - d = (size_t)st->data.data(); - st->enrs = e; - - *(int32_t*)d = a2->data.start_time; - *(int32_t*)(d + 4) = a2->data.life_time; - *(int32_t*)(d + 8) = a2->data.loop_start_time; - *(int32_t*)(d + 12) = a2->data.loop_end_time; - *(int32_t*)(d + 16) = a2->data.flags; - *(int16_t*)(d + 20) = (int16_t)a2->data.type; - *(int16_t*)(d + 22) = (int16_t)a2->data.direction; - *(float_t*)(d + 24) = a2->data.emission_interval; - *(float_t*)(d + 28) = a2->data.particles_per_emission; - *(int16_t*)(d + 32) = 0; - *(int16_t*)(d + 34) = 0; - - *(vec3*)(d + 36) = a2->translation; - *(vec3*)(d + 48) = a2->rotation; - *(vec3*)(d + 60) = a2->scale; - *(vec3*)(d + 72) = a2->data.rotation_add; - *(vec3*)(d + 84) = a2->data.rotation_add_random; - d += 96; - - switch (a2->data.type) { - case EMITTER_BOX: - *(vec3*)d = a2->data.box.size; - break; - case EMITTER_CYLINDER: - *(float_t*)d = a2->data.cylinder.radius; - *(float_t*)(d + 4) = a2->data.cylinder.height; - *(float_t*)(d + 8) = a2->data.cylinder.start_angle; - *(float_t*)(d + 12) = a2->data.cylinder.end_angle; - *(int32_t*)(d + 16) = ((int32_t)a2->data.cylinder.direction << 1) - | (a2->data.cylinder.on_edge ? 1 : 0); - break; - case EMITTER_SPHERE: - *(float_t*)d = a2->data.sphere.radius; - *(float_t*)(d + 4) = a2->data.sphere.latitude; - *(float_t*)(d + 8) = a2->data.sphere.longitude; - *(int32_t*)(d + 12) = ((int32_t)a2->data.sphere.direction << 1) - | (a2->data.sphere.on_edge ? 1 : 0); - break; - case EMITTER_POLYGON: - *(float_t*)d = a2->data.polygon.size; - *(int32_t*)(d + 4) = a2->data.polygon.count; - break; - } - - st->header.signature = reverse_endianness_uint32_t('EMIT'); - st->header.length = 0x20; - st->header.use_big_endian = false; - st->header.use_section_size = true; - st->header.version = a2->version; - return true; -} -*/ \ No newline at end of file diff --git a/src/CRE/Glitter/file_reader.cpp b/src/CRE/Glitter/file_reader.cpp index 9c585b2b..1ed51067 100644 --- a/src/CRE/Glitter/file_reader.cpp +++ b/src/CRE/Glitter/file_reader.cpp @@ -42,8 +42,8 @@ namespace Glitter { this->hash = GLT_VAL != Glitter::FT ? hash_utf8_murmurhash(file_temp) : hash_utf8_fnv1a64m(file_temp); - free(path_temp); - free(file_temp); + free_def(path_temp); + free_def(file_temp); } FileReader::~FileReader() { @@ -760,10 +760,10 @@ namespace Glitter { } if (!texture_txp_set_load(&eff_group->resources_tex, &eff_group->resources, ids)) { - free(ids); + free_def(ids); return false; } - free(ids); + free_def(ids); for (Effect*& i : eff_group->effects) { if (!i) @@ -1853,9 +1853,9 @@ namespace Glitter { ptcl->data.split_u = split_u; ptcl->data.split_v = split_v; ptcl->data.uv_index_type = uv_index_type; - ptcl->data.uv_index = max(uv_index, 0); + ptcl->data.uv_index = max_def(uv_index, 0); ptcl->data.frame_step_uv = frame_step_uv; - ptcl->data.uv_index_start = max(uv_index_start, 0); + ptcl->data.uv_index_start = max_def(uv_index_start, 0); ptcl->data.uv_index_end = uv_index_end; ptcl->data.split_uv.x = (float_t)split_u; ptcl->data.split_uv.y = (float_t)split_v; @@ -1885,7 +1885,7 @@ namespace Glitter { else if (uv_index_end >= 0 && uv_index > uv_index_end) ptcl->data.uv_index = uv_index_end; - ptcl->data.uv_index = min(ptcl->data.uv_index, uv_max_count); + ptcl->data.uv_index = min_def(ptcl->data.uv_index, uv_max_count); break; } diff --git a/src/CRE/Glitter/file_writer.cpp b/src/CRE/Glitter/file_writer.cpp index b6d2bc2f..a0848e59 100644 --- a/src/CRE/Glitter/file_writer.cpp +++ b/src/CRE/Glitter/file_writer.cpp @@ -4,6 +4,7 @@ */ #include "glitter.hpp" +#include "../../KKdLib/io/file_stream.hpp" #include "../../KKdLib/io/path.hpp" #include "../../KKdLib/interpolation.hpp" #include "../../KKdLib/farc.hpp" @@ -15,7 +16,7 @@ namespace Glitter { } - void FileWriter::PackCurve(f2_struct* st, Curve* c) { + void FileWriter::PackCurve(f2_struct* st, Curve* c, bool big_endian) { if (!c->keys.size()) { st->header.signature = reverse_endianness_uint32_t('KEYS'); st->header.length = 0x20; @@ -144,83 +145,153 @@ namespace Glitter { st->data.resize(l); size_t d = (size_t)st->data.data(); - if (scale == 1.0f) - if (c->flags & CURVE_KEY_RANDOM_RANGE) - for (Curve::Key& i : c->keys) { - *(int16_t*)d = (int16_t)i.type; - *(int16_t*)(d + 2) = (int16_t)i.frame; - if (i.type == KEY_HERMITE) { - *(float_t*)(d + 4) = i.tangent1; - *(float_t*)(d + 8) = i.tangent2; - *(float_t*)(d + 12) = i.random_range; - *(float_t*)(d + 16) = i.value; - d += 20; + if (scale == 1.0f) { + if (big_endian) + if (c->flags & CURVE_KEY_RANDOM_RANGE) + for (Curve::Key& i : c->keys) { + store_reverse_endianness_int16_t((int16_t*)d, (int16_t)i.type); + store_reverse_endianness_int16_t((int16_t*)(d + 2), (int16_t)i.frame); + if (i.type == KEY_HERMITE) { + store_reverse_endianness_float_t((float_t*)(d + 4), i.tangent1); + store_reverse_endianness_float_t((float_t*)(d + 8), i.tangent2); + store_reverse_endianness_float_t((float_t*)(d + 12), i.random_range); + store_reverse_endianness_float_t((float_t*)(d + 16), i.value); + d += 20; + } + else { + store_reverse_endianness_float_t((float_t*)(d + 4), i.random_range); + store_reverse_endianness_float_t((float_t*)(d + 8), i.value); + d += 12; + } } - else { - *(float_t*)(d + 4) = i.random_range; - *(float_t*)(d + 8) = i.value; - d += 12; + else + for (Curve::Key& i : c->keys) { + store_reverse_endianness_int16_t((int16_t*)d, (int16_t)i.type); + store_reverse_endianness_int16_t((int16_t*)(d + 2), (int16_t)i.frame); + if (i.type == KEY_HERMITE) { + store_reverse_endianness_float_t((float_t*)(d + 4), i.tangent1); + store_reverse_endianness_float_t((float_t*)(d + 8), i.tangent2); + store_reverse_endianness_float_t((float_t*)(d + 12), i.value); + d += 16; + } + else { + store_reverse_endianness_float_t((float_t*)(d + 4), i.value); + d += 8; + } } - } else - for (Curve::Key& i : c->keys) { - *(int16_t*)d = (int16_t)i.type; - *(int16_t*)(d + 2) = (int16_t)i.frame; - if (i.type == KEY_HERMITE) { - *(float_t*)(d + 4) = i.tangent1; - *(float_t*)(d + 8) = i.tangent2; - *(float_t*)(d + 12) = i.value; - d += 16; + if (c->flags & CURVE_KEY_RANDOM_RANGE) + for (Curve::Key& i : c->keys) { + *(int16_t*)d = (int16_t)i.type; + *(int16_t*)(d + 2) = (int16_t)i.frame; + if (i.type == KEY_HERMITE) { + *(float_t*)(d + 4) = i.tangent1; + *(float_t*)(d + 8) = i.tangent2; + *(float_t*)(d + 12) = i.random_range; + *(float_t*)(d + 16) = i.value; + d += 20; + } + else { + *(float_t*)(d + 4) = i.random_range; + *(float_t*)(d + 8) = i.value; + d += 12; + } } - else { - *(float_t*)(d + 4) = i.value; - d += 8; + else + for (Curve::Key& i : c->keys) { + *(int16_t*)d = (int16_t)i.type; + *(int16_t*)(d + 2) = (int16_t)i.frame; + if (i.type == KEY_HERMITE) { + *(float_t*)(d + 4) = i.tangent1; + *(float_t*)(d + 8) = i.tangent2; + *(float_t*)(d + 12) = i.value; + d += 16; + } + else { + *(float_t*)(d + 4) = i.value; + d += 8; + } } - } - else - if (c->flags & CURVE_KEY_RANDOM_RANGE) - for (Curve::Key& i : c->keys) { - *(int16_t*)d = (int16_t)i.type; - *(int16_t*)(d + 2) = (int16_t)i.frame; - if (i.type == KEY_HERMITE) { - *(float_t*)(d + 4) = i.tangent1 * scale; - *(float_t*)(d + 8) = i.tangent2 * scale; - *(float_t*)(d + 12) = i.random_range * scale; - *(float_t*)(d + 16) = i.value * scale; - d += 20; + } + else { + if (big_endian) + if (c->flags & CURVE_KEY_RANDOM_RANGE) + for (Curve::Key& i : c->keys) { + store_reverse_endianness_int16_t((int16_t*)d, (int16_t)i.type); + store_reverse_endianness_int16_t((int16_t*)(d + 2), (int16_t)i.frame); + if (i.type == KEY_HERMITE) { + store_reverse_endianness_float_t((float_t*)(d + 4), i.tangent1 * scale); + store_reverse_endianness_float_t((float_t*)(d + 8), i.tangent2 * scale); + store_reverse_endianness_float_t((float_t*)(d + 12), i.random_range * scale); + store_reverse_endianness_float_t((float_t*)(d + 16), i.value * scale); + d += 20; + } + else { + store_reverse_endianness_float_t((float_t*)(d + 4), i.random_range * scale); + store_reverse_endianness_float_t((float_t*)(d + 8), i.value * scale); + d += 12; + } } - else { - *(float_t*)(d + 4) = i.random_range * scale; - *(float_t*)(d + 8) = i.value * scale; - d += 12; + else + for (Curve::Key& i : c->keys) { + store_reverse_endianness_int16_t((int16_t*)d, (int16_t)i.type); + store_reverse_endianness_int16_t((int16_t*)(d + 2), (int16_t)i.frame); + if (i.type == KEY_HERMITE) { + store_reverse_endianness_float_t((float_t*)(d + 4), i.tangent1 * scale); + store_reverse_endianness_float_t((float_t*)(d + 8), i.tangent2 * scale); + store_reverse_endianness_float_t((float_t*)(d + 12), i.value * scale); + d += 16; + } + else { + store_reverse_endianness_float_t((float_t*)(d + 4), i.value * scale); + d += 8; + } } - } else - for (Curve::Key& i : c->keys) { - *(int16_t*)d = (int16_t)i.type; - *(int16_t*)(d + 2) = (int16_t)i.frame; - if (i.type == KEY_HERMITE) { - *(float_t*)(d + 4) = i.tangent1 * scale; - *(float_t*)(d + 8) = i.tangent2 * scale; - *(float_t*)(d + 12) = i.value * scale; - d += 16; + if (c->flags & CURVE_KEY_RANDOM_RANGE) + for (Curve::Key& i : c->keys) { + *(int16_t*)d = (int16_t)i.type; + *(int16_t*)(d + 2) = (int16_t)i.frame; + if (i.type == KEY_HERMITE) { + *(float_t*)(d + 4) = i.tangent1 * scale; + *(float_t*)(d + 8) = i.tangent2 * scale; + *(float_t*)(d + 12) = i.random_range * scale; + *(float_t*)(d + 16) = i.value * scale; + d += 20; + } + else { + *(float_t*)(d + 4) = i.random_range * scale; + *(float_t*)(d + 8) = i.value * scale; + d += 12; + } } - else { - *(float_t*)(d + 4) = i.value * scale; - d += 8; + else + for (Curve::Key& i : c->keys) { + *(int16_t*)d = (int16_t)i.type; + *(int16_t*)(d + 2) = (int16_t)i.frame; + if (i.type == KEY_HERMITE) { + *(float_t*)(d + 4) = i.tangent1 * scale; + *(float_t*)(d + 8) = i.tangent2 * scale; + *(float_t*)(d + 12) = i.value * scale; + d += 16; + } + else { + *(float_t*)(d + 4) = i.value * scale; + d += 8; + } } - } + } st->enrs = e; st->header.signature = reverse_endianness_uint32_t('KEYS'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; st->header.version = c->keys_version; } - bool FileWriter::PackDivaList(EffectGroup* eff_group, f2_struct* st) { + bool FileWriter::PackDivaList(EffectGroup* eff_group, f2_struct* st, bool big_endian) { if (!eff_group->effects.size()) return false; @@ -239,12 +310,15 @@ namespace Glitter { st->data.resize(0x10 + 0x80 * length); size_t d = (size_t)st->data.data(); - *(uint32_t*)d = (uint32_t)length; + if (big_endian) + store_reverse_endianness_uint32_t((uint32_t*)d, (uint32_t)length); + else + *(uint32_t*)d = (uint32_t)length; d += 4; for (Effect*& i : eff_group->effects) if (i) { - size_t size = min(i->name.size(), 0x7F); + size_t size = min_def(i->name.size(), 0x7F); memcpy((void*)d, i->name.c_str(), size); memset((void*)(d + size), 0, 0x80 - size); d += 0x80; @@ -254,7 +328,7 @@ namespace Glitter { st->header.signature = reverse_endianness_uint32_t('GEFF'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; return true; } @@ -275,7 +349,7 @@ namespace Glitter { return true; } - bool FileWriter::PackDivaResourceHashes(EffectGroup* eff_group, f2_struct* st) { + bool FileWriter::PackDivaResourceHashes(EffectGroup* eff_group, f2_struct* st, bool big_endian) { if (eff_group->effects.size() < 1 || !eff_group->resources_count || eff_group->resource_hashes.size() < 1) return false; @@ -297,22 +371,32 @@ namespace Glitter { st->data.resize(l); size_t d = (size_t)st->data.data(); - *(int32_t*)d = (int32_t)count; + if (big_endian) + store_reverse_endianness_int32_t((int32_t*)d, (int32_t)count); + else + *(int32_t*)d = (int32_t)count; *(int32_t*)(d + 4) = 0; d += 8; - memcpy((void*)d, eff_group->resource_hashes.data(), sizeof(uint64_t) * count); + if (big_endian) { + uint64_t* hashes_src = eff_group->resource_hashes.data(); + uint64_t* hashes_dst = (uint64_t*)(void*)d; + for (size_t i = 0; i < count; i++) + store_reverse_endianness_uint64_t(hashes_dst++, *hashes_src++); + } + else + memcpy((void*)d, eff_group->resource_hashes.data(), sizeof(uint64_t) * count); st->enrs = e; st->header.signature = reverse_endianness_uint32_t('DVRS'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; return true; } - bool FileWriter::PackEffect(f2_struct* st, Effect* eff) { + bool FileWriter::PackEffect(f2_struct* st, Effect* eff, bool big_endian) { if (eff->version != 6 && eff->version != 7) return false; @@ -373,45 +457,88 @@ namespace Glitter { if (eff->data.flags & EFFECT_EMISSION) enum_or(flags, EFFECT_FILE_EMISSION); - *(uint64_t*)d = type != Glitter::FT - ? hash_string_murmurhash(eff->name) : hash_string_fnv1a64m(eff->name); - *(int32_t*)(d + 8) = eff->data.appear_time; - *(int32_t*)(d + 12) = eff->data.life_time; - *(int32_t*)(d + 16) = eff->data.start_time; - *(int32_t*)(d + 20) = 0xFFFFFFFF; - *(int32_t*)(d + 24) = eff->data.flags & EFFECT_LOOP ? 1 : 0; - *(vec3*)(d + 28) = eff->translation; - *(vec3*)(d + 40) = eff->rotation; - *(int32_t*)(d + 52) = flags; + if (big_endian) { + store_reverse_endianness_uint64_t((uint64_t*)d, type != Glitter::FT + ? hash_string_murmurhash(eff->name) : hash_string_fnv1a64m(eff->name)); + store_reverse_endianness_int32_t((int32_t*)(d + 8), eff->data.appear_time); + store_reverse_endianness_int32_t((int32_t*)(d + 12), eff->data.life_time); + store_reverse_endianness_int32_t((int32_t*)(d + 16), eff->data.start_time); + store_reverse_endianness_int32_t((int32_t*)(d + 20), 0xFFFFFFFF); + store_reverse_endianness_int32_t((int32_t*)(d + 24), eff->data.flags & EFFECT_LOOP ? 1 : 0); + store_reverse_endianness_float_t((float_t*)(d + 28), eff->translation.x); + store_reverse_endianness_float_t((float_t*)(d + 32), eff->translation.y); + store_reverse_endianness_float_t((float_t*)(d + 36), eff->translation.z); + store_reverse_endianness_float_t((float_t*)(d + 40), eff->rotation.x); + store_reverse_endianness_float_t((float_t*)(d + 40), eff->rotation.y); + store_reverse_endianness_float_t((float_t*)(d + 40), eff->rotation.z); + store_reverse_endianness_int32_t((int32_t*)(d + 52), flags); + } + else { + *(uint64_t*)d = type != Glitter::FT + ? hash_string_murmurhash(eff->name) : hash_string_fnv1a64m(eff->name); + *(int32_t*)(d + 8) = eff->data.appear_time; + *(int32_t*)(d + 12) = eff->data.life_time; + *(int32_t*)(d + 16) = eff->data.start_time; + *(int32_t*)(d + 20) = 0xFFFFFFFF; + *(int32_t*)(d + 24) = eff->data.flags & EFFECT_LOOP ? 1 : 0; + *(vec3*)(d + 28) = eff->translation; + *(vec3*)(d + 40) = eff->rotation; + *(int32_t*)(d + 52) = flags; + } d += 56; if (eff->version == 7) { - *(float_t*)d = eff->data.emission; + if (big_endian) + store_reverse_endianness_float_t((float_t*)d, eff->data.emission); + else + *(float_t*)d = eff->data.emission; d += 4; } if (eff->data.flags & EFFECT_LOCAL) { - *(int32_t*)d = 1; + if (big_endian) + store_reverse_endianness_int32_t((int32_t*)d, 1); + else + *(int32_t*)d = 1; d += 4; } else if (ext_anim) { if (ext_anim->flags & EFFECT_EXT_ANIM_CHARA_ANIM) { - *(int32_t*)d = 2; + if (big_endian) + store_reverse_endianness_int32_t((int32_t*)d, 2); + else + *(int32_t*)d = 2; d += 4; EffectExtAnimFlag ext_anim_flag = ext_anim->flags; enum_and(ext_anim_flag, ~EFFECT_EXT_ANIM_CHARA_ANIM); - *(int32_t*)d = ext_anim->chara_index; - *(int32_t*)(d + 4) = ext_anim_flag; - *(int32_t*)(d + 8) = ext_anim->node_index; + if (big_endian) { + store_reverse_endianness_int32_t((int32_t*)d, ext_anim->chara_index); + store_reverse_endianness_int32_t((int32_t*)(d + 4), ext_anim_flag); + store_reverse_endianness_int32_t((int32_t*)(d + 8), ext_anim->node_index); + } + else { + *(int32_t*)d = ext_anim->chara_index; + *(int32_t*)(d + 4) = ext_anim_flag; + *(int32_t*)(d + 8) = ext_anim->node_index; + } } else { - *(int32_t*)d = 3; + if (big_endian) + store_reverse_endianness_int32_t((int32_t*)d, 3); + else + *(int32_t*)d = 3; d += 4; - *(uint64_t*)d = ext_anim->object_hash; - *(int32_t*)(d + 8) = ext_anim->flags; + if (big_endian) { + store_reverse_endianness_uint64_t((uint64_t*)d, ext_anim->object_hash); + store_reverse_endianness_int32_t((int32_t*)(d + 8), ext_anim->flags); + } + else { + *(uint64_t*)d = ext_anim->object_hash; + *(int32_t*)(d + 8) = ext_anim->flags; + } strncpy_s((char*)(d + 12), 0x80, ext_anim->mesh_name, 0x80); ((char*)(d + 12))[0x7F] = '\0'; } @@ -425,13 +552,13 @@ namespace Glitter { st->header.signature = reverse_endianness_uint32_t('EFCT'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; st->header.version = eff->version; return true; } - bool FileWriter::PackEmitter(f2_struct* st, Emitter* emit) { + bool FileWriter::PackEmitter(f2_struct* st, Emitter* emit, bool big_endian) { if (emit->version != 1 && emit->version != 2) return false; @@ -491,47 +618,109 @@ namespace Glitter { st->data.resize(l); size_t d = (size_t)st->data.data(); - *(int32_t*)d = emit->data.start_time; - *(int32_t*)(d + 4) = emit->data.life_time; - *(int32_t*)(d + 8) = emit->data.loop_start_time; - *(int32_t*)(d + 12) = emit->data.loop_end_time; - *(int32_t*)(d + 16) = emit->data.flags; - *(int16_t*)(d + 20) = (int16_t)emit->data.type; - *(int16_t*)(d + 22) = (int16_t)emit->data.direction; - *(float_t*)(d + 24) = emit->data.emission_interval; - *(float_t*)(d + 28) = emit->data.particles_per_emission; - *(int16_t*)(d + 32) = 0; - *(int16_t*)(d + 34) = 0; + if (big_endian) { + store_reverse_endianness_int32_t((int32_t*)d, emit->data.start_time); + store_reverse_endianness_int32_t((int32_t*)(d + 4), emit->data.life_time); + store_reverse_endianness_int32_t((int32_t*)(d + 8), emit->data.loop_start_time); + store_reverse_endianness_int32_t((int32_t*)(d + 12), emit->data.loop_end_time); + store_reverse_endianness_int32_t((int32_t*)(d + 16), emit->data.flags); + store_reverse_endianness_int32_t((int16_t*)(d + 20), (int16_t)emit->data.type); + store_reverse_endianness_int32_t((int16_t*)(d + 22), (int16_t)emit->data.direction); + store_reverse_endianness_float_t((float_t*)(d + 24), emit->data.emission_interval); + store_reverse_endianness_float_t((float_t*)(d + 28), emit->data.particles_per_emission); + store_reverse_endianness_int16_t((int16_t*)(d + 32), (uint16_t)0); + store_reverse_endianness_int16_t((int16_t*)(d + 34), (uint16_t)0); - *(vec3*)(d + 36) = emit->translation; - *(vec3*)(d + 48) = emit->rotation; - *(vec3*)(d + 60) = emit->scale; - *(vec3*)(d + 72) = emit->data.rotation_add; - *(vec3*)(d + 84) = emit->data.rotation_add_random; + store_reverse_endianness_float_t((float_t*)(d + 36), emit->translation.x); + store_reverse_endianness_float_t((float_t*)(d + 40), emit->translation.y); + store_reverse_endianness_float_t((float_t*)(d + 44), emit->translation.z); + store_reverse_endianness_float_t((float_t*)(d + 48), emit->rotation.x); + store_reverse_endianness_float_t((float_t*)(d + 52), emit->rotation.y); + store_reverse_endianness_float_t((float_t*)(d + 56), emit->rotation.z); + store_reverse_endianness_float_t((float_t*)(d + 60), emit->scale.x); + store_reverse_endianness_float_t((float_t*)(d + 64), emit->scale.y); + store_reverse_endianness_float_t((float_t*)(d + 68), emit->scale.z); + store_reverse_endianness_float_t((float_t*)(d + 72), emit->data.rotation_add.x); + store_reverse_endianness_float_t((float_t*)(d + 76), emit->data.rotation_add.y); + store_reverse_endianness_float_t((float_t*)(d + 80), emit->data.rotation_add.z); + store_reverse_endianness_float_t((float_t*)(d + 84), emit->data.rotation_add_random.x); + store_reverse_endianness_float_t((float_t*)(d + 88), emit->data.rotation_add_random.y); + store_reverse_endianness_float_t((float_t*)(d + 92), emit->data.rotation_add_random.z); + } + else { + *(int32_t*)d = emit->data.start_time; + *(int32_t*)(d + 4) = emit->data.life_time; + *(int32_t*)(d + 8) = emit->data.loop_start_time; + *(int32_t*)(d + 12) = emit->data.loop_end_time; + *(int32_t*)(d + 16) = emit->data.flags; + *(int16_t*)(d + 20) = (int16_t)emit->data.type; + *(int16_t*)(d + 22) = (int16_t)emit->data.direction; + *(float_t*)(d + 24) = emit->data.emission_interval; + *(float_t*)(d + 28) = emit->data.particles_per_emission; + *(int16_t*)(d + 32) = 0; + *(int16_t*)(d + 34) = 0; + + *(vec3*)(d + 36) = emit->translation; + *(vec3*)(d + 48) = emit->rotation; + *(vec3*)(d + 60) = emit->scale; + *(vec3*)(d + 72) = emit->data.rotation_add; + *(vec3*)(d + 84) = emit->data.rotation_add_random; + } d += 96; switch (emit->data.type) { case EMITTER_BOX: - *(vec3*)d = emit->data.box.size; + if (big_endian) { + store_reverse_endianness_float_t((float_t*)d, emit->data.box.size.x); + store_reverse_endianness_float_t((float_t*)(d + 4), emit->data.box.size.y); + store_reverse_endianness_float_t((float_t*)(d + 8), emit->data.box.size.z); + } + else + *(vec3*)d = emit->data.box.size; break; case EMITTER_CYLINDER: - *(float_t*)d = emit->data.cylinder.radius; - *(float_t*)(d + 4) = emit->data.cylinder.height; - *(float_t*)(d + 8) = emit->data.cylinder.start_angle; - *(float_t*)(d + 12) = emit->data.cylinder.end_angle; - *(int32_t*)(d + 16) = ((int32_t)emit->data.cylinder.direction << 1) - | (emit->data.cylinder.on_edge ? 1 : 0); + if (big_endian) { + store_reverse_endianness_float_t((float_t*)d, emit->data.cylinder.radius); + store_reverse_endianness_float_t((float_t*)(d + 4), emit->data.cylinder.height); + store_reverse_endianness_float_t((float_t*)(d + 8), emit->data.cylinder.start_angle); + store_reverse_endianness_float_t((float_t*)(d + 12), emit->data.cylinder.end_angle); + store_reverse_endianness_int32_t((int32_t*)(d + 16), ((int32_t)emit->data.cylinder.direction << 1) + | (emit->data.cylinder.on_edge ? 1 : 0)); + } + else { + *(float_t*)d = emit->data.cylinder.radius; + *(float_t*)(d + 4) = emit->data.cylinder.height; + *(float_t*)(d + 8) = emit->data.cylinder.start_angle; + *(float_t*)(d + 12) = emit->data.cylinder.end_angle; + *(int32_t*)(d + 16) = ((int32_t)emit->data.cylinder.direction << 1) + | (emit->data.cylinder.on_edge ? 1 : 0); + } break; case EMITTER_SPHERE: - *(float_t*)d = emit->data.sphere.radius; - *(float_t*)(d + 4) = emit->data.sphere.latitude; - *(float_t*)(d + 8) = emit->data.sphere.longitude; - *(int32_t*)(d + 12) = ((int32_t)emit->data.sphere.direction << 1) - | (emit->data.sphere.on_edge ? 1 : 0); + if (big_endian) { + store_reverse_endianness_float_t((float_t*)d, emit->data.sphere.radius); + store_reverse_endianness_float_t((float_t*)(d + 4), emit->data.sphere.latitude); + store_reverse_endianness_float_t((float_t*)(d + 8), emit->data.sphere.longitude); + store_reverse_endianness_int32_t((int32_t*)(d + 12), ((int32_t)emit->data.sphere.direction << 1) + | (emit->data.sphere.on_edge ? 1 : 0)); + } + else { + *(float_t*)d = emit->data.sphere.radius; + *(float_t*)(d + 4) = emit->data.sphere.latitude; + *(float_t*)(d + 8) = emit->data.sphere.longitude; + *(int32_t*)(d + 12) = ((int32_t)emit->data.sphere.direction << 1) + | (emit->data.sphere.on_edge ? 1 : 0); + } break; case EMITTER_POLYGON: - *(float_t*)d = emit->data.polygon.size; - *(int32_t*)(d + 4) = emit->data.polygon.count; + if (big_endian) { + store_reverse_endianness_float_t((float_t*)d, emit->data.polygon.size); + store_reverse_endianness_int32_t((int32_t*)(d + 4), emit->data.polygon.count); + } + else { + *(float_t*)d = emit->data.polygon.size; + *(int32_t*)(d + 4) = emit->data.polygon.count; + } break; } @@ -539,13 +728,14 @@ namespace Glitter { st->header.signature = reverse_endianness_uint32_t('EMIT'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; st->header.version = emit->version; return true; } - bool FileWriter::PackParticle(EffectGroup* eff_group, f2_struct* st, Particle* ptcl, Effect* eff) { + bool FileWriter::PackParticle(EffectGroup* eff_group, + f2_struct* st, Particle* ptcl, Effect* eff, bool big_endian) { if (ptcl->version < 2) return false; @@ -615,72 +805,164 @@ namespace Glitter { else type = ptcl->data.type; - *(int32_t*)d = ptcl->data.life_time; - *(int32_t*)(d + 4) = type; - *(int32_t*)(d + 8) = ptcl->data.draw_type; - *(vec3*)(d + 12) = ptcl->data.rotation; - *(vec3*)(d + 24) = ptcl->data.rotation_random; - *(vec3*)(d + 36) = ptcl->data.rotation_add; - *(vec3*)(d + 48) = ptcl->data.rotation_add_random; - *(vec3*)(d + 60) = ptcl->data.scale; - *(vec3*)(d + 72) = ptcl->data.scale_random; - *(float_t*)(d + 84) = ptcl->data.z_offset; - *(int32_t*)(d + 88) = ptcl->data.pivot; - *(int32_t*)(d + 92) = flags; - *(float_t*)(d + 96) = ptcl->data.speed; - *(float_t*)(d + 100) = ptcl->data.speed_random; - *(float_t*)(d + 104) = ptcl->data.deceleration; - *(float_t*)(d + 108) = ptcl->data.deceleration_random; - *(vec3*)(d + 112) = ptcl->data.direction; - *(vec3*)(d + 124) = ptcl->data.direction_random; - *(vec3*)(d + 136) = ptcl->data.gravity; - *(vec3*)(d + 148) = ptcl->data.acceleration; - *(vec3*)(d + 160) = ptcl->data.acceleration_random; - *(float_t*)(d + 172) = ptcl->data.reflection_coeff; - *(float_t*)(d + 176) = ptcl->data.reflection_coeff_random; - *(float_t*)(d + 180) = ptcl->data.rebound_plane_y; - *(vec2*)(d + 184) = ptcl->data.uv_scroll_add; - *(float_t*)(d + 192) = ptcl->data.uv_scroll_add_scale; - *(int32_t*)(d + 196) = ptcl->data.sub_flags; - *(int32_t*)(d + 200) = ptcl->data.count; + if (big_endian) { + store_reverse_endianness_int32_t((int32_t*)d, ptcl->data.life_time); + store_reverse_endianness_int32_t((int32_t*)(d + 4), type); + store_reverse_endianness_int32_t((int32_t*)(d + 8), ptcl->data.draw_type); + store_reverse_endianness_float_t((float_t*)(d + 12), ptcl->data.rotation.x); + store_reverse_endianness_float_t((float_t*)(d + 16), ptcl->data.rotation.y); + store_reverse_endianness_float_t((float_t*)(d + 20), ptcl->data.rotation.z); + store_reverse_endianness_float_t((float_t*)(d + 24), ptcl->data.rotation_random.x); + store_reverse_endianness_float_t((float_t*)(d + 28), ptcl->data.rotation_random.y); + store_reverse_endianness_float_t((float_t*)(d + 32), ptcl->data.rotation_random.z); + store_reverse_endianness_float_t((float_t*)(d + 36), ptcl->data.rotation_add.x); + store_reverse_endianness_float_t((float_t*)(d + 40), ptcl->data.rotation_add.y); + store_reverse_endianness_float_t((float_t*)(d + 44), ptcl->data.rotation_add.z); + store_reverse_endianness_float_t((float_t*)(d + 48), ptcl->data.rotation_add_random.x); + store_reverse_endianness_float_t((float_t*)(d + 52), ptcl->data.rotation_add_random.y); + store_reverse_endianness_float_t((float_t*)(d + 56), ptcl->data.rotation_add_random.z); + store_reverse_endianness_float_t((float_t*)(d + 60), ptcl->data.scale.x); + store_reverse_endianness_float_t((float_t*)(d + 64), ptcl->data.scale.y); + store_reverse_endianness_float_t((float_t*)(d + 68), ptcl->data.scale.z); + store_reverse_endianness_float_t((float_t*)(d + 72), ptcl->data.scale_random.x); + store_reverse_endianness_float_t((float_t*)(d + 76), ptcl->data.scale_random.y); + store_reverse_endianness_float_t((float_t*)(d + 80), ptcl->data.scale_random.z); + store_reverse_endianness_float_t((float_t*)(d + 84), ptcl->data.z_offset); + store_reverse_endianness_int32_t((int32_t*)(d + 88), ptcl->data.pivot); + store_reverse_endianness_int32_t((int32_t*)(d + 92), flags); + store_reverse_endianness_float_t((float_t*)(d + 96), ptcl->data.speed); + store_reverse_endianness_float_t((float_t*)(d + 100), ptcl->data.speed_random); + store_reverse_endianness_float_t((float_t*)(d + 104), ptcl->data.deceleration); + store_reverse_endianness_float_t((float_t*)(d + 108), ptcl->data.deceleration_random); + store_reverse_endianness_float_t((float_t*)(d + 112), ptcl->data.direction.x); + store_reverse_endianness_float_t((float_t*)(d + 116), ptcl->data.direction.y); + store_reverse_endianness_float_t((float_t*)(d + 120), ptcl->data.direction.z); + store_reverse_endianness_float_t((float_t*)(d + 124), ptcl->data.direction_random.x); + store_reverse_endianness_float_t((float_t*)(d + 128), ptcl->data.direction_random.y); + store_reverse_endianness_float_t((float_t*)(d + 132), ptcl->data.direction_random.z); + store_reverse_endianness_float_t((float_t*)(d + 136), ptcl->data.gravity.x); + store_reverse_endianness_float_t((float_t*)(d + 140), ptcl->data.gravity.y); + store_reverse_endianness_float_t((float_t*)(d + 144), ptcl->data.gravity.z); + store_reverse_endianness_float_t((float_t*)(d + 148), ptcl->data.acceleration.x); + store_reverse_endianness_float_t((float_t*)(d + 152), ptcl->data.acceleration.y); + store_reverse_endianness_float_t((float_t*)(d + 156), ptcl->data.acceleration.z); + store_reverse_endianness_float_t((float_t*)(d + 160), ptcl->data.acceleration_random.x); + store_reverse_endianness_float_t((float_t*)(d + 164), ptcl->data.acceleration_random.y); + store_reverse_endianness_float_t((float_t*)(d + 168), ptcl->data.acceleration_random.z); + store_reverse_endianness_float_t((float_t*)(d + 172), ptcl->data.reflection_coeff); + store_reverse_endianness_float_t((float_t*)(d + 176), ptcl->data.reflection_coeff_random); + store_reverse_endianness_float_t((float_t*)(d + 180), ptcl->data.rebound_plane_y); + store_reverse_endianness_float_t((float_t*)(d + 184), ptcl->data.uv_scroll_add.x); + store_reverse_endianness_float_t((float_t*)(d + 188), ptcl->data.uv_scroll_add.y); + store_reverse_endianness_float_t((float_t*)(d + 192), ptcl->data.uv_scroll_add_scale); + store_reverse_endianness_int32_t((int32_t*)(d + 196), ptcl->data.sub_flags); + store_reverse_endianness_int32_t((int32_t*)(d + 200), ptcl->data.count); + } + else { + *(int32_t*)d = ptcl->data.life_time; + *(int32_t*)(d + 4) = type; + *(int32_t*)(d + 8) = ptcl->data.draw_type; + *(vec3*)(d + 12) = ptcl->data.rotation; + *(vec3*)(d + 24) = ptcl->data.rotation_random; + *(vec3*)(d + 36) = ptcl->data.rotation_add; + *(vec3*)(d + 48) = ptcl->data.rotation_add_random; + *(vec3*)(d + 60) = ptcl->data.scale; + *(vec3*)(d + 72) = ptcl->data.scale_random; + *(float_t*)(d + 84) = ptcl->data.z_offset; + *(int32_t*)(d + 88) = ptcl->data.pivot; + *(int32_t*)(d + 92) = flags; + *(float_t*)(d + 96) = ptcl->data.speed; + *(float_t*)(d + 100) = ptcl->data.speed_random; + *(float_t*)(d + 104) = ptcl->data.deceleration; + *(float_t*)(d + 108) = ptcl->data.deceleration_random; + *(vec3*)(d + 112) = ptcl->data.direction; + *(vec3*)(d + 124) = ptcl->data.direction_random; + *(vec3*)(d + 136) = ptcl->data.gravity; + *(vec3*)(d + 148) = ptcl->data.acceleration; + *(vec3*)(d + 160) = ptcl->data.acceleration_random; + *(float_t*)(d + 172) = ptcl->data.reflection_coeff; + *(float_t*)(d + 176) = ptcl->data.reflection_coeff_random; + *(float_t*)(d + 180) = ptcl->data.rebound_plane_y; + *(vec2*)(d + 184) = ptcl->data.uv_scroll_add; + *(float_t*)(d + 192) = ptcl->data.uv_scroll_add_scale; + *(int32_t*)(d + 196) = ptcl->data.sub_flags; + *(int32_t*)(d + 200) = ptcl->data.count; + } d += 204; if (ptcl->version == 3) { *(int32_t*)d = 0; - *(float_t*)(d + 4) = ptcl->data.emission; + if (big_endian) + store_reverse_endianness_float_t((float_t*)(d + 4), ptcl->data.emission); + else + *(float_t*)(d + 4) = ptcl->data.emission; d += 8; } if (ptcl->data.type == PARTICLE_LOCUS || ptcl->data.type == PARTICLE_MESH) { - *(uint16_t*)d = ptcl->data.locus_history_size; - *(uint16_t*)(d + 2) = ptcl->data.locus_history_size_random; + if (big_endian) { + store_reverse_endianness_uint16_t((uint16_t*)d, (uint16_t)ptcl->data.locus_history_size); + store_reverse_endianness_uint16_t((uint16_t*)(d + 2), (uint16_t)ptcl->data.locus_history_size_random); + } + else { + *(uint16_t*)d = (uint16_t)ptcl->data.locus_history_size; + *(uint16_t*)(d + 2) = (uint16_t)ptcl->data.locus_history_size_random; + } d += 4; } - *(uint64_t*)d = ptcl->data.tex_hash; - *(uint8_t*)(d + 8) = (uint8_t)roundf(clamp(ptcl->data.color.x, 0.0f, 1.0f) * 255.0f); - *(uint8_t*)(d + 9) = (uint8_t)roundf(clamp(ptcl->data.color.y, 0.0f, 1.0f) * 255.0f); - *(uint8_t*)(d + 10) = (uint8_t)roundf(clamp(ptcl->data.color.z, 0.0f, 1.0f) * 255.0f); - *(uint8_t*)(d + 11) = (uint8_t)roundf(clamp(ptcl->data.color.w, 0.0f, 1.0f) * 255.0f); - *(int32_t*)(d + 12) = ptcl->data.blend_mode; - *(int32_t*)(d + 16) = ptcl->data.unk0; - *(int32_t*)(d + 20) = ptcl->data.split_u; - *(int32_t*)(d + 24) = ptcl->data.split_v; - *(int32_t*)(d + 28) = ptcl->data.uv_index_type; - *(int16_t*)(d + 32) = ptcl->data.uv_index; - *(int16_t*)(d + 34) = (int16_t)ptcl->data.frame_step_uv; - *(int32_t*)(d + 36) = ptcl->data.uv_index_start; - *(int32_t*)(d + 40) = ptcl->data.uv_index_end; + if (big_endian) { + store_reverse_endianness_uint64_t((uint64_t*)d, ptcl->data.tex_hash); + *(uint8_t*)(d + 8) = (uint8_t)roundf(clamp_def(ptcl->data.color.x, 0.0f, 1.0f) * 255.0f); + *(uint8_t*)(d + 9) = (uint8_t)roundf(clamp_def(ptcl->data.color.y, 0.0f, 1.0f) * 255.0f); + *(uint8_t*)(d + 10) = (uint8_t)roundf(clamp_def(ptcl->data.color.z, 0.0f, 1.0f) * 255.0f); + *(uint8_t*)(d + 11) = (uint8_t)roundf(clamp_def(ptcl->data.color.w, 0.0f, 1.0f) * 255.0f); + store_reverse_endianness_int32_t((int32_t*)(d + 12), ptcl->data.blend_mode); + store_reverse_endianness_int32_t((int32_t*)(d + 16), ptcl->data.unk0); + store_reverse_endianness_int32_t((int32_t*)(d + 20), ptcl->data.split_u); + store_reverse_endianness_int32_t((int32_t*)(d + 24), ptcl->data.split_v); + store_reverse_endianness_int32_t((int32_t*)(d + 28), ptcl->data.uv_index_type); + store_reverse_endianness_int16_t((int16_t*)(d + 32), (int16_t)ptcl->data.uv_index); + store_reverse_endianness_int16_t((int16_t*)(d + 34), (int16_t)ptcl->data.frame_step_uv); + store_reverse_endianness_int32_t((int32_t*)(d + 36), ptcl->data.uv_index_start); + store_reverse_endianness_int32_t((int32_t*)(d + 40), ptcl->data.uv_index_end); + } + else { + *(uint64_t*)d = ptcl->data.tex_hash; + *(uint8_t*)(d + 8) = (uint8_t)roundf(clamp_def(ptcl->data.color.x, 0.0f, 1.0f) * 255.0f); + *(uint8_t*)(d + 9) = (uint8_t)roundf(clamp_def(ptcl->data.color.y, 0.0f, 1.0f) * 255.0f); + *(uint8_t*)(d + 10) = (uint8_t)roundf(clamp_def(ptcl->data.color.z, 0.0f, 1.0f) * 255.0f); + *(uint8_t*)(d + 11) = (uint8_t)roundf(clamp_def(ptcl->data.color.w, 0.0f, 1.0f) * 255.0f); + *(int32_t*)(d + 12) = ptcl->data.blend_mode; + *(int32_t*)(d + 16) = ptcl->data.unk0; + *(int32_t*)(d + 20) = ptcl->data.split_u; + *(int32_t*)(d + 24) = ptcl->data.split_v; + *(int32_t*)(d + 28) = ptcl->data.uv_index_type; + *(int16_t*)(d + 32) = (int16_t)ptcl->data.uv_index; + *(int16_t*)(d + 34) = (int16_t)ptcl->data.frame_step_uv; + *(int32_t*)(d + 36) = ptcl->data.uv_index_start; + *(int32_t*)(d + 40) = ptcl->data.uv_index_end; + } + d += 44; + if (eff_group->version >= 7) { - *(int32_t*)(d + 44) = ptcl->data.unk1; - d += 48; + if (big_endian) + store_reverse_endianness_int32_t((int32_t*)d, ptcl->data.unk1); + else + *(int32_t*)d = ptcl->data.unk1; + d += 4; } else - d += 44; if (ptcl->data.flags & PARTICLE_TEXTURE_MASK) { - *(uint64_t*)d = ptcl->data.mask_tex_hash; - *(int32_t*)(d + 8) = ptcl->data.mask_blend_mode; + if (big_endian) { + store_reverse_endianness_uint64_t((uint64_t*)d, ptcl->data.mask_tex_hash); + store_reverse_endianness_int32_t((int32_t*)(d + 8), ptcl->data.mask_blend_mode); + } + else { + *(uint64_t*)d = ptcl->data.mask_tex_hash; + *(int32_t*)(d + 8) = ptcl->data.mask_blend_mode; + } d += 12; } else { @@ -693,13 +975,13 @@ namespace Glitter { st->header.signature = reverse_endianness_uint32_t('PTCL'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; st->header.version = ptcl->version; return true; } - bool FileWriter::UnparseAnimation(f2_struct* st, Animation* anim, CurveTypeFlags flags) { + bool FileWriter::UnparseAnimation(f2_struct* st, Animation* anim, CurveTypeFlags flags, bool big_endian) { if (anim->curves.size() < 1) return false; @@ -746,7 +1028,7 @@ namespace Glitter { continue; f2_struct s; - if (UnparseCurve(&s, c)) { + if (UnparseCurve(&s, c, big_endian)) { st->sub_structs.push_back(s); break; } @@ -758,12 +1040,12 @@ namespace Glitter { st->header.signature = reverse_endianness_uint32_t('ANIM'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; return true; } - bool FileWriter::UnparseCurve(f2_struct* st, Curve* c) { + bool FileWriter::UnparseCurve(f2_struct* st, Curve* c, bool big_endian) { #if !defined(CRE_DEV) if (c->keys.size() < 1) return false; @@ -806,24 +1088,35 @@ namespace Glitter { break; } - *(uint32_t*)d = c->type; - *(uint32_t*)(d + 4) = c->repeat ? 1 : 0; - *(uint32_t*)(d + 8) = c->flags; - *(float_t*)(d + 12) = random_range; - *(int16_t*)(d + 16) = (int16_t)c->keys.size(); - *(int16_t*)(d + 18) = (int16_t)c->start_time; - *(int16_t*)(d + 20) = (int16_t)c->end_time; + if (big_endian) { + store_reverse_endianness_uint32_t((uint32_t*)d, c->type); + store_reverse_endianness_uint32_t((uint32_t*)(d + 4), c->repeat ? 1 : 0); + store_reverse_endianness_uint32_t((uint32_t*)(d + 8), c->flags); + store_reverse_endianness_float_t((float_t*)(d + 12), random_range); + store_reverse_endianness_int16_t((int16_t*)(d + 16), (int16_t)c->keys.size()); + store_reverse_endianness_int16_t((int16_t*)(d + 18), (int16_t)c->start_time); + store_reverse_endianness_int16_t((int16_t*)(d + 20), (int16_t)c->end_time); + } + else { + *(uint32_t*)d = c->type; + *(uint32_t*)(d + 4) = c->repeat ? 1 : 0; + *(uint32_t*)(d + 8) = c->flags; + *(float_t*)(d + 12) = random_range; + *(int16_t*)(d + 16) = (int16_t)c->keys.size(); + *(int16_t*)(d + 18) = (int16_t)c->start_time; + *(int16_t*)(d + 20) = (int16_t)c->end_time; + } st->enrs = e; st->header.signature = reverse_endianness_uint32_t('CURV'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; st->header.version = c->version; f2_struct s; - PackCurve(&s, c); + PackCurve(&s, c, big_endian); st->sub_structs.push_back(s); #if defined(CRE_DEV) @@ -832,8 +1125,8 @@ namespace Glitter { return true; } - bool FileWriter::UnparseDivaEffect(EffectGroup* eff_group, f2_struct* st) { - UnparseEffectGroup(eff_group, st); + bool FileWriter::UnparseDivaEffect(EffectGroup* eff_group, f2_struct* st, bool big_endian) { + UnparseEffectGroup(eff_group, st, big_endian); st->header.signature = reverse_endianness_uint32_t('DVEF'); st->header.length = 0x20; @@ -843,16 +1136,16 @@ namespace Glitter { return true; } - bool FileWriter::UnparseDivaList(EffectGroup* eff_group, f2_struct* st) { + bool FileWriter::UnparseDivaList(EffectGroup* eff_group, f2_struct* st, bool big_endian) { f2_struct s; - if (!PackDivaList(eff_group, &s)) + if (!PackDivaList(eff_group, &s, big_endian)) return false; st->sub_structs.push_back(s); st->header.signature = reverse_endianness_uint32_t('LIST'); st->header.length = 0x20; - st->header.use_big_endian = false; + st->header.use_big_endian = big_endian; st->header.use_section_size = true; return true; } @@ -872,12 +1165,12 @@ namespace Glitter { return true; } - bool FileWriter::UnparseEffect(EffectGroup* eff_group, f2_struct* st, Effect* eff) { - if (!PackEffect(st, eff)) + bool FileWriter::UnparseEffect(EffectGroup* eff_group, f2_struct* st, Effect* eff, bool big_endian) { + if (!PackEffect(st, eff, big_endian)) return false; f2_struct s; - if (UnparseAnimation(&s, &eff->animation, effect_curve_flags)) + if (UnparseAnimation(&s, &eff->animation, effect_curve_flags, big_endian)) st->sub_structs.push_back(s); for (Emitter*& i : eff->emitters) { @@ -885,33 +1178,34 @@ namespace Glitter { continue; f2_struct s; - if (UnparseEmitter(eff_group, &s, i, eff)) + if (UnparseEmitter(eff_group, &s, i, eff, big_endian)) st->sub_structs.push_back(s); } return true; } - void FileWriter::UnparseEffectGroup(EffectGroup* eff_group, f2_struct* st) { + void FileWriter::UnparseEffectGroup(EffectGroup* eff_group, f2_struct* st, bool big_endian) { for (Effect*& i : eff_group->effects) { if (!i) continue; f2_struct s; - if (UnparseEffect(eff_group, &s, i)) + if (UnparseEffect(eff_group, &s, i, big_endian)) st->sub_structs.push_back(s); } f2_struct s; - if (PackDivaResourceHashes(eff_group, &s)) + if (PackDivaResourceHashes(eff_group, &s, big_endian)) st->sub_structs.push_back(s); } - bool FileWriter::UnparseEmitter(EffectGroup* eff_group, f2_struct* st, Emitter* emit, Effect* eff) { - if (!PackEmitter(st, emit)) + bool FileWriter::UnparseEmitter(EffectGroup* eff_group, + f2_struct* st, Emitter* emit, Effect* eff, bool big_endian) { + if (!PackEmitter(st, emit, big_endian)) return false; f2_struct s; - if (UnparseAnimation(&s, &emit->animation, emitter_curve_flags)) + if (UnparseAnimation(&s, &emit->animation, emitter_curve_flags, big_endian)) st->sub_structs.push_back(s); for (Particle*& i : emit->particles) { @@ -919,14 +1213,15 @@ namespace Glitter { continue; f2_struct s; - if (UnparseParticle(eff_group, &s, i, eff)) + if (UnparseParticle(eff_group, &s, i, eff, big_endian)) st->sub_structs.push_back(s); } return true; } - bool FileWriter::UnparseParticle(EffectGroup* eff_group, f2_struct* st, Particle* ptcl, Effect* eff) { - if (!PackParticle(eff_group, st, ptcl, eff)) + bool FileWriter::UnparseParticle(EffectGroup* eff_group, + f2_struct* st, Particle* ptcl, Effect* eff, bool big_endian) { + if (!PackParticle(eff_group, st, ptcl, eff, big_endian)) return false; CurveTypeFlags flags; @@ -942,19 +1237,20 @@ namespace Glitter { } f2_struct s; - if (UnparseAnimation(&s, &ptcl->animation, flags)) + if (UnparseAnimation(&s, &ptcl->animation, flags, big_endian)) st->sub_structs.push_back(s); return true; } - void FileWriter::Write(GLT, EffectGroup* eff_group, const char* path, const char* file, bool compress) { + void FileWriter::Write(GLT, EffectGroup* eff_group, + const char* path, const char* file, bool compress, bool big_endian) { FileWriter fr; fr.type = GLT_VAL; farc f; { f2_struct st; - if (fr.UnparseDivaEffect(eff_group, &st)) { + if (fr.UnparseDivaEffect(eff_group, &st, big_endian)) { f.add_file(); farc_file& ff_drs = f.files.back(); st.write(&ff_drs.data, &ff_drs.size); @@ -976,7 +1272,7 @@ namespace Glitter { if (fr.type == Glitter::FT) { f2_struct st; - if (fr.UnparseDivaList(eff_group, &st)) { + if (fr.UnparseDivaList(eff_group, &st, big_endian)) { f.add_file(); farc_file& ff_lst = f.files.back(); st.write(&ff_lst.data, &ff_lst.size); @@ -995,18 +1291,18 @@ namespace Glitter { char* temp = str_utils_add(path, file); if (glt_type != Glitter::FT) { char* list_temp = str_utils_add(temp, ".glitter.txt"); - stream s; + file_stream s; s.open(list_temp, "wb"); - if (s.io.stream) { + if (s.check_not_null()) { for (Glitter::Effect*& i : eff_group->effects) if (i) { s.write_string(i->name); s.write_char('\n'); } } - free(list_temp); + free_def(list_temp); } f.write(temp, mode, false); - free(temp); + free_def(temp); } } diff --git a/src/CRE/Glitter/glitter.cpp b/src/CRE/Glitter/glitter.cpp index cdcb9bbf..5daf006c 100644 --- a/src/CRE/Glitter/glitter.cpp +++ b/src/CRE/Glitter/glitter.cpp @@ -268,7 +268,7 @@ namespace Glitter { vec3_cross(*vec1, *vec2, *axis); vec3_length(*axis, *angle); if (*angle >= 0.000001f) - *angle = asinf(min(*angle, 1.0f)); + *angle = asinf(min_def(*angle, 1.0f)); else { *angle = 0.0f; axis->x = vec1->z; diff --git a/src/CRE/Glitter/glitter.hpp b/src/CRE/Glitter/glitter.hpp index b8bacf67..4835df84 100644 --- a/src/CRE/Glitter/glitter.hpp +++ b/src/CRE/Glitter/glitter.hpp @@ -941,7 +941,7 @@ namespace Glitter { void GetExtColor(float_t& r, float_t& g, float_t& b, float_t& a); FogType GetFog(); void GetValue(); - void SetExtAnim(mat4* a2, mat4* a3, vec3* trans, bool set_flags); + void SetExtAnim(const mat4* a2, const mat4* a3, const vec3* trans, bool set_flags); }; class Emitter : public Node { @@ -1130,24 +1130,28 @@ namespace Glitter { FileWriter(); - void PackCurve(f2_struct* st, Curve* c); - bool PackDivaList(EffectGroup* eff_group, f2_struct* st); + void PackCurve(f2_struct* st, Curve* c, bool big_endian); + bool PackDivaList(EffectGroup* eff_group, f2_struct* st, bool big_endian); bool PackDivaResource(EffectGroup* eff_group, f2_struct* st); - bool PackDivaResourceHashes(EffectGroup* eff_group, f2_struct* st); - bool PackEffect(f2_struct* st, Effect* eff); - bool PackEmitter(f2_struct* st, Emitter* emit); - bool PackParticle(EffectGroup* eff_group, f2_struct* st, Particle* ptcl, Effect* eff); - bool UnparseAnimation(f2_struct* st, Animation* anim, CurveTypeFlags flags); - bool UnparseCurve(f2_struct* st, Curve* c); - bool UnparseDivaEffect(EffectGroup* eff_group, f2_struct* st); - bool UnparseDivaList(EffectGroup* eff_group, f2_struct* st); + bool PackDivaResourceHashes(EffectGroup* eff_group, f2_struct* st, bool big_endian); + bool PackEffect(f2_struct* st, Effect* eff, bool big_endian); + bool PackEmitter(f2_struct* st, Emitter* emit, bool big_endian); + bool PackParticle(EffectGroup* eff_group, + f2_struct* st, Particle* ptcl, Effect* eff, bool big_endian); + bool UnparseAnimation(f2_struct* st, Animation* anim, CurveTypeFlags flags, bool big_endian); + bool UnparseCurve(f2_struct* st, Curve* c, bool big_endian); + bool UnparseDivaEffect(EffectGroup* eff_group, f2_struct* st, bool big_endian); + bool UnparseDivaList(EffectGroup* eff_group, f2_struct* st, bool big_endian); bool UnparseDivaResource(EffectGroup* eff_group, f2_struct* st); - bool UnparseEffect(EffectGroup* eff_group, f2_struct* st, Effect* eff); - void UnparseEffectGroup(EffectGroup* eff_group, f2_struct* st); - bool UnparseEmitter(EffectGroup* eff_group, f2_struct* st, Emitter* emit, Effect* eff); - bool UnparseParticle(EffectGroup* eff_group, f2_struct* st, Particle* ptcl, Effect* eff); + bool UnparseEffect(EffectGroup* eff_group, f2_struct* st, Effect* eff, bool big_endian); + void UnparseEffectGroup(EffectGroup* eff_group, f2_struct* st, bool big_endian); + bool UnparseEmitter(EffectGroup* eff_group, + f2_struct* st, Emitter* emit, Effect* eff, bool big_endian); + bool UnparseParticle(EffectGroup* eff_group, + f2_struct* st, Particle* ptcl, Effect* eff, bool big_endian); - static void Write(GLT, EffectGroup* eff_group, const char* path, const char* file, bool compress); + static void Write(GLT, EffectGroup* eff_group, + const char* path, const char* file, bool compress, bool big_endian = false); }; struct LocusHistory { @@ -1155,6 +1159,8 @@ namespace Glitter { vec4 color; vec3 translation; float_t scale; + + Data(); }; std::vector data; @@ -1234,6 +1240,8 @@ namespace Glitter { int32_t unk0; int32_t unk1; Particle::Mesh mesh; + + Data(); }; Particle::Data data; diff --git a/src/CRE/Glitter/locus_history.cpp b/src/CRE/Glitter/locus_history.cpp index 50732cc2..9acd363f 100644 --- a/src/CRE/Glitter/locus_history.cpp +++ b/src/CRE/Glitter/locus_history.cpp @@ -6,6 +6,10 @@ #include "glitter.hpp" namespace Glitter { + LocusHistory::LocusHistory::Data::Data() :scale() { + + } + LocusHistory::LocusHistory(size_t size) { data.reserve(size); } @@ -21,7 +25,7 @@ namespace Glitter { if (ptcl_inst->data.data.flags & PARTICLE_EMITTER_LOCAL && ptcl_inst->data.emitter) { vec3 emit_trans; mat4_get_translation(&ptcl_inst->data.emitter->mat, &emit_trans); - vec3_add(temp, emit_trans, temp); + temp += emit_trans; } LocusHistory::Data locus_history; @@ -57,7 +61,7 @@ namespace Glitter { if (ptcl_inst->data.data.flags & PARTICLE_EMITTER_LOCAL && ptcl_inst->data.emitter) { vec3 emit_trans; mat4_get_translation(&ptcl_inst->data.emitter->mat, &emit_trans); - vec3_add(temp, emit_trans, temp); + temp += emit_trans; if (ptcl_inst->data.data.flags & PARTICLE_ROTATE_LOCUS) mat4_mult_vec3(&ptcl_inst->data.emitter->mat_rot, &temp, &temp); } diff --git a/src/CRE/Glitter/particle.cpp b/src/CRE/Glitter/particle.cpp index 72a0a810..60c474aa 100644 --- a/src/CRE/Glitter/particle.cpp +++ b/src/CRE/Glitter/particle.cpp @@ -6,6 +6,16 @@ #include "glitter.hpp" namespace Glitter { + Particle::Data::Data() : flags(), life_time(), life_time_random(), fade_in(), fade_in_random(), + fade_out(), fade_out_random(), type(), pivot(), draw_type(), z_offset(), speed(), speed_random(), + deceleration(), deceleration_random(), reflection_coeff(), reflection_coeff_random(), rebound_plane_y(), + uv_index_type(), uv_index(), frame_step_uv(), uv_index_start(), uv_index_end(), uv_index_count(), + uv_scroll_add_scale(), uv_scroll_2nd_add_scale(), split_u(), split_v(), blend_mode(), mask_blend_mode(), + sub_flags(), count(), locus_history_size(), locus_history_size_random(), draw_flags(), + emission(), tex_hash(), mask_tex_hash(), texture(), mask_texture(), unk0(), unk1(), mesh() { + + } + Particle::Particle(GLT) : data() { version = GLT_VAL == Glitter::X ? 0x05 : 0x03; data.pivot = PIVOT_MIDDLE_CENTER; @@ -40,185 +50,3 @@ namespace Glitter { } } - -/* -#include "particle.hpp" -#include "animation.hpp" -#include "curve.hpp" - -static bool glitter_particle_pack_file(GLT, EffectGroup* a1, - f2_struct* st, glitter_particle* a3, glitter_effect* effect); - -bool glitter_particle_unparse_file(GLT, EffectGroup* a1, - f2_struct* st, glitter_particle* a3, glitter_effect* effect) { - if (!glitter_particle_pack_file(GLT_VAL, a1, st, a3, effect)) - return false; - - glitter_curve_type_flags flags = (glitter_curve_type_flags)0; - if (a1->type == Glitter::X) - flags = glitter_particle_x_curve_flags; - else - flags = glitter_particle_curve_flags; - - if (a3->data.type != PARTICLE_MESH) { - enum_and(flags, ~CURVE_TYPE_UV_SCROLL_2ND); - if (a3->data.draw_type != DIRECTION_PARTICLE_ROTATION) - enum_and(flags, ~(CURVE_TYPE_ROTATION_X | CURVE_TYPE_ROTATION_Y)); - } - - f2_struct s; - if (glitter_animation_unparse_file(GLT_VAL, &s, &a3->animation, flags)) - st->sub_structs.push_back(s); - return true; -} - -static bool glitter_particle_pack_file(GLT, - EffectGroup* a1, f2_struct* st, glitter_particle* a3, glitter_effect* effect) { - size_t l; - size_t d; - glitter_particle_flag flags; - - if (a3->version < 2) - return false; - - l = 0; - - uint32_t o; - enrs e; - enrs_entry ee; - - ee = { 0, 1, 204, 1 }; - ee.append(0, 51, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 204; - - if (a3->version == 3) { - ee = { o, 1, 8, 1 }; - ee.append(0, 2, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 8; - } - - if (a3->data.type == PARTICLE_LOCUS || a3->data.type == PARTICLE_MESH) { - ee = { o, 1, 4, 1 }; - ee.append(0, 2, ENRS_WORD); - e.vec.push_back(ee); - l += o = 4; - } - - ee = { o, 4, 44, 1 }; - ee.append(0, 1, ENRS_QWORD); - ee.append(4, 5, ENRS_DWORD); - ee.append(0, 2, ENRS_WORD); - ee.append(0, 2, ENRS_DWORD); - if (a1->version >= 7) { - ee.count++; - ee.size += 4; - ee.append.push_back(0, 1, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 48; - } - else { - e.vec.push_back(ee); - l += o = 44; - } - - ee = { o, 2, 12, 1 }; - ee.append.push_back(0, 1, ENRS_QWORD); - ee.append.push_back(0, 1, ENRS_DWORD); - e.vec.push_back(ee); - l += o = 12; - - l = align_val(l, 0x10); - st->data.resize(l); - d = (size_t)st->data.data(); - st->enrs = e; - - flags = a3->data.flags; - if (effect->data.flags & EFFECT_LOCAL) - enum_and(flags, ~PARTICLE_LOCAL); - if (effect->data.flags & EFFECT_EMISSION) - enum_and(flags, ~PARTICLE_EMISSION); - - *(int32_t*)d = a3->data.life_time; - *(int32_t*)(d + 4) = a3->data.type; - *(int32_t*)(d + 8) = a3->data.draw_type; - *(vec3*)(d + 12) = a3->data.rotation; - *(vec3*)(d + 24) = a3->data.rotation_random; - *(vec3*)(d + 36) = a3->data.rotation_add; - *(vec3*)(d + 48) = a3->data.rotation_add_random; - *(vec3*)(d + 60) = a3->data.scale; - *(vec3*)(d + 72) = a3->data.scale_random; - *(float_t*)(d + 84) = a3->data.z_offset; - *(int32_t*)(d + 88) = a3->data.pivot; - *(int32_t*)(d + 92) = flags; - *(float_t*)(d + 96) = a3->data.speed; - *(float_t*)(d + 100) = a3->data.speed_random; - *(float_t*)(d + 104) = a3->data.deceleration; - *(float_t*)(d + 108) = a3->data.deceleration_random; - *(vec3*)(d + 112) = a3->data.direction; - *(vec3*)(d + 124) = a3->data.direction_random; - *(vec3*)(d + 136) = a3->data.gravity; - *(vec3*)(d + 148) = a3->data.acceleration; - *(vec3*)(d + 160) = a3->data.acceleration_random; - *(float_t*)(d + 172) = a3->data.reflection_coeff; - *(float_t*)(d + 176) = a3->data.reflection_coeff_random; - *(float_t*)(d + 180) = a3->data.rebound_plane_y; - *(vec2*)(d + 184) = a3->data.uv_scroll_add; - *(float_t*)(d + 192) = a3->data.uv_scroll_add_scale; - *(int32_t*)(d + 196) = a3->data.sub_flags; - *(int32_t*)(d + 200) = a3->data.count; - d += 204; - - if (a3->version == 3) { - *(int32_t*)d = 0; - *(float_t*)(d + 4) = a3->data.emission; - d += 8; - } - - if (a3->data.type == PARTICLE_LOCUS || a3->data.type == PARTICLE_MESH) { - *(uint16_t*)d = a3->data.locus_history_size; - *(uint16_t*)(d + 2) = a3->data.locus_history_size_random; - d += 4; - } - - *(uint64_t*)d = a3->data.tex_hash; - *(uint8_t*)(d + 8) = (uint8_t)roundf(clamp(a3->data.color.x, 0.0f, 1.0f) * 255.0f); - *(uint8_t*)(d + 9) = (uint8_t)roundf(clamp(a3->data.color.y, 0.0f, 1.0f) * 255.0f); - *(uint8_t*)(d + 10) = (uint8_t)roundf(clamp(a3->data.color.z, 0.0f, 1.0f) * 255.0f); - *(uint8_t*)(d + 11) = (uint8_t)roundf(clamp(a3->data.color.w, 0.0f, 1.0f) * 255.0f); - *(int32_t*)(d + 12) = a3->data.blend_mode; - *(int32_t*)(d + 16) = a3->data.unk0; - *(int32_t*)(d + 20) = a3->data.split_u; - *(int32_t*)(d + 24) = a3->data.split_v; - *(int32_t*)(d + 28) = a3->data.uv_index_type; - *(int16_t*)(d + 32) = a3->data.uv_index; - *(int16_t*)(d + 34) = (int16_t)a3->data.frame_step_uv; - *(int32_t*)(d + 36) = a3->data.uv_index_start; - *(int32_t*)(d + 40) = a3->data.uv_index_end; - if (a1->version >= 7) { - *(int32_t*)(d + 44) = a3->data.unk1; - d += 48; - } - else - d += 44; - - if (a3->data.flags & PARTICLE_TEXTURE_MASK) { - *(uint64_t*)d = a3->data.mask_tex_hash; - *(int32_t*)(d + 8) = a3->data.mask_blend_mode; - d += 12; - } - else { - *(uint64_t*)d = 0; - *(int32_t*)(d + 8) = 0; - d += 12; - } - - st->header.signature = reverse_endianness_uint32_t('PTCL'); - st->header.length = 0x20; - st->header.use_big_endian = false; - st->header.use_section_size = true; - st->header.version = a3->version; - return true; -} -*/ \ No newline at end of file diff --git a/src/CRE/Glitter/particle_inst.cpp b/src/CRE/Glitter/particle_inst.cpp index e61344dd..0b42e0a5 100644 --- a/src/CRE/Glitter/particle_inst.cpp +++ b/src/CRE/Glitter/particle_inst.cpp @@ -236,7 +236,7 @@ namespace Glitter { + random->F2GetInt(GLT_VAL, ptcl_inst_data->data.uv_index_count); break; } - rend_elem->uv_index = min(rend_elem->uv_index, ptcl_inst_data->data.uv_index_end); + rend_elem->uv_index = min_def(rend_elem->uv_index, ptcl_inst_data->data.uv_index_end); rend_elem->uv.x = (float_t)(rend_elem->uv_index % ptcl_inst_data->data.split_u) * ptcl_inst_data->data.split_uv.x; rend_elem->uv.y = (float_t)(rend_elem->uv_index @@ -559,7 +559,7 @@ namespace Glitter { float_t time = rend_elem->frame * (float_t)(1.0 / 60.0); float_t diff_time = time - rend_elem->rebound_time - (float_t)(1.0 / 60.0); float_t speed = rend_elem->speed * delta_frame; - diff_time = max(diff_time, 0.0f) * (float_t)(1.0 / 60.0); + diff_time = max_def(diff_time, 0.0f) * (float_t)(1.0 / 60.0); vec3 acceleration; vec3_mult_scalar(rend_elem->acceleration, @@ -593,7 +593,7 @@ namespace Glitter { speed = rend_elem->base_speed + (float_t)(1.0 / 7200.0) * rend_elem->deceleration - diff_time * rend_elem->deceleration; - rend_elem->speed = max(speed, 0.0f); + rend_elem->speed = max_def(speed, 0.0f); } void XParticleInst::Copy(XParticleInst* dst, float_t emission) { @@ -711,7 +711,7 @@ namespace Glitter { + random->XGetInt(ptcl_inst_data->data.uv_index_count); break; } - rend_elem->uv_index = min(rend_elem->uv_index, ptcl_inst_data->data.uv_index_end); + rend_elem->uv_index = min_def(rend_elem->uv_index, ptcl_inst_data->data.uv_index_end); rend_elem->uv.x = (float_t)(rend_elem->uv_index % ptcl_inst_data->data.split_u) * ptcl_inst_data->data.split_uv.x; rend_elem->uv.y = (float_t)(rend_elem->uv_index diff --git a/src/CRE/Glitter/particle_manager.cpp b/src/CRE/Glitter/particle_manager.cpp index 91870d7e..3973d78b 100644 --- a/src/CRE/Glitter/particle_manager.cpp +++ b/src/CRE/Glitter/particle_manager.cpp @@ -761,7 +761,7 @@ namespace Glitter { id++; } CheckSceneHasLocalEffect(j); - + SceneCounter counter = j->counter; if (j->type == Glitter::X) counter.index = (uint8_t)id; @@ -789,7 +789,7 @@ namespace Glitter { } CheckSceneHasLocalEffect(scene); scenes.push_back(scene); - + if (scene->type == Glitter::X) counter.index = (uint8_t)id; return counter; @@ -922,7 +922,7 @@ namespace Glitter { break; } } - + void GltParticleManager::SetSceneFrameRate(SceneCounter scene_counter, FrameRateControl* frame_rate) { for (Scene*& i : scenes) if (i && i->counter.counter == scene_counter.counter) { @@ -930,7 +930,7 @@ namespace Glitter { break; } } - + void GltParticleManager::SetSceneName(uint64_t hash, const char* name) { std::map::iterator elem = effect_groups.find(hash); if (elem != effect_groups.end()) diff --git a/src/CRE/Glitter/render_element.cpp b/src/CRE/Glitter/render_element.cpp index 72944046..745f1c52 100644 --- a/src/CRE/Glitter/render_element.cpp +++ b/src/CRE/Glitter/render_element.cpp @@ -75,7 +75,7 @@ namespace Glitter { float_t deceleration = random->F2GetFloat(GLT_VAL, ptcl_inst_data->data.deceleration_random) + ptcl_inst_data->data.deceleration; this->speed = speed * 60.0f; - this->deceleration = max(deceleration * 60.0f, 0.0f); + this->deceleration = max_def(deceleration * 60.0f, 0.0f); vec3 acceleration; random->F2GetVec3(GLT_VAL, ptcl_inst_data->data.acceleration_random, acceleration); @@ -123,7 +123,7 @@ namespace Glitter { ptcl_inst_data->data.deceleration_random) + ptcl_inst_data->data.deceleration; base_speed = speed; this->speed = speed; - this->deceleration = max(deceleration, 0.0f); + this->deceleration = max_def(deceleration, 0.0f); vec3 acceleration; random->XGetVec3(ptcl_inst_data->data.acceleration_random, acceleration); diff --git a/src/CRE/Glitter/render_group.cpp b/src/CRE/Glitter/render_group.cpp index 2a8160a9..23a8d965 100644 --- a/src/CRE/Glitter/render_group.cpp +++ b/src/CRE/Glitter/render_group.cpp @@ -100,8 +100,8 @@ namespace Glitter { glGenBuffers(1, &ebo); gl_state_bind_element_array_buffer(ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int32_t) * count, ebo_data, GL_STATIC_DRAW);; - free(ebo_data); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int32_t) * count, ebo_data, GL_STATIC_DRAW); + free_def(ebo_data); } static const GLsizei buffer_size = sizeof(Buffer); @@ -214,16 +214,13 @@ namespace Glitter { particle->AccelerateParticle(GLT_VAL, rend_elem, rend_elem->frame * (float_t)(1.0 / 60.0), delta_frame, random_ptr); - if (particle->data.data.draw_type == DIRECTION_PARTICLE_ROTATION) { - rend_elem->rotation.x += rend_elem->rotation_add.x * delta_frame; - rend_elem->rotation.y += rend_elem->rotation_add.y * delta_frame; - } - rend_elem->rotation.z += rend_elem->rotation_add.z * delta_frame; + if (particle->data.data.draw_type == DIRECTION_PARTICLE_ROTATION) + rend_elem->rotation += rend_elem->rotation_add * delta_frame; + else + rend_elem->rotation.z += rend_elem->rotation_add.z * delta_frame; - vec2 uv_scroll; - vec2_mult_scalar(particle->data.data.uv_scroll_add, - particle->data.data.uv_scroll_add_scale * delta_frame, uv_scroll); - vec2_add(rend_elem->uv_scroll, uv_scroll, rend_elem->uv_scroll); + rend_elem->uv_scroll += particle->data.data.uv_scroll_add + * (particle->data.data.uv_scroll_add_scale * delta_frame); particle->StepUVParticle(GLT_VAL, rend_elem, delta_frame, random_ptr); rend_elem->disp = true; @@ -453,8 +450,8 @@ namespace Glitter { glGenBuffers(1, &ebo); gl_state_bind_element_array_buffer(ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int32_t) * count, ebo_data, GL_STATIC_DRAW);; - free(ebo_data); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int32_t) * count, ebo_data, GL_STATIC_DRAW); + free_def(ebo_data); } if (!is_mesh) { @@ -574,11 +571,10 @@ namespace Glitter { particle->AccelerateParticle(rend_elem, delta_frame, random_ptr); if (particle->data.data.draw_type == DIRECTION_PARTICLE_ROTATION - || particle->data.data.type == PARTICLE_MESH) { - rend_elem->rotation.x += rend_elem->rotation_add.x * delta_frame; - rend_elem->rotation.y += rend_elem->rotation_add.y * delta_frame; - } - rend_elem->rotation.z += rend_elem->rotation_add.z * delta_frame; + || particle->data.data.type == PARTICLE_MESH) + rend_elem->rotation += rend_elem->rotation_add * delta_frame; + else + rend_elem->rotation.z += rend_elem->rotation_add.z * delta_frame; vec2 uv_scroll; vec2_mult_scalar(particle->data.data.uv_scroll_add, @@ -642,7 +638,7 @@ namespace Glitter { if (!a2 && elements) { Free(); - free(elements); + free_def(elements); } } void XRenderGroup::Emit(XParticleInst::Data* ptcl_inst_data, diff --git a/src/CRE/Glitter/render_scene.cpp b/src/CRE/Glitter/render_scene.cpp index 063b0726..7750db58 100644 --- a/src/CRE/Glitter/render_scene.cpp +++ b/src/CRE/Glitter/render_scene.cpp @@ -485,7 +485,7 @@ namespace Glitter { RenderElement* elem = rend_group->elements; size_t disp = 0; for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; @@ -639,7 +639,7 @@ namespace Glitter { size_t disp = 0; if (rend_group->draw_type == DIRECTION_PARTICLE_ROTATION) for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; @@ -722,7 +722,7 @@ namespace Glitter { } else for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; @@ -1020,7 +1020,6 @@ namespace Glitter { case PARTICLE_QUAD: { gl_state_bind_vertex_array(rend_group->vao); shaders_ft.draw_elements(GL_TRIANGLES, (GLsizei)(6 * rend_group->disp), GL_UNSIGNED_INT, 0); - gl_state_bind_vertex_array(0); } break; case PARTICLE_LINE: @@ -1029,7 +1028,6 @@ namespace Glitter { const GLenum mode = rend_group->type == PARTICLE_LINE ? GL_LINE_STRIP : GL_TRIANGLE_STRIP; for (std::pair& i : rend_group->draw_list) shaders_ft.draw_arrays(mode, i.first, i.second); - gl_state_bind_vertex_array(0); } break; } @@ -1457,7 +1455,7 @@ namespace Glitter { RenderElement* elem = rend_group->elements; size_t disp = 0; for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; @@ -1628,7 +1626,7 @@ namespace Glitter { RenderElement* elem = rend_group->elements; size_t disp = 0; for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; @@ -1778,7 +1776,7 @@ namespace Glitter { size_t disp = 0; if (rend_group->draw_type == DIRECTION_PARTICLE_ROTATION) for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; @@ -1856,7 +1854,7 @@ namespace Glitter { } else for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; diff --git a/src/CRE/Glitter/scene.cpp b/src/CRE/Glitter/scene.cpp index 08acc512..8683e1d2 100644 --- a/src/CRE/Glitter/scene.cpp +++ b/src/CRE/Glitter/scene.cpp @@ -76,7 +76,7 @@ namespace Glitter { continue; EffectInst* eff = i.ptr; - + bool v13 = false; bool v14 = false; if (v14) @@ -259,7 +259,7 @@ namespace Glitter { return false; return true; } - + bool Scene::HasEnded(size_t id, bool a3) { for (SceneEffect& i : effects) if (i.ptr && i.disp && i.ptr->id == id && !i.ptr->HasEnded(a3)) @@ -320,7 +320,7 @@ namespace Glitter { return false; } #endif - + if (type == Glitter::FT && effect_hash == hash_fnv1a64m_empty || type != Glitter::FT && effect_hash == hash_murmurhash_empty) { for (SceneEffect& i : effects) diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index a29ee180..cf04badb 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -4,6 +4,7 @@ */ #include "auth_3d.hpp" +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/io/json.hpp" #include "../KKdLib/io/path.hpp" #include "../KKdLib/hash.hpp" @@ -75,9 +76,9 @@ static int32_t auth_3d_get_auth_3d_object_index_by_hash(auth_3d* auth, uint32_t object_hash, int32_t instance); static mat4* auth_3d_get_auth_3d_object_hrc_bone_mats(auth_3d* auth, size_t index); static int32_t auth_3d_get_auth_3d_object_hrc_index_by_object_info(auth_3d* auth, - object_info obj_info, int32_t instance); + object_info obj_info, int32_t instance = -1); static int32_t auth_3d_get_auth_3d_object_hrc_index_by_hash(auth_3d* auth, - uint32_t object_hash, int32_t instance); + uint32_t object_hash, int32_t instance = -1); static void auth_3d_read_file(auth_3d* auth, auth_3d_database* auth_3d_db); static void auth_3d_read_file_modern(auth_3d* auth); static void auth_3d_set_material_list(auth_3d* auth, render_context* rctx); @@ -339,8 +340,8 @@ void auth_3d::ctrl(render_context* rctx) { auth_3d_post_process_ctrl(&post_process, frame); auth_3d_post_process_set(&post_process, rctx); - auth_3d_camera_auxiliary_set(&camera_auxiliary, rctx); auth_3d_camera_auxiliary_ctrl(&camera_auxiliary, frame); + auth_3d_camera_auxiliary_set(&camera_auxiliary, rctx); if (camera_root_update) for (auth_3d_camera_root& i : camera_root) { @@ -1146,7 +1147,7 @@ void auth_3d_light::reset() { linear_init = 0.0f; quadratic_init = 0.0f; specular_init = vec4_null; - tone_curve_init = vec3_null; + tone_curve_init = {}; } auth_3d_m_object_hrc::auth_3d_m_object_hrc() { @@ -2303,7 +2304,7 @@ static void a3da_msgpack_read(const char* path, const char* file, a3da* auth_fil msgpack msg; - stream s; + file_stream s; s.open(buf, "rb"); io_json_read(s, &msg); s.close(); @@ -2311,9 +2312,9 @@ static void a3da_msgpack_read(const char* path, const char* file, a3da* auth_fil if (msg.type != MSGPACK_MAP) return; - msgpack* m_objhrcs = msg.read("m_objhrc"); + msgpack* m_objhrcs = msg.read_array("m_objhrc"); if (m_objhrcs) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, m_objhrcs); + msgpack_array* ptr = m_objhrcs->data.arr; for (msgpack& i : *ptr) { msgpack& m_objhrc = i; @@ -2324,9 +2325,9 @@ static void a3da_msgpack_read(const char* path, const char* file, a3da* auth_fil if (name_hash != hash_string_murmurhash(j.name)) continue; - msgpack* instances = m_objhrc.read("instance"); + msgpack* instances = m_objhrc.read_array("instance"); if (instances) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, instances); + msgpack_array* ptr = instances->data.arr; for (msgpack& k : *ptr) { msgpack& instance = k; @@ -2340,9 +2341,9 @@ static void a3da_msgpack_read(const char* path, const char* file, a3da* auth_fil } } - msgpack* objhrcs = msg.read("objhrc"); + msgpack* objhrcs = msg.read_array("objhrc"); if (objhrcs) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, objhrcs); + msgpack_array* ptr = objhrcs->data.arr; for (msgpack& i : *ptr) { msgpack& objhrc = i; @@ -2364,7 +2365,7 @@ static bool auth_3d_key_detect_fast_change(auth_3d_key* data, float_t frame, flo if (data->type < AUTH_3D_KEY_LINEAR || data->type > AUTH_3D_KEY_HOLD) return false; - frame = clamp(frame, 0.0f, data->max_frame); + frame = clamp_def(frame, 0.0f, data->max_frame); size_t length = data->length; if (!length) return false; @@ -2622,25 +2623,39 @@ static mat4* auth_3d_get_auth_3d_object_hrc_bone_mats(auth_3d* auth, size_t inde static int32_t auth_3d_get_auth_3d_object_hrc_index_by_object_info(auth_3d* auth, object_info obj_info, int32_t instance) { - int32_t obj_instance = 0; - for (auth_3d_object_hrc& i : auth->object_hrc) - if (obj_info == i.object_info) { - if (obj_instance == instance) + if (instance < 0) { + for (auth_3d_object_hrc& i : auth->object_hrc) + if (obj_info == i.object_info) return (int32_t)(&i - auth->object_hrc.data()); - obj_instance++; - } + } + else { + int32_t obj_instance = 0; + for (auth_3d_object_hrc& i : auth->object_hrc) + if (obj_info == i.object_info) { + if (obj_instance == instance) + return (int32_t)(&i - auth->object_hrc.data()); + obj_instance++; + } + } return -1; } static int32_t auth_3d_get_auth_3d_object_hrc_index_by_hash(auth_3d* auth, uint32_t object_hash, int32_t instance) { - int32_t obj_instance = 0; - for (auth_3d_object_hrc& i : auth->object_hrc) - if (object_hash == i.object_hash) { - if (obj_instance == instance) + if (instance < 0) { + for (auth_3d_object_hrc& i : auth->object_hrc) + if (object_hash == i.object_hash) return (int32_t)(&i - auth->object_hrc.data()); - obj_instance++; - } + } + else { + int32_t obj_instance = 0; + for (auth_3d_object_hrc& i : auth->object_hrc) + if (object_hash == i.object_hash) { + if (obj_instance == instance) + return (int32_t)(&i - auth->object_hrc.data()); + obj_instance++; + } + } return -1; } @@ -2954,8 +2969,7 @@ static void auth_3d_dof_set(auth_3d_dof* d, render_context* rctx) { vec3 view_point; rctx->camera->get_view_point(view_point); - float_t focus; - vec3_distance(d->model_transform.translation_value, view_point, focus); + float_t focus = vec3::distance(d->model_transform.translation_value, view_point); dof_pv pv; pv.enable = fabsf(d->model_transform.rotation_value.z) > 0.000001f; @@ -3281,7 +3295,11 @@ static void auth_3d_light_set(auth_3d_light* l, render_context* rctx) { enum_or(l->flags_init, AUTH_3D_LIGHT_TONE_CURVE); } - data->set_tone_curve(*(vec3*)&l->tone_curve.value); + light_tone_curve tone_curve; + tone_curve.start_point = l->tone_curve.value.x; + tone_curve.end_point = l->tone_curve.value.y; + tone_curve.coefficient = l->tone_curve.value.z; + data->set_tone_curve(tone_curve); } } @@ -4679,7 +4697,7 @@ static void Auth3dTestTask__SetStage(Auth3dTestTask* tt) { if (!v7) break; - if (memcmp(v7, "STG", min(v5, 3))) { + if (memcmp(v7, "STG", min_def(v5, 3))) { v5 += v6 - v7 - 1; v6 = v7 + 1; continue; diff --git a/src/CRE/auth_3d.hpp b/src/CRE/auth_3d.hpp index b9a9262a..bed7522b 100644 --- a/src/CRE/auth_3d.hpp +++ b/src/CRE/auth_3d.hpp @@ -430,7 +430,7 @@ struct auth_3d_light { float_t linear_init; float_t quadratic_init; vec4 specular_init; - vec3 tone_curve_init; + light_tone_curve tone_curve_init; auth_3d_light(); ~auth_3d_light(); @@ -852,9 +852,9 @@ extern bool auth_3d_data_check_id_loaded(int32_t* id); extern auth_3d* auth_3d_data_get_auth_3d(int32_t id); extern int32_t auth_3d_data_get_auth_3d_id(const char* object_name); extern int32_t auth_3d_data_get_auth_3d_id(object_info obj_info, - int32_t* object_index, bool* hrc, int32_t instance); + int32_t* object_index, bool* hrc, int32_t instance = -1); extern int32_t auth_3d_data_get_auth_3d_id(uint32_t file_name_hash, uint32_t object_hash, - int32_t* object_index, bool* hrc, int32_t instance); + int32_t* object_index, bool* hrc, int32_t instance = -1); extern mat4* auth_3d_data_get_auth_3d_object_mat(int32_t id, size_t index, bool hrc, mat4* mat); extern int32_t auth_3d_data_get_chara_id(int32_t id); extern bool auth_3d_data_get_enable(int32_t* id); diff --git a/src/CRE/camera.cpp b/src/CRE/camera.cpp index 27218e19..158275ee 100644 --- a/src/CRE/camera.cpp +++ b/src/CRE/camera.cpp @@ -6,14 +6,14 @@ #include "camera.hpp" static void camera_calculate_projection(camera* c); +static void camera_calculate_projection_aet(camera* c); static void camera_calculate_view(camera* c); static void camera_calculate_forward(camera* c); -camera::camera() : view(), inv_view(), projection(), inv_projection(), view_projection(), -inv_view_projection(), view_projection_prev(), inv_view_projection_prev(), view_mat3(), inv_view_mat3(), -view_rot(), inv_view_rot(), forward(), rotation(), view_point(), interest(), width(), height(), field_1E4(), -field_1F0(), field_1FC(), field_208(), yaw(), pitch(), roll(), aspect(), fov(), fov_rad(),max_distance(), -min_distance(), changed_view(), changed_proj(), fast_change(), fast_change_hist0(), fast_change_hist1() { +camera::camera() : forward(), rotation(), view_point(), interest(), render_width(), render_height(), +sprite_width(), sprite_height(), field_1E4(), field_1F0(), field_1FC(), field_208(), yaw(), +pitch(), roll(), aspect(), fov(), fov_rad(), max_distance(), min_distance(), changed_view(), +changed_proj(), changed_proj_aet(), fast_change(), fast_change_hist0(), fast_change_hist1() { } @@ -21,15 +21,18 @@ camera::~camera() { } -void camera::initialize(double_t aspect, int32_t width, int32_t height) { +void camera::initialize(double_t aspect, int32_t render_width, + int32_t render_height, int32_t sprite_width, int32_t sprite_height) { this->aspect = aspect; fov = 0.0; forward = { 0.0f, 0.0f, -1.0f }; rotation = { 0.0f, 0.0f, 0.0f }; view_point = { 0.0, 0.0f, 0.0f }; interest = { 0.0f, 0.0f, -1.0f }; - this->width = width; - this->height = height; + this->render_width = render_width; + this->render_height = render_height; + this->sprite_width = sprite_width; + this->sprite_height = sprite_height; view = mat4_identity; inv_view = mat4_identity; projection = mat4_identity; @@ -41,6 +44,7 @@ void camera::initialize(double_t aspect, int32_t width, int32_t height) { min_distance = 0.05; max_distance = 6000.0; changed_proj = true; + changed_proj_aet = true; changed_view = true; fast_change = false; fast_change_hist0 = false; @@ -62,6 +66,7 @@ void camera::set_min_distance(double_t value) { if (value != min_distance) { min_distance = value; changed_proj = true; + changed_proj_aet = true; } } @@ -92,7 +97,7 @@ double_t camera::get_fov() { } void camera::set_fov(double_t value) { - value = clamp(value, 1.0, 180.0); + value = clamp_def(value, 1.0, 180.0); if (value != fov) { fov = value; fov_rad = value * DEG_TO_RAD; @@ -106,7 +111,7 @@ double_t camera::get_pitch() { void camera::set_pitch(double_t value) { value = fmod(value, 360.0); - value = clamp(value, -89.5, 89.5); + value = clamp_def(value, -89.5, 89.5); if (pitch != value) { pitch = value; changed_view = true; @@ -173,16 +178,24 @@ void camera::set_interest(const vec3&& value) { } } -void camera::get_res(int32_t& width, int32_t& height) { - width = this->width; - height = this->height; +void camera::get_res(int32_t& render_width, int32_t& render_height, + int32_t& sprite_width, int32_t& sprite_height) { + render_width = this->render_width; + render_height = this->render_height; + sprite_width = this->sprite_width; + sprite_height = this->sprite_height; } -void camera::set_res(int32_t width, int32_t height) { - if (this->width != width || this->height != height) { - this->width = width; - this->height = height; +void camera::set_res(int32_t render_width, int32_t render_height, + int32_t sprite_width, int32_t sprite_height) { + if (this->render_width != render_width || this->render_height != render_height + || this->sprite_width != sprite_width || this->sprite_height != sprite_height) { + this->render_width = render_width; + this->render_height = render_height; + this->sprite_width = sprite_width; + this->sprite_height = sprite_height; changed_proj = true; + changed_proj_aet = true; } } @@ -215,20 +228,12 @@ void camera::reset() { void camera::move(double_t move_x, double_t move_y) { if (move_x != 0.0 || move_y != 0.0) { - vec3 temp; - vec3 view_point; - vec3 interest; vec3 up = { 0.0f, 1.0f, 0.0f }; - vec3_cross(forward, up, temp); - vec3_normalize(temp, temp); - vec3_mult_scalar(temp, (float_t)move_y, temp); - vec3_add(this->view_point, temp, view_point); - vec3_mult_scalar(forward, (float_t)move_x, temp); - vec3_add(view_point, temp, view_point); - - vec3_add(view_point, forward, interest); + vec3 view_point = this->view_point; + view_point += vec3::normalize(vec3::cross(forward, up)) * (float_t)move_y; + view_point += forward * (float_t)move_x; set_view_point(view_point); - set_interest(interest); + set_interest(view_point + forward); } } @@ -242,9 +247,7 @@ void camera::rotate(double_t rotate_x, double_t rotate_y) { if (rotate_x != 0.0 || rotate_y != 0.0) { camera_calculate_forward(this); - vec3 interest; - vec3_add(view_point, forward, interest); - set_interest(interest); + set_interest(view_point + forward); } } @@ -279,17 +282,13 @@ void camera::set(const vec3&& view_point, const vec3&& interest, } void camera::set_position(const vec3& pos) { - vec3 interest; - vec3_add(pos, forward, interest); set_view_point(pos); - set_interest(interest); + set_interest(pos + forward); } void camera::set_position(const vec3&& pos) { - vec3 interest; - vec3_add(pos, forward, interest); set_view_point(pos); - set_interest(interest); + set_interest(pos + forward); } void camera::update() { @@ -304,6 +303,9 @@ void camera::update_data() { if (changed_proj) camera_calculate_projection(this); + if (changed_proj_aet) + camera_calculate_projection_aet(this); + if (changed_view) camera_calculate_view(this); @@ -313,6 +315,7 @@ void camera::update_data() { } changed_proj = false; + changed_proj_aet = false; changed_view = false; } @@ -326,31 +329,67 @@ static void camera_calculate_projection(camera* c) { mat4_persp(c->fov_rad, c->aspect, c->min_distance, c->max_distance, &c->projection); mat4_inverse(&c->projection, &c->inv_projection); - float_t fov_correct_height = (float_t)(((double_t)c->height * 0.5) / tan(c->fov_rad * 0.5)); - float_t height = (float_t)c->height * 0.5f; - float_t width = (float_t)c->height * (float_t)c->aspect * 0.5f; + float_t fov_correct_height = (float_t)(((double_t)c->render_height * 0.5) / tan(c->fov_rad * 0.5)); + float_t height = (float_t)c->render_height * 0.5f; + float_t width = (float_t)c->render_height * (float_t)c->aspect * 0.5f; c->field_1E4.x = fov_correct_height; c->field_1E4.y = 0.0f; c->field_1E4.z = -width; - vec3_normalize(c->field_1E4, c->field_1E4); + c->field_1E4 = vec3::normalize(c->field_1E4); c->field_1F0.x = -fov_correct_height; c->field_1F0.y = 0.0f; c->field_1F0.z = -width; - vec3_normalize(c->field_1F0, c->field_1F0); + c->field_1F0 = vec3::normalize(c->field_1F0); c->field_1FC.x = 0.0f; c->field_1FC.y = fov_correct_height; c->field_1FC.z = -height; - vec3_normalize(c->field_1FC, c->field_1FC); + c->field_1FC = vec3::normalize(c->field_1FC); c->field_208.x = 0.0f; c->field_208.y = -fov_correct_height; c->field_208.z = -height; - vec3_normalize(c->field_208, c->field_208); + c->field_208 = vec3::normalize(c->field_208); +} + +static void camera_calculate_projection_aet(camera* c) { + float_t sprite_half_width = (float_t)c->sprite_width * 0.5f; + float_t sprite_half_height = (float_t)c->sprite_height * 0.5f; + float_t render_half_width = (float_t)c->render_width * 0.5f; + float_t render_half_height = (float_t)c->render_height * 0.5f; + + float_t aet_depth = sprite_half_height / (tanf(0.34557518363f) * 0.75f); + + float_t v8a = (float_t)c->min_distance / aet_depth * sprite_half_width; + float_t v8b = (float_t)c->min_distance / aet_depth * sprite_half_height; + + mat4 spr_2d_proj; + mat4_frustrum(-v8a, v8a, v8b, -v8b, c->min_distance, 3000.0, &spr_2d_proj); + + vec3 spr_2d_viewpoint = { sprite_half_width, sprite_half_height, aet_depth }; + vec3 spr_2d_interest = { sprite_half_width, sprite_half_height, 0.0f }; + vec3 spr_2d_up = { 0.0f, 1.0f, 0.0f }; + mat4 spr_2d_view; + mat4_look_at(&spr_2d_viewpoint, &spr_2d_interest, &spr_2d_up, &spr_2d_view); + + mat4_mult(&spr_2d_view, &spr_2d_proj, &c->projection_aet_2d); + + float_t v13a = (float_t)c->min_distance / aet_depth * render_half_width; + float_t v13b = (float_t)c->min_distance / aet_depth * render_half_height; + + mat4 spr_3d_proj; + mat4_frustrum(-v13a, v13a, v13b, -v13b, c->min_distance, 3000.0, &spr_3d_proj); + + vec3 spr_3d_viewpoint = { render_half_width, render_half_height, render_half_height }; + vec3 spr_3d_interest = { render_half_width, render_half_height, 0.0f }; + vec3 spr_3d_up = { 0.0f, 1.0f, 0.0f }; + mat4 spr_3d_view; + mat4_look_at(&spr_3d_viewpoint, &spr_3d_interest, &spr_3d_up, &spr_3d_view); + + mat4_mult(&spr_3d_view, &spr_3d_proj, &c->projection_aet_3d); } static void camera_calculate_view(camera* c) { - vec3 direction; - vec3_sub(c->view_point, c->interest, direction); + vec3 direction = c->view_point - c->interest; vec3 rotation; rotation.x = atan2f(-direction.y, sqrtf(direction.x * direction.x + direction.z * direction.z)); @@ -358,10 +397,9 @@ static void camera_calculate_view(camera* c) { rotation.z = (float_t)(c->roll * DEG_TO_RAD); c->rotation = rotation; - vec3_negate(rotation, rotation); + rotation = -rotation; - vec3 view_point; - vec3_negate(c->view_point, view_point); + vec3 view_point = -c->view_point; mat4_rotate_z(rotation.z, &c->view); mat4_rotate_x_mult(&c->view, rotation.x, &c->view); diff --git a/src/CRE/camera.hpp b/src/CRE/camera.hpp index 72735058..05763aae 100644 --- a/src/CRE/camera.hpp +++ b/src/CRE/camera.hpp @@ -22,12 +22,16 @@ struct camera { mat3 inv_view_mat3; mat4 view_rot; mat4 inv_view_rot; + mat4 projection_aet_2d; + mat4 projection_aet_3d; vec3 forward; vec3 rotation; vec3 view_point; vec3 interest; - int32_t width; - int32_t height; + int32_t render_width; + int32_t render_height; + int32_t sprite_width; + int32_t sprite_height; vec3 field_1E4; vec3 field_1F0; vec3 field_1FC; @@ -42,6 +46,7 @@ struct camera { double_t min_distance; bool changed_view; bool changed_proj; + bool changed_proj_aet; bool fast_change; bool fast_change_hist0; bool fast_change_hist1; @@ -49,7 +54,8 @@ struct camera { camera(); virtual ~camera(); - void initialize(double_t aspect, int32_t width, int32_t height); + void initialize(double_t aspect, int32_t render_width, int32_t render_height, + int32_t sprite_width, int32_t sprite_height); double_t get_min_distance(); void set_min_distance(double_t value); double_t get_max_distance(); @@ -70,8 +76,10 @@ struct camera { void get_interest(vec3& value); void set_interest(const vec3& value); void set_interest(const vec3&& value); - void get_res(int32_t& width, int32_t& height); - void set_res(int32_t width, int32_t height); + void get_res(int32_t& render_width, int32_t& render_height, + int32_t& sprite_width, int32_t& sprite_height); + void set_res(int32_t render_width, int32_t render_height, + int32_t sprite_width, int32_t sprite_height); void set_fast_change(bool value); void set_fast_change_hist0(bool value); void set_fast_change_hist1(bool value); diff --git a/src/CRE/data.cpp b/src/CRE/data.cpp index fc3b7ca7..e4f197a3 100644 --- a/src/CRE/data.cpp +++ b/src/CRE/data.cpp @@ -4,8 +4,9 @@ */ #include "data.hpp" +#include "../KKdLib/io/file_stream.hpp" +#include "../KKdLib/io/memory_stream.hpp" #include "../KKdLib/io/path.hpp" -#include "../KKdLib/io/stream.hpp" #include "../KKdLib/hash.hpp" #include "../KKdLib/str_utils.hpp" #include "mdata_manager.hpp" @@ -27,26 +28,30 @@ void data_struct_init() { } void data_struct_load(const char* path) { - stream s; + file_stream s; s.open(path, "rb"); - if (s.io.stream) + if (s.check_not_null()) data_load_inner(s); else { s.close(); - s.open(default_config, 7); - data_load_inner(s); + + memory_stream ms; + ms.open(default_config, 7); + data_load_inner(ms); } } void data_struct_load(const wchar_t* path) { - stream s; + file_stream s; s.open(path, L"rb"); - if (s.io.stream) + if (s.check_not_null()) data_load_inner(s); else { s.close(); - s.open(default_config, 7); - data_load_inner(s); + + memory_stream ms; + ms.open(default_config, 7); + data_load_inner(ms); } } @@ -93,6 +98,16 @@ void data_struct_load_db() { d->obj_db.add(&obj_db_file); } + for (std::string& i : prefixes) { + std::string file = i + "spr_db.bin"; + + sprite_database_file spr_db_file; + spr_db_file.modern = false; + ds->load_file(&spr_db_file, "rom/2d/", file.c_str(), + sprite_database_file::load_file); + d->spr_db.add(&spr_db_file); + } + for (std::string& i : prefixes) { std::string file = i + "stage_data.bin"; @@ -247,39 +262,22 @@ bool data_struct::check_directory_exists(const char* dir) { dir_len--; } - size_t max_len = 0; - for (data_struct_path& i : data_paths) - for (data_struct_directory& j : i.data) - if (max_len < j.path.size()) - max_len = j.path.size(); + std::string dir_temp(dir, dir_len); - char* dir_temp = force_malloc_s(char, dir_len + 1); - memcpy(dir_temp, dir, dir_len + 1); - - char* t = dir_temp; + char* t = (char*)dir_temp.c_str(); while (t = strchr(t, '/')) *t = '\\'; - char* temp = force_malloc_s(char, max_len + dir_len + 2); + std::string temp; for (data_struct_path& i : data_paths) for (data_struct_directory& j : i.data) { - const char* path = j.path.c_str(); - size_t path_len = j.path.size(); + temp.assign(j.path); + temp += '\\'; + temp.append(dir_temp); - memcpy(temp, path, path_len); - memcpy(&temp[path_len], "\\", 2); - if (dir_len) - memcpy(&temp[path_len + 1], dir_temp, dir_len + 1); - - if (path_check_directory_exists(temp)) { - free(dir_temp); - free(temp); + if (path_check_directory_exists(temp.c_str())) return true; - } } - - free(dir_temp); - free(temp); return false; } @@ -339,44 +337,24 @@ bool data_struct::check_file_exists(const char* dir, const char* file) { dir_len--; } - size_t max_len = 0; - for (data_struct_path& i : data_paths) - for (data_struct_directory& j : i.data) - if (max_len < j.path.size()) - max_len = j.path.size(); + std::string dir_temp(dir, dir_len); - char* dir_temp = force_malloc_s(char, dir_len + 1); - memcpy(dir_temp, dir, dir_len + 1); - - char* t = dir_temp; + char* t = (char*)dir_temp.c_str(); while (t = strchr(t, '/')) *t = '\\'; - char* temp = force_malloc_s(char, max_len + dir_len + file_len + 2); + std::string temp; for (data_struct_path& i : data_paths) for (data_struct_directory& j : i.data) { - const char* path = j.path.c_str(); - size_t path_len = j.path.size(); + temp.assign(j.path); + temp += '\\'; + temp.append(dir_temp); + temp.append(file, file_len); - memcpy(temp, path, path_len); - memcpy(&temp[path_len], "\\", 2); - if (dir_len) { - memcpy(&temp[path_len + 1], dir_temp, dir_len + 1); - memcpy(&temp[path_len + dir_len + 1], file, file_len + 1); - } - else - memcpy(&temp[path_len + 1], file, file_len + 1); - - if (path_check_file_exists(temp)) { - free(dir_temp); - free(temp); + if (path_check_file_exists(temp.c_str())) return true; - } } - free(dir_temp); - free(temp); - if (f2) return check_file_exists("rom/data/", file); return false; @@ -407,32 +385,20 @@ bool data_struct::check_file_exists(const char* dir, uint32_t hash) { dir_len--; } - size_t max_len = 0; - for (data_struct_path& i : data_paths) - for (data_struct_directory& j : i.data) - if (max_len < j.path.size()) - max_len = j.path.size(); + std::string dir_temp(dir, dir_len); - char* dir_temp = force_malloc_s(char, dir_len + 1); - memcpy(dir_temp, dir, dir_len + 1); - - char* t = dir_temp; + char* t = (char*)dir_temp.c_str(); while (t = strchr(t, '/')) *t = '\\'; - char* temp = force_malloc_s(char, max_len + dir_len + 2); + std::string temp; for (data_struct_path& i : data_paths) for (data_struct_directory& j : i.data) { - const char* path = j.path.c_str(); - size_t path_len = j.path.size(); + temp.assign(j.path); + temp += '\\'; + temp.append(dir_temp); - memcpy(temp, path, path_len); - memcpy(&temp[path_len], "\\", 2); - if (dir_len) - memcpy(&temp[path_len + 1], dir_temp, dir_len + 1); - - std::vector files; - path_get_files(&files, temp); + std::vector files = path_get_files(temp.c_str()); if (!files.size()) continue; @@ -449,16 +415,10 @@ bool data_struct::check_file_exists(const char* dir, uint32_t hash) { } for (uint32_t& l : files_murmurhash) - if (l == hash) { - free(dir_temp); - free(temp); + if (l == hash) return true; - } } - free(dir_temp); - free(temp); - if (f2) return check_file_exists("rom/data/", hash); return false; @@ -492,32 +452,20 @@ void data_struct::get_directory_files(const char* dir, std::vector files; - path_get_files(&files, temp); + std::vector files = path_get_files(temp.c_str()); if (!files.size()) continue; @@ -533,14 +481,11 @@ void data_struct::get_directory_files(const char* dir, std::vector files; - path_get_files(&files, temp); + std::vector files = path_get_files(temp.c_str()); if (!files.size()) continue; @@ -608,17 +541,12 @@ bool data_struct::get_file(const char* dir, uint32_t hash, const char* ext, std: t = l.c_str(); if (hash_murmurhash(t, t_len) == hash) { - file = l; - free(dir_temp); - free(temp); + file.assign(l); return true; } } } - free(dir_temp); - free(temp); - if (f2) return get_file("rom/data/", hash, ext, file); return false; @@ -682,39 +610,22 @@ bool data_struct::load_file(void* data, const char* dir, const char* file, dir_len--; } - size_t max_len = 0; - for (data_struct_path& i : data_paths) - for (data_struct_directory& j : i.data) - if (max_len < j.path.size()) - max_len = j.path.size(); + std::string dir_temp(dir, dir_len); - char* dir_temp = force_malloc_s(char, dir_len + 1); - memcpy(dir_temp, dir, dir_len + 1); - - char* t = dir_temp; + char* t = (char*)dir_temp.c_str(); while(t = strchr(t, '/')) *t = '\\'; - char* temp = force_malloc_s(char, max_len + dir_len + file_len + 2); + std::string temp; for (data_struct_path& i : data_paths) for (data_struct_directory& j : i.data) { - const char* path = j.path.c_str(); - size_t path_len = j.path.size(); + temp.assign(j.path); + temp += '\\'; + temp.append(dir_temp); + temp.append(file, file_len); - memcpy(temp, path, path_len); - memcpy(&temp[path_len], "\\", 2); - if (dir_len) { - memcpy(&temp[path_len + 1], dir_temp, dir_len + 1); - memcpy(&temp[path_len + dir_len + 1], file, file_len + 1); - } - else - memcpy(&temp[path_len + 1], file, file_len + 1); - - if (path_check_file_exists(temp)) { - if (dir_len) - temp[path_len + dir_len + 1] = 0; - else - temp[path_len + 1] = 0; + if (path_check_file_exists(temp.c_str())) { + temp.resize(temp.size() - file_len); const char* l_str = file; const char* t = strrchr(l_str, '.'); @@ -725,17 +636,11 @@ bool data_struct::load_file(void* data, const char* dir, const char* file, l_len = file_len; uint32_t h = hash_murmurhash(l_str, l_len); - if (load_func(data, temp, l_str, h)) { - free(dir_temp); - free(temp); + if (load_func(data, temp.c_str(), l_str, h)) return true; - } } } - free(dir_temp); - free(temp); - if (f2) return load_file(data, "rom/data/", file, load_func); return false; @@ -767,32 +672,20 @@ bool data_struct::load_file(void* data, const char* dir, uint32_t hash, const ch dir_len--; } - size_t max_len = 0; - for (data_struct_path& i : data_paths) - for (data_struct_directory& j : i.data) - if (max_len < j.path.size()) - max_len = j.path.size(); + std::string dir_temp(dir, dir_len); - char* dir_temp = force_malloc_s(char, dir_len + 1); - memcpy(dir_temp, dir, dir_len + 1); - - char* t = dir_temp; + char* t = (char*)dir_temp.c_str(); while (t = strchr(t, '/')) *t = '\\'; - char* temp = force_malloc_s(char, max_len + dir_len + 2); + std::string temp; for (data_struct_path& i : data_paths) for (data_struct_directory& j : i.data) { - const char* path = j.path.c_str(); - size_t path_len = j.path.size(); + temp.assign(j.path); + temp += '\\'; + temp.append(dir_temp); - memcpy(temp, path, path_len); - memcpy(&temp[path_len], "\\", 2); - if (dir_len) - memcpy(&temp[path_len + 1], dir_temp, dir_len + 1); - - std::vector files; - path_get_files(&files, temp); + std::vector files = path_get_files(temp.c_str()); if (!files.size()) continue; @@ -807,17 +700,11 @@ bool data_struct::load_file(void* data, const char* dir, uint32_t hash, const ch t = l.c_str(); if (hash_murmurhash(t, t_len) == hash - && load_func(data, temp, l.c_str(), hash)) { - free(dir_temp); - free(temp); + && load_func(data, temp.c_str(), l.c_str(), hash)) return true; - } } } - free(dir_temp); - free(temp); - if (f2) return load_file(data, "rom/data/", hash, ext, load_func); return false; @@ -918,11 +805,11 @@ static void data_load_inner(stream& s) { char* buf; char** lines; size_t count; - if (!str_utils_text_file_parse(data, length, &buf, &lines, &count)) { - free(data); + if (!str_utils_text_file_parse(data, length, buf, lines, count)) { + free_def(data); return; } - free(data); + free_def(data); for (size_t i = 0; i < count; i++) { char* s = lines[i]; @@ -1002,36 +889,15 @@ static void data_load_inner(stream& s) { count++; } - size_t max_len = 0; - t = data_paths; - for (size_t j = 0; j < count; j++) { - size_t len = utf8_length(t); - if (max_len < len) - max_len = len; - t += len + 1; - } - size_t main_rom_len = utf8_length(main_rom); size_t add_data_len = utf8_length(add_data); size_t add_data_rom_len = utf8_length(add_data_rom); - char* main_rom_path = force_malloc_s(char, max_len + main_rom_len + 3); - if (!main_rom_path) { - data_free_inner(ds); - continue; - } - - char* add_data_rom_path = force_malloc_s(char, max_len + add_data_len + 3); - if (!add_data_rom_path) { - free(main_rom_path); - data_free_inner(ds); - continue; - } + std::string main_rom_path; + std::string add_data_rom_path; ssize_t* t_len = force_malloc_s(ssize_t, count); if (!t_len) { - free(main_rom_path); - free(add_data_rom_path); data_free_inner(ds); continue; } @@ -1048,94 +914,77 @@ static void data_load_inner(stream& s) { data_path.data = {}; ds->data_paths.push_back(data_path); } - free(t_len); + free_def(t_len); for (data_struct_path& j : ds->data_paths) { const char* data_path = j.path.c_str(); size_t data_path_length = j.path.size(); if (!main_rom_len) - memcpy(main_rom_path, data_path, data_path_length); + main_rom_path.assign(j.path); else if (data_path_length) { - memcpy(main_rom_path, data_path, data_path_length); - main_rom_path[data_path_length] = '\\'; - memcpy(&main_rom_path[data_path_length + 1], main_rom, main_rom_len + 1); + main_rom_path.assign(j.path); + main_rom_path += '\\'; + main_rom_path.append(main_rom, main_rom_len); } else - memcpy(main_rom_path, main_rom, main_rom_len + 1); + main_rom_path.assign(main_rom, main_rom_len); if (!add_data_len) - memcpy(add_data_rom_path, data_path, data_path_length); + add_data_rom_path.assign(j.path); else if (data_path_length) { - memcpy(add_data_rom_path, data_path, data_path_length); - add_data_rom_path[data_path_length] = '\\'; - memcpy(&add_data_rom_path[data_path_length + 1], add_data, add_data_len + 1); + add_data_rom_path.assign(j.path); + add_data_rom_path += '\\'; + add_data_rom_path.append(add_data, add_data_len); } else - memcpy(add_data_rom_path, add_data, add_data_len + 1); + add_data_rom_path.assign(add_data, add_data_len); - size_t main_rom_path_len = utf8_length(main_rom_path); - if (main_rom_path_len && main_rom_path[main_rom_path_len - 1] == '\\') { - main_rom_path[main_rom_path_len - 1] = 0; - main_rom_path_len--; - } + if (main_rom_path.size() && main_rom_path.back() == '\\') + main_rom_path.pop_back(); - size_t add_data_rom_path_len = utf8_length(add_data_rom_path); - if (add_data_rom_path_len && add_data_rom_path[add_data_rom_path_len - 1] == '\\') { - add_data_rom_path[add_data_rom_path_len - 1] = 0; - add_data_rom_path_len--; - } + if (add_data_rom_path.size() && add_data_rom_path.back() == '\\') + add_data_rom_path.pop_back(); - std::vector data_directories; - path_get_directories(&data_directories, add_data_rom_path, &main_rom_path, 1); + const char* exclude_list[1]; + exclude_list[0] = main_rom_path.c_str(); + std::vector data_directories + = path_get_directories(add_data_rom_path.c_str(), exclude_list, 1); - max_len = 0; - for (std::string& k : data_directories) { - size_t len = k.size(); - if (max_len < len) - max_len = len; - } - - char* data_dir_path_temp = force_malloc_s(char, add_data_rom_path_len + max_len + add_data_rom_len + 3); - if (data_dir_path_temp) { + std::string data_dir_path; + if (data_directories.size()) { j.data.reserve(data_directories.size() + 1); - memcpy(data_dir_path_temp, add_data_rom_path, add_data_rom_path_len); - data_dir_path_temp[add_data_rom_path_len] = '\\'; + data_dir_path.assign(add_data_rom_path); + data_dir_path += '\\'; for (std::vector::reverse_iterator k = data_directories.rbegin(); k != data_directories.rend(); k++) { - memcpy(&data_dir_path_temp[add_data_rom_path_len + 1], k->c_str(), k->size() + 1); - if (add_data_rom_len) { - data_dir_path_temp[add_data_rom_path_len + 1 + k->size()] = '\\'; - memcpy(&data_dir_path_temp[add_data_rom_path_len + 1 + k->size() + 1], - add_data_rom, add_data_rom_len + 1); - } - data_struct_directory data_dir; - data_dir.path = data_dir_path_temp; - data_dir.name = *k; + data_dir.path.assign(data_dir_path); + data_dir.path.append(*k); + if (add_data_rom_len) { + data_dir.path += '\\'; + data_dir.path.append(add_data_rom, add_data_rom_len); + } + data_dir.name.assign(*k); j.data.push_back(data_dir); } } else j.data.reserve(1); - free(data_dir_path_temp); data_struct_directory data_dir; data_dir.path = main_rom_path; data_dir.name = {}; j.data.push_back(data_dir); - free(data_dir_path_temp); } - free(main_rom_path); - free(add_data_rom_path); ds->ready = true; } - free(buf); - free(lines); + free_def(buf); + free_def(lines); } #if defined(CRE_DEV) static void data_load_glitter_list(data_struct* ds, const char* path) { - stream s; + file_stream s; s.open(path, "rb"); size_t length = s.length; uint8_t* data = force_malloc_s(uint8_t, length); @@ -1145,7 +994,7 @@ static void data_load_glitter_list(data_struct* ds, const char* path) { char* buf; char** lines; size_t count; - if (str_utils_text_file_parse(data, length, &buf, &lines, &count)) { + if (str_utils_text_file_parse(data, length, buf, lines, count)) { for (size_t i = 0; i < count; i++) { char* t = strstr(lines[i], "#(?)"); if (t) @@ -1156,7 +1005,7 @@ static void data_load_glitter_list(data_struct* ds, const char* path) { glitter_list_names.reserve(count); for (size_t i = 0; i < count; i++) { size_t len = utf8_length(lines[i]); - std::string name = std::string(lines[i], min(len, 0x7F)); + std::string name = std::string(lines[i], min_def(len, 0x7F)); glitter_list_names.push_back(name); } @@ -1183,9 +1032,9 @@ static void data_load_glitter_list(data_struct* ds, const char* path) { break; } - free(buf); - free(lines); + free_def(buf); + free_def(lines); } - free(data); + free_def(data); } #endif diff --git a/src/CRE/data.hpp b/src/CRE/data.hpp index d3e710ff..4a668a2c 100644 --- a/src/CRE/data.hpp +++ b/src/CRE/data.hpp @@ -12,6 +12,7 @@ #include "../KKdLib/database/bone.hpp" #include "../KKdLib/database/motion.hpp" #include "../KKdLib/database/object.hpp" +#include "../KKdLib/database/sprite.hpp" #include "../KKdLib/database/stage.hpp" #include "../KKdLib/database/texture.hpp" #include "../KKdLib/vec.hpp" @@ -68,6 +69,7 @@ struct data_ft { bone_database bone_data; motion_database mot_db; object_database obj_db; + sprite_database spr_db; stage_database stage_data; texture_database tex_db; diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index a5098d3a..062939ec 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -66,8 +66,7 @@ void draw_object_draw(render_context* rctx, draw_object* draw, mat4* model, if (!show_vector) { - gl_state_bind_vertex_array(rctx->object_data.get_vertex_array( - draw->array_buffer, draw->morph_array_buffer)); + gl_state_bind_vertex_array(rctx->object_data.get_vertex_array(draw)); draw_object_func(rctx, draw); } uniform_value[U_BONE_MAT] = 0; @@ -315,20 +314,17 @@ inline void model_mat_face_camera_position(mat4* view, mat4* src, mat4* dst) { vec3 trans; mat4_get_translation(view, &trans); mat4_mult_vec3_inv_trans(view, &trans, &trans); - vec3_negate(trans, trans); + trans = -trans; - vec3 dir; - vec3_sub(trans, *(vec3*)&src->row3, dir); - vec3_normalize(dir, dir); + vec3 dir = vec3::normalize(trans - *(vec3*)&src->row3); vec3 x_rot; vec3 y_rot; vec3 z_rot; y_rot = *(vec3*)&src->row1; - vec3_cross(y_rot, dir, x_rot); - vec3_normalize(x_rot, x_rot); - vec3_cross(x_rot, y_rot, z_rot); + x_rot = vec3::normalize(vec3::cross(y_rot, dir)); + z_rot = vec3::cross(x_rot, y_rot); *(vec3*)&dst->row0 = x_rot; *(vec3*)&dst->row1 = y_rot; @@ -552,22 +548,23 @@ static void draw_object_material_set_default(render_context* rctx, draw_object* else { gl_state_active_bind_texture_2d(tex_index, tex_id); - GLenum wrap_s = 0; + GLenum wrap_s; if (texdata->attrib.m.mirror_u) wrap_s = GL_MIRRORED_REPEAT; else if (texdata->attrib.m.repeat_u) wrap_s = GL_REPEAT; + else + wrap_s = GL_CLAMP_TO_EDGE; - GLenum wrap_t = 0; + GLenum wrap_t; if (texdata->attrib.m.mirror_v) wrap_t = GL_MIRRORED_REPEAT; else if (texdata->attrib.m.repeat_v) wrap_t = GL_REPEAT; + else + wrap_t = GL_CLAMP_TO_EDGE; - if (wrap_s) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s); - if (wrap_t) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t); + texture_storage_set_texture_wrap(tex_id, wrap_s, wrap_t); } if (material->material.shader.index == SHADER_FT_SKY) { @@ -615,9 +612,8 @@ static void draw_object_material_set_default(render_context* rctx, draw_object* vec4 specular = material->material.color.specular; shaders_ft.state_material_set_specular(false, specular); - float_t luma; vec3 luma_coeff = { 0.30f, 0.59f, 0.11f }; - vec3_dot(*(vec3*)&specular, luma_coeff, luma); + float_t luma = vec3::dot(*(vec3*)&specular, luma_coeff); if (luma >= 0.0099999998f || draw->texture_color_coeff.w >= 0.1f) uniform_value[U_SPECULAR_IBL] = 1; else @@ -654,7 +650,7 @@ static void draw_object_material_set_default(render_context* rctx, draw_object* shininess = 10.0f; else { shininess = (material->material.color.shininess - 16.0f) * (float_t)(1.0 / 112.0); - shininess = max(shininess, 0.0f); + shininess = max_def(shininess, 0.0f); } shaders_ft.state_material_set_shininess(false, shininess, 0.0f, 0.0f, 1.0f); @@ -668,7 +664,7 @@ static void draw_object_material_set_default(render_context* rctx, draw_object* shaders_ft.local_vert_set(0, fresnel, 0.18f, line_light, 0.0f); shaders_ft.local_frag_set(9, fresnel, 0.18f, line_light, 0.0f); - shininess = max(material->material.color.shininess, 1.0f); + shininess = max_def(material->material.color.shininess, 1.0f); shaders_ft.local_vert_set(1, shininess, 0.0f, 0.0f, 0.0f); shaders_ft.local_frag_set(3, shininess, 0.0f, 0.0f, 0.0f); @@ -724,7 +720,7 @@ static void draw_object_material_set_parameter(render_context* rctx, obj_materia inv_bump_depth = (1.0f - bump_depth) * 256.0f + 1.0f; } - intensity = max(intensity, 1.0f); + intensity = max_def(intensity, 1.0f); shaders_ft.local_vert_set(2, inv_bump_depth, bump_depth, 0.0f, 0.0f); shaders_ft.local_frag_set(0, inv_bump_depth, bump_depth, 0.0f, 0.0f); @@ -735,7 +731,7 @@ static void draw_object_material_set_parameter(render_context* rctx, obj_materia vec4 specular; shaders_ft.env_vert_get(17, specular); - vec3_mult(*(vec3*)&specular, *(vec3*)&mat_data->material.color.specular, *(vec3*)&specular); + *(vec3*)&specular = *(vec3*)&specular * *(vec3*)&mat_data->material.color.specular; shaders_ft.env_vert_set(18, specular); } @@ -768,22 +764,23 @@ static void draw_object_material_set_reflect(render_context* rctx, draw_object* gl_state_active_bind_texture_2d(i, tex_id); - GLenum wrap_s = 0; + GLenum wrap_s; if (texdata->attrib.m.mirror_u) wrap_s = GL_MIRRORED_REPEAT; else if (texdata->attrib.m.repeat_u) wrap_s = GL_REPEAT; + else + wrap_s = GL_CLAMP_TO_EDGE; - GLenum wrap_t = 0; + GLenum wrap_t; if (texdata->attrib.m.mirror_v) wrap_t = GL_MIRRORED_REPEAT; else if (texdata->attrib.m.repeat_v) wrap_t = GL_REPEAT; + else + wrap_t = GL_CLAMP_TO_EDGE; - if (wrap_s) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s); - if (wrap_t) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t); + texture_storage_set_texture_wrap(tex_id, wrap_s, wrap_t); } vec4 ambient; @@ -940,18 +937,30 @@ static void draw_object_vertex_attrib_set_default(draw_object* draw) { if (vertex_format & OBJ_VERTEX_BONE_DATA) uniform_value[U_BONE_MAT] = 1; + else + uniform_value[U_BONE_MAT] = 0; if (draw->morph_array_buffer) { uniform_value[U_MORPH] = 1; if (vertex_format & OBJ_VERTEX_COLOR0) uniform_value[U_MORPH_COLOR] = 1; + else + uniform_value[U_MORPH_COLOR] = 0; shaders_ft.env_vert_set(13, draw->morph_value, 1.0f - draw->morph_value, 0.0f, 0.0f); } + else { + uniform_value[U_MORPH] = 0; + uniform_value[U_MORPH_COLOR] = 0; + + shaders_ft.env_vert_set(13, 0.0f, 1.0f, 0.0f, 0.0f); + } if (draw->instances_count) uniform_value[U_INSTANCE] = 1; + else + uniform_value[U_INSTANCE] = 0; } static void draw_object_vertex_attrib_set_reflect(draw_object* draw) { @@ -977,13 +986,23 @@ static void draw_object_vertex_attrib_set_reflect(draw_object* draw) { if (vertex_format & OBJ_VERTEX_BONE_DATA) uniform_value[U_BONE_MAT] = 1; + else + uniform_value[U_BONE_MAT] = 0; if (draw->morph_array_buffer) { uniform_value[U_MORPH] = 1; if (vertex_format & OBJ_VERTEX_COLOR0) uniform_value[U_MORPH_COLOR] = 1; + else + uniform_value[U_MORPH_COLOR] = 0; shaders_ft.env_vert_set(13, draw->morph_value, 1.0f - draw->morph_value, 0.0f, 0.0f); } + else { + uniform_value[U_MORPH] = 0; + uniform_value[U_MORPH_COLOR] = 0; + + shaders_ft.env_vert_set(13, 0.0f, 1.0f, 0.0f, 0.0f); + } } diff --git a/src/CRE/draw_pass.cpp b/src/CRE/draw_pass.cpp index c8f5f6ae..4cbba764 100644 --- a/src/CRE/draw_pass.cpp +++ b/src/CRE/draw_pass.cpp @@ -109,10 +109,16 @@ void draw_pass_main(render_context* rctx) { break; case DRAW_PASS_CLEAR: { rctx->post_process.rend_texture.bind(); - vec4 _clear_color; - vec4u8_to_vec4(clear_color, _clear_color); - vec4_mult_scalar(_clear_color, (float_t)(1.0 / 255.0), _clear_color); - glClearBufferfv(GL_COLOR, 0, (GLfloat*)&_clear_color); + if (set_clear_color) { + vec4 _clear_color; + vec4u8_to_vec4(clear_color, _clear_color); + _clear_color *= (float_t)(1.0 / 255.0); + glClearBufferfv(GL_COLOR, 0, (GLfloat*)&_clear_color); + } + else { + vec4 _clear_color = {}; + glClearBufferfv(GL_COLOR, 0, (GLfloat*)&_clear_color); + } //sub_140501470(rctx, &rctx->draw_pass); } break; case DRAW_PASS_PRE_SPRITE: @@ -523,11 +529,8 @@ static void draw_pass_sss_contour(render_context* rctx, post_process* pp) { camera* cam = rctx->camera; float_t v3 = 1.0f / tanf((float_t)(cam->fov_rad * 0.5)); - vec3 direction; - vec3_sub(cam->interest, cam->view_point, direction); - vec3_normalize(direction, direction); - float_t length; - vec3_length(direction, length); + vec3 direction = cam->interest - cam->view_point; + float_t length = vec3::length(direction); float_t v7 = direction.y; if (length != 0.0) v7 /= length; @@ -607,7 +610,7 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* a1) { mat4* mat = rob_chara_bone_data_get_mats_mat(v16, MOTION_BONE_N_HARA_CP); if (mat) { mat4_get_translation(mat, &chara_position[i]); - vec3_distance(view_point, chara_position[i], chara_distance[i]); + chara_distance[i] = vec3::distance(view_point, chara_position[i]); } } } @@ -620,13 +623,11 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* a1) { else closest_chara_position = chara_position[0]; - float_t length; - vec3_distance(interest, closest_chara_position, length); + float_t length = vec3::distance(interest, closest_chara_position); if (length > 1.25f) interest = chara_position[0]; - float_t v29; - vec3_distance(view_point, interest, v29); + float_t v29 = vec3::distance(view_point, interest); if (v29 < 0.25f) v29 = 0.25f; float_t v31 = tanf((float_t)(rctx->camera->fov_rad * 0.5)) * 5.0f; @@ -634,7 +635,7 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* a1) { v31 = 0.25f; float_t v32 = v31 * v29; float_t v33 = 0.6f; - float_t v34 = 1.0f / clamp(v32, 0.25f, 100.0f); + float_t v34 = 1.0f / clamp_def(v32, 0.25f, 100.0f); if (v34 < 0.145) { float_t v36 = v34 - 0.02f; if (v34 < 0.0f) @@ -718,11 +719,13 @@ static void draw_pass_reflect(render_context* rctx, draw_pass* a1) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); rctx->draw_state.shader_index = SHADER_FT_S_REFL; - bool clip_plane[4]; + light_set* set = &rctx->light_set[LIGHT_SET_MAIN]; + light_clip_plane clip_plane; set->lights[LIGHT_SPOT].get_clip_plane(clip_plane); uniform_value[U_REFLECT] = 2; - uniform_value[U_CLIP_PLANE] = clip_plane[1]; + uniform_value[U_CLIP_PLANE] = clip_plane.data[1]; + gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LEQUAL); gl_state_set_depth_mask(GL_TRUE); @@ -737,7 +740,7 @@ static void draw_pass_reflect(render_context* rctx, draw_pass* a1) { if (a1->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { uniform_value[U_REFLECT] = a1->field_31E; - uniform_value[U_CLIP_PLANE] = clip_plane[0]; + uniform_value[U_CLIP_PLANE] = clip_plane.data[0]; draw_task_draw_objects_by_type(rctx, DRAW_OBJECT_REFLECT_CHARA_OPAQUE, 0, 0, 1, -1); } gl_state_disable_depth_test(); diff --git a/src/CRE/draw_task.cpp b/src/CRE/draw_task.cpp index 4b7f4b89..b51fe128 100644 --- a/src/CRE/draw_task.cpp +++ b/src/CRE/draw_task.cpp @@ -170,7 +170,7 @@ void draw_task_draw_objects_by_type(render_context* rctx, draw_object_type type, switch (task->type) { case DRAW_TASK_OBJECT: { int32_t a = (int32_t)(task->data.object.blend_color.w * 255.0f); - a = clamp(a, 0, 255); + a = clamp_def(a, 0, 255); if (a == alpha) { draw_object_draw(rctx, &task->data.object, &task->mat, draw_object_func, show_vector); @@ -180,7 +180,7 @@ void draw_task_draw_objects_by_type(render_context* rctx, draw_object_type type, for (int32_t j = 0; j < task->data.object_translucent.count; j++) { draw_object* object = task->data.object_translucent.objects[j]; int32_t a = (int32_t)(object->blend_color.w * 255.0f); - a = clamp(a, 0, 255); + a = clamp_def(a, 0, 255); if (a == alpha) draw_object_draw(rctx, object, &task->mat, draw_object_func, show_vector); @@ -228,15 +228,16 @@ void draw_task_draw_objects_by_type_translucent(render_context* rctx, bool opaqu && draw_task_get_count(rctx, translucent) < 1) return; + post_process* pp = &rctx->post_process; + int32_t alpha_array[256]; int32_t count = draw_task_translucent_sort_count_layers(rctx, alpha_array, opaque, transparent, translucent); for (int32_t i = 0; i < count; i++) { int32_t alpha = alpha_array[i]; - fbo::blit(rctx->post_process.rend_texture.fbos[0], - rctx->post_process.alpha_layer_texture.fbos[0], - 0, 0, rctx->post_process.render_width, rctx->post_process.render_height, - 0, 0, rctx->post_process.render_width, rctx->post_process.render_height, + fbo::blit(pp->rend_texture.fbos[0], pp->alpha_layer_texture.fbos[0], + 0, 0, pp->render_width, pp->render_height, + 0, 0, pp->render_width, pp->render_height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); if (opaque_enable && draw_task_get_count(rctx, opaque)) @@ -249,17 +250,16 @@ void draw_task_draw_objects_by_type_translucent(render_context* rctx, bool opaqu gl_state_disable_blend(); } - rctx->post_process.buf_texture.bind(); - render_texture::shader_set_glsl(&rctx->post_process.alpha_layer_shader); - gl_state_active_bind_texture_2d(0, rctx->post_process.alpha_layer_texture.color_texture->tex); - gl_state_active_bind_texture_2d(1, rctx->post_process.rend_texture.color_texture->tex); + pp->buf_texture.bind(); + render_texture::shader_set_glsl(&pp->alpha_layer_shader); + gl_state_active_bind_texture_2d(0, pp->alpha_layer_texture.color_texture->tex); + gl_state_active_bind_texture_2d(1, pp->rend_texture.color_texture->tex); glUniform1f(0, (float_t)(alpha * (1.0 / 255.0))); render_texture::draw_custom_glsl(); - fbo::blit(rctx->post_process.buf_texture.fbos[0], - rctx->post_process.rend_texture.fbos[0], - 0, 0, rctx->post_process.render_width, rctx->post_process.render_height, - 0, 0, rctx->post_process.render_width, rctx->post_process.render_height, + fbo::blit(pp->buf_texture.fbos[0], pp->rend_texture.fbos[0], + 0, 0, pp->render_width, pp->render_height, + 0, 0, pp->render_width, pp->render_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } } @@ -430,7 +430,7 @@ bool draw_task_add_draw_object(render_context* rctx, obj* object, if (!has_blend_color) _blend_color = *blend_color; else - vec4_mult(_blend_color, *blend_color, _blend_color); + _blend_color *= *blend_color; } bool has_emission = false; @@ -711,7 +711,7 @@ void draw_task_add_draw_object_by_object_info_object_skin(render_context* rctx, if (texture_data && !texture_data->field_0) { vec4 value; object_data->get_texture_color_coeff(texture_color_coeff); - vec3_mult(texture_data->texture_color_coeff, *(vec3*)&texture_color_coeff, *(vec3*)&value); + *(vec3*)&value = texture_data->texture_color_coeff * *(vec3*)&texture_color_coeff; value.w = 0.0f; object_data->set_texture_color_coeff(value); @@ -721,7 +721,7 @@ void draw_task_add_draw_object_by_object_info_object_skin(render_context* rctx, object_data->set_texture_color_offset(value); object_data->get_texture_specular_coeff(texture_specular_coeff); - vec3_mult(texture_data->texture_specular_coeff, *(vec3*)&texture_specular_coeff, *(vec3*)&value); + *(vec3*)&value = texture_data->texture_specular_coeff * *(vec3*)&texture_specular_coeff; value.w = 0.0f; object_data->set_texture_specular_coeff(value); @@ -778,9 +778,9 @@ void draw_task_sort(render_context* rctx, draw_object_type type, int32_t compare for (uint32_t j = 0; j < sub_mesh->bone_indices_count; j++) { center = sub_mesh->bounding_sphere.center; mat4_mult_vec3_trans(&task->data.object.mats[j], ¢er, ¢er); - vec3_add(center_sum, center, center_sum); + center_sum += center; } - vec3_mult_scalar(center_sum, 1.0f / (float_t)sub_mesh->bone_indices_count, center); + center_sum *= 1.0f / (float_t)sub_mesh->bone_indices_count; } task->bounding_radius = task->data.object.mesh->bounding_sphere.radius; } @@ -807,33 +807,15 @@ void draw_task_sort(render_context* rctx, draw_object_type type, int32_t compare int32_t obj_axis_aligned_bounding_box_check_visibility( obj_axis_aligned_bounding_box* aabb, camera* cam, mat4* mat) { - vec3 size; vec3 points[8]; - vec3 neg; - neg = { 0.0f, 0.0f, 0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[0]); - neg = { -0.0f, -0.0f, -0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[1]); - neg = { -0.0f, 0.0f, 0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[2]); - neg = { 0.0f, -0.0f, -0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[3]); - neg = { 0.0f, -0.0f, 0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[4]); - neg = { -0.0f, 0.0f, -0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[5]); - neg = { 0.0f, 0.0f, -0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[6]); - neg = { -0.0f, -0.0f, 0.0f }; - vec3_xor(aabb->size, neg, size); - vec3_add(aabb->center, size, points[7]); + points[0] = aabb->center + (aabb->size ^ vec3( 0.0f, 0.0f, 0.0f)); + points[1] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, -0.0f)); + points[2] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, 0.0f)); + points[3] = aabb->center + (aabb->size ^ vec3( 0.0f, -0.0f, -0.0f)); + points[4] = aabb->center + (aabb->size ^ vec3( 0.0f, -0.0f, 0.0f)); + points[5] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, -0.0f)); + points[6] = aabb->center + (aabb->size ^ vec3( 0.0f, 0.0f, -0.0f)); + points[7] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, 0.0f)); mat4 view_mat; mat4_mult(mat, &cam->view, &view_mat); @@ -856,9 +838,7 @@ int32_t obj_axis_aligned_bounding_box_check_visibility( for (int32_t i = 0; i < 6; i++) for (int32_t j = 0; j < 8; j++) { - float_t v34 = 0.0f; - vec3_dot(*(vec3*)&v2[i], points[j], v34); - v34 += v2[i].w; + float_t v34 = vec3::dot(*(vec3*)&v2[i], points[j]) + v2[i].w; if (v34 > 0.0f) break; @@ -883,23 +863,19 @@ int32_t object_bounding_sphere_check_visibility(obj_bounding_sphere* sphere, if (-cam->min_distance < min_depth || -cam->max_distance > max_depth) return 0; - float_t v5; - vec3_dot(cam->field_1E4, center, v5); + float_t v5 = vec3::dot(cam->field_1E4, center); if (v5 < -radius) return 0; - float_t v6; - vec3_dot(cam->field_1F0, center, v6); + float_t v6 = vec3::dot(cam->field_1F0, center); if (v6 < -radius) return 0; - float_t v7; - vec3_dot(cam->field_1FC, center, v7); + float_t v7 = vec3::dot(cam->field_1FC, center); if (v7 < -radius) return 0; - float_t v8; - vec3_dot(cam->field_208, center, v8); + float_t v8 = vec3::dot(cam->field_208, center); if (v8 < -radius) return 0; @@ -1018,7 +994,7 @@ inline static void draw_task_translucent_sort_has_objects(render_context* rctx, continue; int32_t alpha = (int32_t)(task->data.object.blend_color.w * 255.0f); - alpha = clamp(alpha, 0, 255); + alpha = clamp_def(alpha, 0, 255); arr[alpha] = true; } } diff --git a/src/CRE/fbo.cpp b/src/CRE/fbo.cpp index 8d270b71..9f664a4b 100644 --- a/src/CRE/fbo.cpp +++ b/src/CRE/fbo.cpp @@ -26,7 +26,7 @@ void fbo::init_data(int32_t width, int32_t height, textures = 0; } - count = min(count, 8); + count = min_def(count, 8); this->width = width; this->height = height; diff --git a/src/CRE/file_handler.cpp b/src/CRE/file_handler.cpp index bfc6a77b..b054a684 100644 --- a/src/CRE/file_handler.cpp +++ b/src/CRE/file_handler.cpp @@ -4,6 +4,7 @@ */ #include +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/hash.hpp" #include "file_handler.hpp" #include "data.hpp" @@ -56,42 +57,50 @@ reading(), cache(), callback(), size(), data(), ds() { } file_handler::~file_handler() { - free(data); + if (data) { + free(data); + data = 0; + } } void file_handler::call_callback(int32_t index) { if (index >= 2) return; - std::unique_lock u_lock(mtx); - const void* data = this->data; - void(*callback_func)(void*, const void*, size_t) = this->callback[index].func; - void* callback_data = this->callback[index].data; - bool ready = this->callback[index].ready; - this->callback[index].ready = true; - u_lock.unlock(); + const void* data = 0; + size_t size = 0; + void(*callback_func)(void*, const void*, size_t) = 0; + void* callback_data = 0; + bool ready = false; + + { + std::unique_lock u_lock(mtx); + data = this->data; + size = this->size; + callback_func = this->callback[index].func; + callback_data = this->callback[index].data; + ready = this->callback[index].ready; + this->callback[index].ready = true; + } if (!ready && callback_func) - callback_func(callback_data, data, this->size); + callback_func(callback_data, data, size); } void file_handler::set_file(const char* file) { std::unique_lock u_lock(mtx); - this->file = file; - u_lock.unlock(); + this->file.assign(file); } void file_handler::set_farc_file(const char* farc_file, bool cache) { std::unique_lock u_lock(mtx); - this->farc_file = farc_file; + this->farc_file.assign(farc_file); this->cache = cache; - u_lock.unlock(); } void file_handler::set_dir(const char* dir) { std::unique_lock u_lock(mtx); - this->dir = dir; - u_lock.unlock(); + this->dir.assign(dir); } void file_handler::set_callback_data(int32_t index, PFNFILEHANDLERCALLBACK* func, void* data) { @@ -101,20 +110,21 @@ void file_handler::set_callback_data(int32_t index, PFNFILEHANDLERCALLBACK* func callback[index].data = data; callback[index].ready = false; } - u_lock.unlock(); } void file_handler::free_data_lock() { - std::unique_lock u_lock(mtx); - if (count > 0) { - count--; - bool free_fhndl = count == 0; - u_lock.unlock(); - if (free_fhndl) - delete this; + bool free_fhndl = false; + + { + std::unique_lock u_lock(mtx); + if (count <= 0) + return; + + free_fhndl = --count == 0; } - else - u_lock.unlock(); + + if (free_fhndl) + delete this; } farc_read_handler::farc_read_handler() : cache(), farc() { @@ -159,8 +169,8 @@ bool farc_read_handler::read_data(void* data, size_t size, std::string& file) { if (farc) { farc_file* ff = farc->read_file(file.c_str()); if (ff) { - memcpy(data, ff->data, min(size, ff->size)); - if (!cache) { + memcpy(data, ff->data, min_def(size, ff->size)); + if (!cache && ff->data) { free(ff->data); ff->data = 0; } @@ -191,27 +201,30 @@ void file_handler_storage_init() { void file_handler_storage_ctrl() { file_handler_storage_ctrl_list(); - std::unique_lock u_lock(file_handler_storage_data->mtx); - if (!file_handler_storage_data->deque.size()) { - for (file_handler*& i : file_handler_storage_data->list) - if (i->not_ready && !i->reading) { - std::unique_lock u_lock(i->mtx); - i->count++; - u_lock.unlock(); - file_handler_storage_data->deque.push_back(i); - } + { + std::unique_lock u_lock(file_handler_storage_data->mtx); + if (!file_handler_storage_data->deque.size()) { + for (file_handler*& i : file_handler_storage_data->list) + if (i->not_ready && !i->reading) { + { + std::unique_lock u_lock(i->mtx); + i->count++; + } + file_handler_storage_data->deque.push_back(i); + } - if (file_handler_storage_data->deque.size()) - file_handler_storage_data->cnd.notify_all(); + if (file_handler_storage_data->deque.size()) + file_handler_storage_data->cnd.notify_all(); + } } - u_lock.unlock(); } void file_handler_storage_free() { - std::unique_lock u_lock(file_handler_storage_data->mtx); - file_handler_storage_data->exit = true; - file_handler_storage_data->cnd.notify_one(); - u_lock.unlock(); + { + std::unique_lock u_lock(file_handler_storage_data->mtx); + file_handler_storage_data->exit = true; + file_handler_storage_data->cnd.notify_one(); + } file_handler_storage_data->thread->join(); delete file_handler_storage_data->thread; @@ -233,11 +246,13 @@ static bool file_handler_load_file(void* data, const char* dir, const char* file if (!fhndl->data) return false; - stream s; + file_stream s; s.open(file_path.c_str(), "rb"); - bool ret = s.io.stream && s.read(fhndl->data, fhndl->size); - if (!ret) + bool ret = s.check_not_null() && s.read(fhndl->data, fhndl->size); + if (!ret && fhndl->data) { free(fhndl->data); + fhndl->data = 0; + } return ret; } @@ -266,14 +281,14 @@ static bool file_handler_load_farc_file(void* data, const char* dir, const char* fhndl->size = 1; fhndl->data = malloc(fhndl->size); - if (fhndl->data && farc_read_hndl->read_data(fhndl->data, fhndl->size, fhndl->file)) { - u_lock.unlock(); + if (fhndl->data && farc_read_hndl->read_data(fhndl->data, fhndl->size, fhndl->file)) return true; - } } - free(fhndl->data); - u_lock.unlock(); + if (fhndl->data) { + free(fhndl->data); + fhndl->data = 0; + } return false; } @@ -313,14 +328,12 @@ static void file_handler_storage_thread_ctrl() { i->dir.c_str(), i->file.c_str(), file_handler_load_file); } i->reading = false; - u_lock.unlock(); } i->free_data_lock(); } file_handler_storage_data->deque.clear(); } file_handler_storage_data->exit = false; - u_lock.unlock(); } p_file_handler::p_file_handler() { @@ -355,10 +368,12 @@ void p_file_handler::free_data() { if (!ptr) return; - std::unique_lock u_lock(ptr->mtx); - for (int32_t i = 0; i < 2; i++) - ptr->callback[i] = {}; - u_lock.unlock(); + { + std::unique_lock u_lock(ptr->mtx); + for (int32_t i = 0; i < 2; i++) + ptr->callback[i] = {}; + } + ptr->free_data_lock(); ptr = 0; } @@ -410,18 +425,21 @@ bool p_file_handler::read_file(void* data, const char* dir, ptr->ds = data; - std::unique_lock u_lock(ptr->mtx); - ptr->count++; - u_lock.unlock(); + { + std::unique_lock u_lock(ptr->mtx); + ptr->count++; + } ptr->set_dir(dir); if (farc_file) ptr->set_farc_file(farc_file, cache); ptr->set_file(file); - std::unique_lock u_lock1(ptr->mtx); - ptr->count++; - u_lock1.unlock(); + { + std::unique_lock u_lock(ptr->mtx); + ptr->count++; + } + file_handler_storage_data->list.push_back(ptr); return true; } @@ -450,16 +468,19 @@ bool p_file_handler::read_file(void* data, const char* dir, uint32_t hash, const ptr->ds = data; - std::unique_lock u_lock(ptr->mtx); - ptr->count++; - u_lock.unlock(); + { + std::unique_lock u_lock(ptr->mtx); + ptr->count++; + } ptr->set_dir(dir); ptr->set_file(file.c_str()); - std::unique_lock u_lock1(ptr->mtx); - ptr->count++; - u_lock1.unlock(); + { + std::unique_lock u_lock(ptr->mtx); + ptr->count++; + } + file_handler_storage_data->list.push_back(ptr); return true; } @@ -485,7 +506,6 @@ void p_file_handler::read_now() { ptr->not_ready = false; } ptr->reading = false; - u_lock.unlock(); } file_handler_storage_ctrl_list(); diff --git a/src/CRE/item_table.cpp b/src/CRE/item_table.cpp index 6c22991b..8e7d17ea 100644 --- a/src/CRE/item_table.cpp +++ b/src/CRE/item_table.cpp @@ -3,6 +3,7 @@ GitHub/GitLab: korenkonder */ +#include "../KKdLib/io/memory_stream.hpp" #include "../KKdLib/io/path.hpp" #include "../KKdLib/str_utils.hpp" #include "data.hpp" @@ -72,6 +73,19 @@ item_table_item_data_obj::item_table_item_data_obj() : rpk() { } +item_table_item_data_ofs::item_table_item_data_ofs() : sub_id(), no() { + +} + +item_table_item_data_tex::item_table_item_data_tex() { + org = -1; + chg = -1; +} + +item_table_item_data_col::item_table_item_data_col() : flag() { + tex_id = -1; +} + item_table_item_data::item_table_item_data() { } @@ -111,7 +125,7 @@ static bool item_table_array_read(data_struct* data, const char* path) { char* path_farc = str_utils_add(path, ".farc"); if (!path_check_file_exists(path_farc)) { - free(path_farc); + free_def(path_farc); return false; } @@ -155,7 +169,7 @@ static bool item_table_array_read(data_struct* data, const char* path) { farc_file* ff = f.read_file(file); if (ff) { - stream s; + memory_stream s; s.open(ff->data, ff->size); itm_table itm; itm.read(ff->data, ff->size); @@ -163,7 +177,7 @@ static bool item_table_array_read(data_struct* data, const char* path) { item_table_load(data, &item_table_array[i], &itm); } } - free(path_farc); + free_def(path_farc); return true; } diff --git a/src/CRE/item_table.hpp b/src/CRE/item_table.hpp index 590a3906..e2938872 100644 --- a/src/CRE/item_table.hpp +++ b/src/CRE/item_table.hpp @@ -24,17 +24,23 @@ struct item_table_item_data_ofs { vec3 position; vec3 rotation; vec3 scale; + + item_table_item_data_ofs(); }; struct item_table_item_data_tex { uint32_t org; uint32_t chg; + + item_table_item_data_tex(); }; struct item_table_item_data_col { uint32_t tex_id; int32_t flag; color_tone col_tone; + + item_table_item_data_col(); }; struct item_table_item_data { diff --git a/src/CRE/light_param.cpp b/src/CRE/light_param.cpp index a309b0c2..3b860155 100644 --- a/src/CRE/light_param.cpp +++ b/src/CRE/light_param.cpp @@ -70,6 +70,14 @@ void light_param_data_storage_data_init() { light_param_data_storage_data = new light_param_data_storage; } +int32_t light_param_data_storage_data_get_pv_id() { + return light_param_data_storage_data->pv_id; +} + +int32_t light_param_data_storage_data_get_stage_index() { + return light_param_data_storage_data->stage_index; +} + void light_param_data_storage_data_free_file_handlers() { light_param_storage_free_file_handlers(light_param_data_storage_data); } @@ -226,7 +234,7 @@ static void light_param_data_get_stage_name_string(std::string* str, int32_t sta s[length] = '\0'; *str = std::string(s, length); - free(s); + free_def(s); } static void light_param_data_get_stage_name_string(std::string* str, @@ -267,7 +275,7 @@ static void light_param_data_get_stage_name_string(std::string* str, s[length] = '\0'; *str = std::string(s, length); - free(s); + free_def(s); } static int32_t light_param_data_load_file(light_param_data* a1, p_file_handler* a2) { @@ -318,27 +326,27 @@ static void light_param_data_load_file_pv_cut(std::map 6 && name[5] == '_') { + if (!strncmp(name, "light", min_def(name_len, 5)) && name_len > 6 && name[5] == '_') { type = 1; name += 6; name_len -= 6; } - else if (!strncmp(name, "fog", min(name_len, 3)) && name_len > 4 && name[3] == '_') { + else if (!strncmp(name, "fog", min_def(name_len, 3)) && name_len > 4 && name[3] == '_') { type = 2; name += 4; name_len -= 4; } - else if (!strncmp(name, "glow", min(name_len, 4)) && name_len > 5 && name[4] == '_') { + else if (!strncmp(name, "glow", min_def(name_len, 4)) && name_len > 5 && name[4] == '_') { type = 3; name += 5; name_len -= 5; } - else if (!strncmp(name, "wind", min(name_len, 4)) && name_len > 5 && name[4] == '_') { + else if (!strncmp(name, "wind", min_def(name_len, 4)) && name_len > 5 && name[4] == '_') { type = 4; name += 5; name_len -= 5; } - else if (!strncmp(name, "face", min(name_len, 4)) && name_len > 5 && name[4] == '_') { + else if (!strncmp(name, "face", min_def(name_len, 4)) && name_len > 5 && name[4] == '_') { type = 5; name += 5; name_len -= 5; @@ -576,7 +584,7 @@ static void light_param_storage_load_stages(light_param_data_storage* a1, continue; size_t name_len = name.size(); - if (!strncmp(name.c_str(), "pv0", min(name_len, 3))) + if (!strncmp(name.c_str(), "pv0", min_def(name_len, 3))) name[2] = '8'; std::map::iterator elem = a1->stage.find(i); diff --git a/src/CRE/light_param.hpp b/src/CRE/light_param.hpp index cba27fb4..76871fe8 100644 --- a/src/CRE/light_param.hpp +++ b/src/CRE/light_param.hpp @@ -69,6 +69,8 @@ struct light_param_data_storage { extern void light_param_data_storage_data_init(); extern void light_param_data_storage_data_free_file_handlers(); +extern int32_t light_param_data_storage_data_get_pv_id(); +extern int32_t light_param_data_storage_data_get_stage_index(); extern int32_t light_param_data_storage_data_load_file(); extern void light_param_data_storage_data_load_stage(int32_t stage_index); extern void light_param_data_storage_data_load_stage(uint32_t stage_hash, stage_database* stage_data); diff --git a/src/CRE/light_param/fog.cpp b/src/CRE/light_param/fog.cpp index 64ce4e71..fc9e04f3 100644 --- a/src/CRE/light_param/fog.cpp +++ b/src/CRE/light_param/fog.cpp @@ -91,8 +91,7 @@ void fog::data_set(fog_id id) { shaders_ft.env_vert_set(29, color); shaders_ft.env_frag_set(4, color); - vec4_mult_scalar(color, (float_t)(1.0 / 8.0), color); - shaders_ft.state_fog_set_color(color); + shaders_ft.state_fog_set_color(color * (float_t)(1.0 / 8.0)); shaders_ft.state_fog_set_params(params); } break; case FOG_HEIGHT: { diff --git a/src/CRE/light_param/light.cpp b/src/CRE/light_param/light.cpp index c8af70a5..5aef63e9 100644 --- a/src/CRE/light_param/light.cpp +++ b/src/CRE/light_param/light.cpp @@ -13,8 +13,8 @@ extern vec4 npr_spec_color; static void light_get_direction_from_position(vec4* pos_dir, light_data* light, bool force); light_data::light_data() : type(), ambient(), diffuse(), specular(), position(), -spot_direction(), spot_exponent(), spot_cutoff(), constant(), linear(), quadratic(), -ibl_specular(), ibl_back(), ibl_direction(), tone_curve(),clip_plane() { +spot_direction(), spot_exponent(), spot_cutoff(), attenuation(), +ibl_specular(), ibl_back(), ibl_direction(), tone_curve(), clip_plane() { set_type(LIGHT_OFF); set_ambient({ 0.0f, 0.0, 0.0f, 1.0f }); set_diffuse({ 1.0f, 1.0, 1.0f, 0.0f }); @@ -207,45 +207,39 @@ void light_data::set_spot_cutoff(float_t value) { } float_t light_data::get_constant() { - return constant; + return attenuation.constant; } void light_data::set_constant(float_t value) { - constant = value; + attenuation.constant = value; } float_t light_data::get_linear() { - return linear; + return attenuation.linear; } void light_data::set_linear(float_t value) { - linear = value; + attenuation.linear = value; } float_t light_data::get_quadratic() { - return quadratic; + return attenuation.quadratic; } void light_data::set_quadratic(float_t value) { - quadratic = value; + attenuation.quadratic = value; } -void light_data::get_attenuation(vec3& value) { - value.x = constant; - value.y = linear; - value.z = quadratic; +void light_data::get_attenuation(light_attenuation& value) { + value = attenuation; } -void light_data::set_attenuation(const vec3& value) { - constant = value.x; - linear = value.y; - quadratic = value.z; +void light_data::set_attenuation(const light_attenuation& value) { + attenuation = value; } -void light_data::set_attenuation(const vec3&& value) { - constant = value.x; - linear = value.y; - quadratic = value.z; +void light_data::set_attenuation(const light_attenuation&& value) { + attenuation = value; } void light_data::get_ibl_specular(vec4& value) { @@ -284,30 +278,28 @@ void light_data::set_ibl_direction(const vec4&& value) { ibl_direction = value; } -void light_data::get_tone_curve(vec3& value) { +void light_data::get_tone_curve(light_tone_curve& value) { value = tone_curve; } -void light_data::set_tone_curve(const vec3& value) { +void light_data::set_tone_curve(const light_tone_curve& value) { tone_curve = value; } -void light_data::set_tone_curve(const vec3&& value) { +void light_data::set_tone_curve(const light_tone_curve&& value) { tone_curve = value; } -void light_data::get_clip_plane(bool value[4]) { - value[0] = clip_plane[0]; - value[1] = clip_plane[1]; - value[2] = clip_plane[2]; - value[3] = clip_plane[3]; +void light_data::get_clip_plane(light_clip_plane& value) { + value = clip_plane; } -void light_data::set_clip_plane(const bool value[4]) { - clip_plane[0] = value[0]; - clip_plane[1] = value[1]; - clip_plane[2] = value[2]; - clip_plane[3] = value[3]; +void light_data::set_clip_plane(const light_clip_plane& value) { + clip_plane = value; +} + +void light_data::set_clip_plane(const light_clip_plane&& value) { + clip_plane = value; } void light_set::get_ambient_intensity(vec4& value) { @@ -364,8 +356,9 @@ void light_set::data_set(face& face, light_set_id id) { light_get_direction_from_position(&light_position, 0, true); shaders_ft.state_light_set_position(i, light_position); + light_attenuation attenuation = light->attenuation; shaders_ft.state_light_set_attenuation(i, - light->constant, light->linear, light->quadratic, light->spot_exponent); + attenuation.constant, attenuation.linear, attenuation.quadratic, light->spot_exponent); vec3 spot_direction = light->spot_direction; shaders_ft.state_light_set_spot_direction(i, @@ -393,21 +386,19 @@ void light_set::data_set(face& face, light_set_id id) { shaders_ft.env_vert_set(5, position); shaders_ft.env_frag_set(5, position); - vec4_mult(diffuse, ibl_specular, temp); + temp = diffuse * ibl_specular; shaders_ft.env_vert_set(6, temp); shaders_ft.env_frag_set(6, temp); - vec4_mult(specular, ibl_specular, temp); - vec4_mult_scalar(temp, spec_coef, temp); + temp = specular * ibl_specular * spec_coef; shaders_ft.env_vert_set(7, temp); shaders_ft.env_frag_set(7, temp); - vec4_mult_scalar(ibl_specular, luce_coef, temp); + temp = ibl_specular * luce_coef; shaders_ft.env_vert_set(8, temp); shaders_ft.env_frag_set(8, temp); - vec4_mult(specular, ibl_back, temp); - vec4_mult_scalar(temp, spec_coef, temp); + temp = specular * ibl_back * spec_coef; shaders_ft.env_vert_set(9, temp); shaders_ft.env_frag_set(9, temp); @@ -420,12 +411,11 @@ void light_set::data_set(face& face, light_set_id id) { shaders_ft.env_vert_set(10, position); shaders_ft.env_frag_set(14, position); - vec4_mult(diffuse, ibl_specular, temp); + temp = diffuse * ibl_specular; shaders_ft.env_vert_set(11, temp); shaders_ft.env_frag_set(16, temp); - vec4_mult(specular, ibl_specular, temp); - vec4_mult_scalar(temp, spec_coef, temp); + temp = specular * ibl_specular * spec_coef; shaders_ft.env_vert_set(12, temp); shaders_ft.env_frag_set(17, temp); @@ -439,7 +429,7 @@ void light_set::data_set(face& face, light_set_id id) { float_t offset = face.get_offset(); float_t v28 = (float_t)(1.0 - exp(offset * -0.44999999)) * 2.0f; - offset = max(offset, 0.0f); + offset = max_def(offset, 0.0f); shaders_ft.env_vert_set(0x11, v28 * 0.1f, offset * 0.06f, 1.0, 1.0); if (lights[LIGHT_CHARA_COLOR].get_type() == LIGHT_PARALLEL) { @@ -466,19 +456,20 @@ void light_set::data_set(face& face, light_set_id id) { lights[LIGHT_TONE_CURVE].get_diffuse(diffuse); lights[LIGHT_TONE_CURVE].get_specular(specular); - vec3 tone_curve; + light_tone_curve tone_curve; lights[LIGHT_TONE_CURVE].get_tone_curve(tone_curve); - tone_curve.y = min(tone_curve.y, 1.0f) - tone_curve.x; - if (tone_curve.y > 0.0f) - tone_curve.y = 1.0f / tone_curve.y; + tone_curve.end_point = min_def(tone_curve.end_point, 1.0f) - tone_curve.start_point; + if (tone_curve.end_point > 0.0f) + tone_curve.end_point = 1.0f / tone_curve.end_point; else - tone_curve.y = 0.0f; + tone_curve.end_point = 0.0f; shaders_ft.env_frag_set(36, position); shaders_ft.env_frag_set(37, ambient); shaders_ft.env_frag_set(38, diffuse); shaders_ft.env_frag_set(39, specular); - shaders_ft.env_frag_set(40, tone_curve.x, tone_curve.y, tone_curve.z, 0.0f); + shaders_ft.env_frag_set(40, tone_curve.start_point, + tone_curve.end_point, tone_curve.coefficient, 0.0f); } else { uniform_value[U_TONE_CURVE] = 0; @@ -493,10 +484,9 @@ void light_set::data_set(face& face, light_set_id id) { if (fabs(position.x) <= 0.000001f && fabs(position.z) <= 0.000001f && fabs(position.z) <= 0.000001f) position = { 0.0f, 1.0f, 0.0f, 1.0f }; else { - float_t length; - vec3_length(*(vec3*)&position, length); + float_t length = vec3::length(*(vec3*)&position); if (length != 0.0f) - vec3_mult_scalar(*(vec3*)&position, 1.0f / length, *(vec3*)&position); + *(vec3*)&position = *(vec3*)&position * (1.0f / length); } shaders_ft.env_vert_set(15, position.x, position.y, position.z, 1.0f); @@ -505,11 +495,10 @@ void light_set::data_set(face& face, light_set_id id) { if (lights[LIGHT_REFLECT].get_type() == LIGHT_SPOT) { vec4 spot_direction; lights[LIGHT_REFLECT].get_spot_direction(*(vec3*)&spot_direction); - vec3_negate(*(vec3*)&spot_direction, *(vec3*)&spot_direction); + *(vec3*)&spot_direction = -*(vec3*)&spot_direction; light_get_direction_from_position(&spot_direction, &lights[LIGHT_REFLECT], true); lights[LIGHT_REFLECT].get_position(position); - vec3_dot(*(vec3*)&position, *(vec3*)&spot_direction, spot_direction.w); - spot_direction.w = -spot_direction.w; + spot_direction.w = -vec3::dot(*(vec3*)&position, *(vec3*)&spot_direction); shaders_ft.env_vert_set(28, spot_direction); shaders_ft.env_frag_set(22, spot_direction); @@ -529,27 +518,22 @@ void light_set::data_set(face& face, light_set_id id) { lights[LIGHT_CHARA].get_ibl_direction(ibl_direction); lights[LIGHT_CHARA].get_position(position); - float_t length; - vec3_length(*(vec3*)&ibl_direction, length); + float_t length = vec3::length(*(vec3*)&ibl_direction); if (length >= 0.000001f) { - vec3_mult_scalar(*(vec3*)&ibl_direction, 1.0f / length, *(vec3*)&ibl_direction); + *(vec3*)&ibl_direction = *(vec3*)&ibl_direction * (1.0f / length); - vec3_length(*(vec3*)&position, length); + length = vec3::length(*(vec3*)&position); if (length >= 0.000001f) { - vec3_mult_scalar(*(vec3*)&position, 1.0f / length, *(vec3*)&position); + *(vec3*)&position = *(vec3*)&position * (1.0f / length); - vec3 axis; - vec3_cross(*(vec3*)&ibl_direction, *(vec3*)&position, axis) - - vec3_length(axis, length); - - float_t v52; - vec3_dot(*(vec3*)&position, *(vec3*)&ibl_direction, v52); + vec3 axis = vec3::cross(*(vec3*)&ibl_direction, *(vec3*)&position); + length = vec3::length(axis); + float_t v52 = vec3::dot(*(vec3*)&position, *(vec3*)&ibl_direction); float_t angle = fabsf(atan2f(length, v52)); if (angle >= 0.01f && angle <= 3.131592653589793f) { if (length != 0.0f) - vec3_mult_scalar(axis, 1.0f / length, axis); + axis *= 1.0f / length; mat4_from_axis_angle(&axis, -angle, &v63); mat4_from_axis_angle(&axis, -angle, &v64); @@ -566,12 +550,11 @@ void light_set::data_set(face& face, light_set_id id) { static void light_get_direction_from_position(vec4* pos_dir, light_data* light, bool force) { if (force || light->get_type() == LIGHT_PARALLEL) { - float_t length; - vec3_length(*(vec3*)pos_dir, length); + float_t length = vec3::length(*(vec3*)pos_dir); if (length <= 0.000001) *(vec3*)pos_dir = { 0.0f, 1.0f, 0.0f }; else - vec3_mult_scalar(*(vec3*)pos_dir, 1.0f / length, *(vec3*)pos_dir); + *(vec3*)pos_dir = *(vec3*)pos_dir * (1.0f / length); pos_dir->w = 0.0f; } } diff --git a/src/CRE/light_param/light.hpp b/src/CRE/light_param/light.hpp index e103da5c..1505cdcd 100644 --- a/src/CRE/light_param/light.hpp +++ b/src/CRE/light_param/light.hpp @@ -20,14 +20,12 @@ struct light_data { vec3 spot_direction; float_t spot_exponent; float_t spot_cutoff; - float_t constant; - float_t linear; - float_t quadratic; + light_attenuation attenuation; vec4 ibl_specular; vec4 ibl_back; vec4 ibl_direction; - vec3 tone_curve; - bool clip_plane[4]; + light_tone_curve tone_curve; + light_clip_plane clip_plane; light_data(); @@ -67,9 +65,9 @@ struct light_data { void set_linear(float_t value); float_t get_quadratic(); void set_quadratic(float_t value); - void get_attenuation(vec3& value); - void set_attenuation(const vec3& value); - void set_attenuation(const vec3&& value); + void get_attenuation(light_attenuation& value); + void set_attenuation(const light_attenuation& value); + void set_attenuation(const light_attenuation&& value); void get_ibl_specular(vec4& value); void set_ibl_specular(const vec4& value); void set_ibl_specular(const vec4&& value); @@ -79,11 +77,12 @@ struct light_data { void get_ibl_direction(vec4& value); void set_ibl_direction(const vec4& value); void set_ibl_direction(const vec4&& value); - void get_tone_curve(vec3& value); - void set_tone_curve(const vec3& value); - void set_tone_curve(const vec3&& value); - void get_clip_plane(bool value[4]); - void set_clip_plane(const bool value[4]); + void get_tone_curve(light_tone_curve& value); + void set_tone_curve(const light_tone_curve& value); + void set_tone_curve(const light_tone_curve&& value); + void get_clip_plane(light_clip_plane& value); + void set_clip_plane(const light_clip_plane& value); + void set_clip_plane(const light_clip_plane&& value); }; struct light_set { diff --git a/src/CRE/light_param/wind.cpp b/src/CRE/light_param/wind.cpp index 60c323dd..b696f03c 100644 --- a/src/CRE/light_param/wind.cpp +++ b/src/CRE/light_param/wind.cpp @@ -95,7 +95,7 @@ static void wind_ctrl(wind* w) { vec3 wind_direction = vec3_null; wind_direction.x = value; mat4_mult_vec3(&mat, &wind_direction, &wind_direction); - vec3_mult_scalar(wind_direction, w->strength, w->wind_direction); + w->wind_direction = wind_direction * w->strength; if (w->strength >= 1.0f) w->strength = 1.0f; else diff --git a/src/CRE/lock.cpp b/src/CRE/lock.cpp index f1f5397d..1422d62f 100644 --- a/src/CRE/lock.cpp +++ b/src/CRE/lock.cpp @@ -4,17 +4,3 @@ */ #include "lock.hpp" - -inline void lock_init(lock* l) { - l->init = InitializeCriticalSectionAndSpinCount(&l->cs, 0); -} - -inline bool lock_check_init(lock* l) { - return l->init; -} - -inline void lock_free(lock* l) { - if (l->init) - DeleteCriticalSection(&l->cs); - l->init = FALSE; -} diff --git a/src/CRE/lock.hpp b/src/CRE/lock.hpp index e36dd723..dd4166a4 100644 --- a/src/CRE/lock.hpp +++ b/src/CRE/lock.hpp @@ -10,12 +10,49 @@ struct lock { CRITICAL_SECTION cs; bool init; + + inline lock() : cs() { + init = InitializeCriticalSectionAndSpinCount(&cs, 0); + } + + inline ~lock() { + if (init) + DeleteCriticalSection(&cs); + cs = {}; + init = false; + } + + inline bool check_init() { + if (!this) + return false; + return init; + } }; -struct lock_data { - lock* lock; - void* lock_data; - void(*lock_free)(void* data); +struct lock_uint32_t { +private: + volatile uint32_t value; + +public: + inline lock_uint32_t() { + _InterlockedExchange(&value, 0); + } + + inline uint32_t get() { + _m_prefetchw(&value); + int32_t v3 = value; + while (true) { + int32_t v4 = v3; + v3 = _InterlockedCompareExchange(&value, v3, v3); + if (v4 == v3) + break; + } + return v3; + } + + inline void set(uint32_t value) { + _InterlockedExchange(&this->value, value); + } }; #define lock_lock(val) \ @@ -28,7 +65,3 @@ if ((val) && (val)->init && TryEnterCriticalSection(&(val)->cs)) { #define lock_unlock(val) \ LeaveCriticalSection(&(val)->cs); \ } - -extern void lock_init(lock* l); -extern bool lock_check_init(lock* l); -extern void lock_free(lock* l); diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index ee8f298c..9c308a00 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -10,6 +10,7 @@ #include "data.hpp" #include "gl_state.hpp" #include "shader_ft.hpp" +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/io/json.hpp" #include "../KKdLib/io/path.hpp" #include "../KKdLib/dds.hpp" @@ -97,7 +98,7 @@ bool obj_mesh_index_buffer::load(obj_mesh& mesh) { } bool ret = load_data((size_t)indices_count * sizeof(uint16_t), indices); - free(indices); + free_def(indices); return ret; } @@ -146,54 +147,6 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { if (!mesh.num_vertex || !mesh.vertex) return false; - { - const vec4 attib_default = { 0.0f, 0.0f, 0.0f, 1.0f }; - - obj_vertex_format vertex_format = mesh.vertex_format; - obj_vertex_data* vertex_file = mesh.vertex; - int32_t num_vertex = mesh.num_vertex; - obj_vertex_format _vertex_format = vertex_format; - enum_and(_vertex_format, ~(OBJ_VERTEX_TEXCOORD0 | OBJ_VERTEX_TEXCOORD1 | OBJ_VERTEX_TEXCOORD2 - | OBJ_VERTEX_TEXCOORD3 | OBJ_VERTEX_COLOR0 | OBJ_VERTEX_COLOR1 | OBJ_VERTEX_BONE_DATA | OBJ_VERTEX_UNKNOWN)); - for (int32_t i = 0; i < num_vertex && _vertex_format != vertex_format; i++) { - if (~_vertex_format & OBJ_VERTEX_TEXCOORD0 && vertex_format & OBJ_VERTEX_TEXCOORD0 - && memcmp(&vertex_file[i].texcoord0, &vec2_null, sizeof(vec2))) - enum_or(_vertex_format, OBJ_VERTEX_TEXCOORD0); - - if (~_vertex_format & OBJ_VERTEX_TEXCOORD1 && vertex_format & OBJ_VERTEX_TEXCOORD1 - && memcmp(&vertex_file[i].texcoord1, &vec2_null, sizeof(vec2))) - enum_or(_vertex_format, OBJ_VERTEX_TEXCOORD1); - - if (~_vertex_format & OBJ_VERTEX_TEXCOORD2 && vertex_format & OBJ_VERTEX_TEXCOORD2 - && memcmp(&vertex_file[i].texcoord2, &vec2_null, sizeof(vec2))) - enum_or(_vertex_format, OBJ_VERTEX_TEXCOORD2); - - if (~_vertex_format & OBJ_VERTEX_TEXCOORD3 && vertex_format & OBJ_VERTEX_TEXCOORD3 - && memcmp(&vertex_file[i].texcoord3, &vec2_null, sizeof(vec2))) - enum_or(_vertex_format, OBJ_VERTEX_TEXCOORD3); - - if (~_vertex_format & OBJ_VERTEX_COLOR0 && vertex_format & OBJ_VERTEX_COLOR0 - && memcmp(&vertex_file[i].color0, &vec4_identity, sizeof(vec4))) - enum_or(_vertex_format, OBJ_VERTEX_COLOR0); - - if (~_vertex_format & OBJ_VERTEX_COLOR1 && vertex_format & OBJ_VERTEX_COLOR1 - && memcmp(&vertex_file[i].color1, &vec4_identity, sizeof(vec4))) - enum_or(_vertex_format, OBJ_VERTEX_COLOR1); - - if (~_vertex_format & OBJ_VERTEX_BONE_DATA && vertex_format & OBJ_VERTEX_BONE_DATA - && memcmp(&vertex_file[i].bone_index, &vec4i_null, sizeof(vec4i)) - && memcmp(&vertex_file[i].bone_weight, &vec4_null, sizeof(vec4))) - enum_or(_vertex_format, OBJ_VERTEX_BONE_DATA); - - if (~_vertex_format & OBJ_VERTEX_UNKNOWN && vertex_format & OBJ_VERTEX_UNKNOWN - && memcmp(&vertex_file[i].unknown, &attib_default, sizeof(vec4))) - enum_or(_vertex_format, OBJ_VERTEX_UNKNOWN); - } - - if (mesh.vertex_format != _vertex_format) - mesh.vertex_format = _vertex_format; - } - size_t size_vertex; if (!mesh.attrib.m.compressed) size_vertex = obj_vertex_format_get_vertex_size(mesh.vertex_format); @@ -279,16 +232,14 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { } if (vertex_format & OBJ_VERTEX_NORMAL) { - vec3 normal; - vec3_mult_scalar(vertex_file[i].normal, 32727.0f, normal); + vec3 normal = vertex_file[i].normal * 32727.0f; vec3_to_vec3i16(normal, *(vec3i16*)d); *(int16_t*)(d + 6) = 0; d += 8; } if (vertex_format & OBJ_VERTEX_TANGENT) { - vec4 tangent = vertex_file[i].tangent; - vec4_mult_scalar(tangent, 32727.0f, tangent); + vec4 tangent = vertex_file[i].tangent * 32727.0f; vec4_to_vec4i16(tangent, *(vec4i16*)d); d += 8; } @@ -320,8 +271,7 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { } if (vertex_format & OBJ_VERTEX_BONE_DATA) { - vec4 bone_weight = vertex_file[i].bone_weight; - vec4_mult_scalar(bone_weight, 65535.0f, bone_weight); + vec4 bone_weight = vertex_file[i].bone_weight * 65535.0f; vec4_to_vec4u16(bone_weight, *(vec4u16*)d); d += 8; @@ -335,7 +285,7 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { mesh.size_vertex = (int32_t)size_vertex; bool ret = load_data(size_vertex * mesh.num_vertex, vertex, mesh.attrib.m.double_buffer ? 2 : 1); - free(vertex); + free_def(vertex); return ret; } @@ -426,7 +376,7 @@ index_buffer_num(), index_buffer_data(), load_count(), modern() { obj_set_handler::~obj_set_handler() { for (uint32_t i = 0; i < tex_num; i++) texture_free(tex_data[i]); - free(tex_data); + free_def(tex_data); obj_set_handler_index_buffer_free(this); obj_set_handler_vertex_buffer_free(this); @@ -534,7 +484,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, msgpack msg; - stream s; + file_stream s; s.open(buf, "rb"); io_json_read(s, &msg); s.close(); @@ -542,7 +492,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, if (msg.type != MSGPACK_ARRAY) return; - msgpack_array* ptr = MSGPACK_SELECT(msgpack_array, msg); + msgpack_array* ptr = msg.data.arr; for (msgpack& i : *ptr) { msgpack& object = i; @@ -555,9 +505,9 @@ void object_material_msgpack_read(const char* path, const char* set_name, if (name_hash != hash_string_murmurhash(obj.name)) continue; - msgpack* materials = object.read("material"); + msgpack* materials = object.read_array("material"); if (materials) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, materials); + msgpack_array* ptr = materials->data.arr; for (msgpack& j : *ptr) { msgpack& material = j; @@ -594,7 +544,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, msgpack* _shader_name = material.read("shader_name"); if (_shader_name) { std::string shader_name = _shader_name->read_string(); - size_t name_length = min(sizeof(mat.shader.name) - 1, shader_name.size()); + size_t name_length = min_def(sizeof(mat.shader.name) - 1, shader_name.size()); memcpy_s(mat.shader.name, sizeof(mat.shader.name) - 1, shader_name.c_str(), name_length); mat.shader.name[name_length] = 0; } @@ -669,7 +619,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, msgpack* _ex_shader = material.read("ex_shader"); if (_ex_shader) { std::string shader_name = _ex_shader->read_string(); - size_t name_length = min(sizeof(l.ex_shader) - 1, shader_name.size()); + size_t name_length = min_def(sizeof(l.ex_shader) - 1, shader_name.size()); memcpy_s(l.ex_shader, sizeof(l.ex_shader) - 1, shader_name.c_str(), name_length); l.ex_shader[name_length] = 0; } @@ -678,13 +628,13 @@ void object_material_msgpack_read(const char* path, const char* set_name, if (weight) l.weight = weight->read_float_t(); - msgpack* tex_coord_mat = tex->read("tex_coord_mat"); + msgpack* tex_coord_mat = tex->read_array("tex_coord_mat"); if (tex_coord_mat) { - msgpack_array* tex_coord_mat_ptr = MSGPACK_SELECT_PTR(msgpack_array, tex_coord_mat); + msgpack_array* tex_coord_mat_ptr = tex_coord_mat->data.arr; { msgpack& row0 = tex_coord_mat_ptr->data()[0]; - msgpack_array* row0_ptr = MSGPACK_SELECT(msgpack_array, row0); + msgpack_array* row0_ptr = row0.data.arr; l.tex_coord_mat.row0.x = row0_ptr->data()[0].read_float_t(); l.tex_coord_mat.row0.y = row0_ptr->data()[1].read_float_t(); l.tex_coord_mat.row0.z = row0_ptr->data()[2].read_float_t(); @@ -693,7 +643,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, { msgpack& row1 = tex_coord_mat_ptr->data()[1]; - msgpack_array* row1_ptr = MSGPACK_SELECT(msgpack_array, row1); + msgpack_array* row1_ptr = row1.data.arr; l.tex_coord_mat.row1.x = row1_ptr->data()[0].read_float_t(); l.tex_coord_mat.row1.y = row1_ptr->data()[1].read_float_t(); l.tex_coord_mat.row1.z = row1_ptr->data()[2].read_float_t(); @@ -702,7 +652,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, { msgpack& row2 = tex_coord_mat_ptr->data()[2]; - msgpack_array* row2_ptr = MSGPACK_SELECT(msgpack_array, row2); + msgpack_array* row2_ptr = row2.data.arr; l.tex_coord_mat.row2.x = row2_ptr->data()[0].read_float_t(); l.tex_coord_mat.row2.y = row2_ptr->data()[1].read_float_t(); l.tex_coord_mat.row2.z = row2_ptr->data()[2].read_float_t(); @@ -711,7 +661,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, { msgpack& row3 = tex_coord_mat_ptr->data()[3]; - msgpack_array* row3_ptr = MSGPACK_SELECT(msgpack_array, row3); + msgpack_array* row3_ptr = row3.data.arr; l.tex_coord_mat.row3.x = row3_ptr->data()[0].read_float_t(); l.tex_coord_mat.row3.y = row3_ptr->data()[1].read_float_t(); l.tex_coord_mat.row3.z = row3_ptr->data()[2].read_float_t(); @@ -719,9 +669,9 @@ void object_material_msgpack_read(const char* path, const char* set_name, } } - msgpack* reserved = tex->read("reserved"); + msgpack* reserved = tex->read_array("reserved"); if (reserved) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, reserved); + msgpack_array* ptr = reserved->data.arr; for (int32_t m = 0; m < 8; m++) l.reserved[m] = ptr->data()[m].read_uint32_t(); } @@ -811,9 +761,9 @@ void object_material_msgpack_read(const char* path, const char* set_name, if (bump_depth) mat.radius = bump_depth->read_float_t(); - msgpack* reserved = material.read("reserved"); + msgpack* reserved = material.read_array("reserved"); if (reserved) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, reserved); + msgpack_array* ptr = reserved->data.arr; for (int32_t m = 0; m < 15; m++) mat.reserved[m] = ptr->data()[m].read_uint32_t(); } @@ -822,9 +772,9 @@ void object_material_msgpack_read(const char* path, const char* set_name, } } - msgpack* meshes = object.read("mesh"); + msgpack* meshes = object.read_array("mesh"); if (meshes) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, meshes); + msgpack_array* ptr = meshes->data.arr; for (msgpack& j : *ptr) { msgpack& _mesh = j; @@ -837,8 +787,11 @@ void object_material_msgpack_read(const char* path, const char* set_name, if (name_hash != hash_string_murmurhash(mesh.name)) continue; - msgpack* sub_meshes = _mesh.read("sub_mesh"); - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, sub_meshes); + msgpack* sub_meshes = _mesh.read_array("sub_mesh"); + if (!sub_meshes) + continue; + + msgpack_array* ptr = sub_meshes->data.arr; for (size_t l = 0; l < mesh.num_submesh; l++) { obj_sub_mesh& sub_mesh = mesh.submesh_array[l]; msgpack& _sub_mesh = ptr->data()[l]; @@ -884,10 +837,10 @@ void object_material_msgpack_read(const char* path, const char* set_name, sprintf_s(buf, sizeof(buf), "%s\\%s\\config_tex.json", path, set_name_buf); if (!path_check_file_exists(buf)) return; - + msgpack msg; - stream s; + file_stream s; s.open(buf, "rb"); io_json_read(s, &msg); s.close(); @@ -895,10 +848,10 @@ void object_material_msgpack_read(const char* path, const char* set_name, if (msg.type != MSGPACK_MAP) return; - msgpack* add = msg.read("Add"); + msgpack* add = msg.read_array("Add"); if (add) { std::vector ids; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, add); + msgpack_array* ptr = add->data.arr; for (msgpack& i : *ptr) { std::string name = i.read_string(); if (!name.size()) @@ -934,8 +887,8 @@ void object_material_msgpack_read(const char* path, const char* set_name, do for (uint32_t i = 0; i < tex->mipmaps_count; i++) { txp_mipmap tex_mip; - tex_mip.width = max(d.width >> i, 1); - tex_mip.height = max(d.height >> i, 1); + tex_mip.width = max_def(d.width >> i, 1); + tex_mip.height = max_def(d.height >> i, 1); tex_mip.format = d.format; uint32_t size = txp::get_size(tex_mip.format, tex_mip.width, tex_mip.height); @@ -954,7 +907,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, if (set->tex_id_num != tex_id_num) { uint32_t* tex_id_data = force_malloc_s(uint32_t, tex_id_num); memmove(tex_id_data, set->tex_id_data, sizeof(uint32_t) * set->tex_id_num); - free(set->tex_id_data); + free_def(set->tex_id_data); memmove(&tex_id_data[set->tex_id_num], ids.data(), sizeof(uint32_t) * (tex_id_num - set->tex_id_num)); @@ -965,9 +918,9 @@ void object_material_msgpack_read(const char* path, const char* set_name, } - msgpack* replace = msg.read("Replace"); + msgpack* replace = msg.read_array("Replace"); if (replace) { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, replace); + msgpack_array* ptr = replace->data.arr; for (msgpack& i : *ptr) { std::string name = i.read_string(); if (!name.size()) @@ -1005,8 +958,8 @@ void object_material_msgpack_read(const char* path, const char* set_name, do for (uint32_t i = 0; i < tex->mipmaps_count; i++) { txp_mipmap tex_mip; - tex_mip.width = max(d.width >> i, 1); - tex_mip.height = max(d.height >> i, 1); + tex_mip.width = max_def(d.width >> i, 1); + tex_mip.height = max_def(d.height >> i, 1); tex_mip.format = d.format; uint32_t size = txp::get_size(tex_mip.format, tex_mip.width, tex_mip.height); @@ -1031,290 +984,282 @@ void object_material_msgpack_write(const char* path, const char* set_name, uint3 if (!path_check_directory_exists(buf) && !CreateDirectoryA(buf, 0)) return; - msgpack_array objects; - objects.resize(obj_set->obj_num); + msgpack_array objects(obj_set->obj_num); for (uint32_t i = 0; i < obj_set->obj_num; i++) { obj& obj = obj_set->obj_data[i]; msgpack& object = objects.data()[i]; - object = msgpack(0, false, 0); - object.append(msgpack("name", obj.name)); - object.append(msgpack("material", true, obj.num_material)); - object.append(msgpack("mesh", true, obj.num_mesh)); + object = msgpack(msgpack_map()); + object.append("name", obj.name); - msgpack* materials = object.get_by_name("material"); - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, materials); - for (size_t j = 0; j < obj.num_material; j++) { - obj_material& mat = obj.material_array[j].material; - msgpack& material = ptr->data()[j]; - material = msgpack(0, false, 0); + msgpack* materials = object.append("material", msgpack_array()); + if (materials) { + msgpack_array* ptr = materials->data.arr; + ptr->resize(obj.num_material); + for (size_t j = 0; j < obj.num_material; j++) { + obj_material& mat = obj.material_array[j].material; + msgpack& material = ptr->data()[j]; + material = msgpack_map(); - { - msgpack shader_compo = msgpack("shader_compo", false, 0); - shader_compo.append({ "color", (bool)mat.shader_compo.m.color }); - shader_compo.append({ "color_a", (bool)mat.shader_compo.m.color_a }); - shader_compo.append({ "color_l1", (bool)mat.shader_compo.m.color_l1 }); - shader_compo.append({ "color_l1_a", (bool)mat.shader_compo.m.color_l1_a }); - shader_compo.append({ "color_l2", (bool)mat.shader_compo.m.color_l2 }); - shader_compo.append({ "color_l2_a", (bool)mat.shader_compo.m.color_l2_a }); - shader_compo.append({ "transparency", (bool)mat.shader_compo.m.transparency }); - shader_compo.append({ "specular", (bool)mat.shader_compo.m.specular }); - shader_compo.append({ "normal_01", (bool)mat.shader_compo.m.normal_01 }); - shader_compo.append({ "normal_02", (bool)mat.shader_compo.m.normal_02 }); - shader_compo.append({ "envmap", (bool)mat.shader_compo.m.envmap }); - shader_compo.append({ "color_l3", (bool)mat.shader_compo.m.color_l3 }); - shader_compo.append({ "color_l3_a", (bool)mat.shader_compo.m.color_l3_a }); - shader_compo.append({ "translucency", (bool)mat.shader_compo.m.translucency }); - shader_compo.append({ "flag_14", (bool)mat.shader_compo.m.flag_14 }); - shader_compo.append({ "override_ibl", (bool)mat.shader_compo.m.override_ibl }); - shader_compo.append({ "dummy", mat.shader_compo.m.dummy }); - material.append(shader_compo); - } + msgpack* shader_compo = material.append("shader_compo", msgpack_map()); + if (shader_compo) { + shader_compo->append("color", (bool)mat.shader_compo.m.color); + shader_compo->append("color_a", (bool)mat.shader_compo.m.color_a); + shader_compo->append("color_l1", (bool)mat.shader_compo.m.color_l1); + shader_compo->append("color_l1_a", (bool)mat.shader_compo.m.color_l1_a); + shader_compo->append("color_l2", (bool)mat.shader_compo.m.color_l2); + shader_compo->append("color_l2_a", (bool)mat.shader_compo.m.color_l2_a); + shader_compo->append("transparency", (bool)mat.shader_compo.m.transparency); + shader_compo->append("specular", (bool)mat.shader_compo.m.specular); + shader_compo->append("normal_01", (bool)mat.shader_compo.m.normal_01); + shader_compo->append("normal_02", (bool)mat.shader_compo.m.normal_02); + shader_compo->append("envmap", (bool)mat.shader_compo.m.envmap); + shader_compo->append("color_l3", (bool)mat.shader_compo.m.color_l3); + shader_compo->append("color_l3_a", (bool)mat.shader_compo.m.color_l3_a); + shader_compo->append("translucency", (bool)mat.shader_compo.m.translucency); + shader_compo->append("flag_14", (bool)mat.shader_compo.m.flag_14); + shader_compo->append("override_ibl", (bool)mat.shader_compo.m.override_ibl); + shader_compo->append("dummy", mat.shader_compo.m.dummy); + } - material.append({ "shader_name", mat.shader.name }); + material.append("shader_name", mat.shader.name); - { - msgpack shader_info = msgpack("shader_info", false, 0); - shader_info.append({ "vtx_trans_type", mat.shader_info.m.vtx_trans_type }); - shader_info.append({ "col_src", mat.shader_info.m.col_src }); - shader_info.append({ "is_lgt_diffuse", (bool)mat.shader_info.m.is_lgt_diffuse }); - shader_info.append({ "is_lgt_specular", (bool)mat.shader_info.m.is_lgt_specular }); - shader_info.append({ "is_lgt_per_pixel",(bool)mat.shader_info.m.is_lgt_per_pixel }); - shader_info.append({ "is_lgt_double", (bool)mat.shader_info.m.is_lgt_double }); - shader_info.append({ "bump_map_type", mat.shader_info.m.bump_map_type }); - shader_info.append({ "fresnel_type", mat.shader_info.m.fresnel_type }); - shader_info.append({ "line_light", mat.shader_info.m.line_light }); - shader_info.append({ "recieve_shadow", (bool)mat.shader_info.m.recieve_shadow }); - shader_info.append({ "cast_shadow", (bool)mat.shader_info.m.cast_shadow }); - shader_info.append({ "specular_quality", mat.shader_info.m.specular_quality }); - shader_info.append({ "aniso_direction", mat.shader_info.m.aniso_direction }); - shader_info.append({ "dummy", mat.shader_info.m.dummy }); - material.append(shader_info); - } + msgpack* shader_info = material.append("shader_info", msgpack_map()); + if (shader_info) { + shader_info->append("vtx_trans_type", mat.shader_info.m.vtx_trans_type); + shader_info->append("col_src", mat.shader_info.m.col_src); + shader_info->append("is_lgt_diffuse", (bool)mat.shader_info.m.is_lgt_diffuse); + shader_info->append("is_lgt_specular", (bool)mat.shader_info.m.is_lgt_specular); + shader_info->append("is_lgt_per_pixel", (bool)mat.shader_info.m.is_lgt_per_pixel); + shader_info->append("is_lgt_double", (bool)mat.shader_info.m.is_lgt_double); + shader_info->append("bump_map_type", mat.shader_info.m.bump_map_type); + shader_info->append("fresnel_type", mat.shader_info.m.fresnel_type); + shader_info->append("line_light", mat.shader_info.m.line_light); + shader_info->append("recieve_shadow", (bool)mat.shader_info.m.recieve_shadow); + shader_info->append("cast_shadow", (bool)mat.shader_info.m.cast_shadow); + shader_info->append("specular_quality", mat.shader_info.m.specular_quality); + shader_info->append("aniso_direction", mat.shader_info.m.aniso_direction); + shader_info->append("dummy", mat.shader_info.m.dummy); + } - { - msgpack texdata = msgpack("texdata", false, 0); - for (obj_material_texture_data& k : mat.texdata) { - if (!k.tex_index || k.tex_index == -1 - || k.tex_index == hash_murmurhash_empty || k.tex_index == hash_murmurhash_null) - continue; + msgpack* texdata = material.append("texdata", msgpack_map()); + if (texdata) { + for (obj_material_texture_data& k : mat.texdata) { + if (!k.tex_index || k.tex_index == -1 + || k.tex_index == hash_murmurhash_empty || k.tex_index == hash_murmurhash_null) + continue; - sprintf_s(buf, sizeof(buf), "%d", (int32_t)(&k - mat.texdata)); - msgpack tex = msgpack(buf, false, 0); + sprintf_s(buf, sizeof(buf), "%d", (int32_t)(&k - mat.texdata)); + msgpack& tex = *texdata->append(buf, msgpack_map()); - { - msgpack attrib = msgpack("attrib", false, 0); - attrib.append({ "repeat_u", (bool)k.attrib.m.repeat_u }); - attrib.append({ "repeat_v", (bool)k.attrib.m.repeat_v }); - attrib.append({ "mirror_u", (bool)k.attrib.m.mirror_u }); - attrib.append({ "mirror_v", (bool)k.attrib.m.mirror_v }); - attrib.append({ "ignore_alpha", (bool)k.attrib.m.ignore_alpha }); - attrib.append({ "blend", k.attrib.m.blend }); - attrib.append({ "alpha_blend", k.attrib.m.alpha_blend }); - attrib.append({ "border", (bool)k.attrib.m.border }); - attrib.append({ "clamp2edge", (bool)k.attrib.m.clamp2edge }); - attrib.append({ "filter", k.attrib.m.filter }); - attrib.append({ "mipmap", k.attrib.m.mipmap }); - attrib.append({ "mipmap_bias", k.attrib.m.mipmap_bias }); - attrib.append({ "flag_29", (bool)k.attrib.m.flag_29 }); - attrib.append({ "anisotropic_filter", k.attrib.m.anisotropic_filter }); - tex.append(attrib); - } - - tex.append({ "tex_name", tex_db->get_texture_name(k.tex_index) }); - - { - msgpack shader_info = msgpack("shader_info", false, 0); - shader_info.append({ "tex_type", k.shader_info.m.tex_type }); - shader_info.append({ "uv_idx", k.shader_info.m.uv_idx }); - shader_info.append({ "texcoord_trans", k.shader_info.m.texcoord_trans }); - shader_info.append({ "dummy", k.shader_info.m.dummy }); - tex.append(shader_info); - } - - tex.append({ "ex_shader", k.ex_shader }); - tex.append({ "weight", k.weight }); - - { - msgpack tex_coord_mat = msgpack("tex_coord_mat", true, 4); - msgpack_array* tex_coord_mat_ptr = MSGPACK_SELECT(msgpack_array, tex_coord_mat); - - { - msgpack& row0 = tex_coord_mat_ptr->data()[0]; - row0 = msgpack(0, true, 4); - msgpack_array* row0_ptr = MSGPACK_SELECT(msgpack_array, row0); - row0_ptr->data()[0] = { 0, k.tex_coord_mat.row0.x }; - row0_ptr->data()[1] = { 0, k.tex_coord_mat.row0.y }; - row0_ptr->data()[2] = { 0, k.tex_coord_mat.row0.z }; - row0_ptr->data()[3] = { 0, k.tex_coord_mat.row0.w }; + msgpack* attrib = tex.append("attrib", msgpack_map()); + if (attrib) { + attrib->append("repeat_u", (bool)k.attrib.m.repeat_u); + attrib->append("repeat_v", (bool)k.attrib.m.repeat_v); + attrib->append("mirror_u", (bool)k.attrib.m.mirror_u); + attrib->append("mirror_v", (bool)k.attrib.m.mirror_v); + attrib->append("ignore_alpha", (bool)k.attrib.m.ignore_alpha); + attrib->append("blend", k.attrib.m.blend); + attrib->append("alpha_blend", k.attrib.m.alpha_blend); + attrib->append("border", (bool)k.attrib.m.border); + attrib->append("clamp2edge", (bool)k.attrib.m.clamp2edge); + attrib->append("filter", k.attrib.m.filter); + attrib->append("mipmap", k.attrib.m.mipmap); + attrib->append("mipmap_bias", k.attrib.m.mipmap_bias); + attrib->append("flag_29", (bool)k.attrib.m.flag_29); + attrib->append("anisotropic_filter", k.attrib.m.anisotropic_filter); } - { - msgpack& row1 = tex_coord_mat_ptr->data()[1]; - row1 = msgpack(0, true, 4); - msgpack_array* row1_ptr = MSGPACK_SELECT(msgpack_array, row1); - row1_ptr->data()[0] = { 0, k.tex_coord_mat.row1.x }; - row1_ptr->data()[1] = { 0, k.tex_coord_mat.row1.y }; - row1_ptr->data()[2] = { 0, k.tex_coord_mat.row1.z }; - row1_ptr->data()[3] = { 0, k.tex_coord_mat.row1.w }; + tex.append("tex_name", tex_db->get_texture_name(k.tex_index)); + + msgpack* shader_info = tex.append("shader_info", msgpack_map()); + if (shader_info) { + shader_info->append("tex_type", k.shader_info.m.tex_type); + shader_info->append("uv_idx", k.shader_info.m.uv_idx); + shader_info->append("texcoord_trans", k.shader_info.m.texcoord_trans); + shader_info->append("dummy", k.shader_info.m.dummy); } - { - msgpack& row2 = tex_coord_mat_ptr->data()[2]; - row2 = msgpack(0, true, 4); - msgpack_array* row2_ptr = MSGPACK_SELECT(msgpack_array, row2); - row2_ptr->data()[0] = { 0, k.tex_coord_mat.row2.x }; - row2_ptr->data()[1] = { 0, k.tex_coord_mat.row2.y }; - row2_ptr->data()[2] = { 0, k.tex_coord_mat.row2.z }; - row2_ptr->data()[3] = { 0, k.tex_coord_mat.row2.w }; + tex.append("ex_shader", k.ex_shader); + tex.append("weight", k.weight); + + msgpack* tex_coord_mat = tex.append("tex_coord_mat", msgpack_array()); + if (tex_coord_mat) { + msgpack_array* tex_coord_mat_ptr = tex_coord_mat->data.arr; + tex_coord_mat_ptr->resize(4); + + { + msgpack& row0 = tex_coord_mat_ptr->data()[0]; + row0 = msgpack_array(); + msgpack_array* row0_ptr = row0.data.arr; + row0_ptr->resize(4); + row0_ptr->data()[0] = k.tex_coord_mat.row0.x; + row0_ptr->data()[1] = k.tex_coord_mat.row0.y; + row0_ptr->data()[2] = k.tex_coord_mat.row0.z; + row0_ptr->data()[3] = k.tex_coord_mat.row0.w; + } + + { + msgpack& row1 = tex_coord_mat_ptr->data()[1]; + row1 = msgpack_array(); + msgpack_array* row1_ptr = row1.data.arr; + row1_ptr->resize(4); + row1_ptr->data()[0] = k.tex_coord_mat.row1.x; + row1_ptr->data()[1] = k.tex_coord_mat.row1.y; + row1_ptr->data()[2] = k.tex_coord_mat.row1.z; + row1_ptr->data()[3] = k.tex_coord_mat.row1.w; + } + + { + msgpack& row2 = tex_coord_mat_ptr->data()[2]; + row2 = msgpack_array(); + msgpack_array* row2_ptr = row2.data.arr; + row2_ptr->resize(4); + row2_ptr->data()[0] = k.tex_coord_mat.row2.x; + row2_ptr->data()[1] = k.tex_coord_mat.row2.y; + row2_ptr->data()[2] = k.tex_coord_mat.row2.z; + row2_ptr->data()[3] = k.tex_coord_mat.row2.w; + } + + { + msgpack& row3 = tex_coord_mat_ptr->data()[3]; + row3 = msgpack_array(); + msgpack_array* row3_ptr = row3.data.arr; + row3_ptr->resize(4); + row3_ptr->data()[0] = k.tex_coord_mat.row3.x; + row3_ptr->data()[1] = k.tex_coord_mat.row3.y; + row3_ptr->data()[2] = k.tex_coord_mat.row3.z; + row3_ptr->data()[3] = k.tex_coord_mat.row3.w; + } } - { - msgpack& row3 = tex_coord_mat_ptr->data()[3]; - row3 = msgpack(0, true, 4); - msgpack_array* row3_ptr = MSGPACK_SELECT(msgpack_array, row3); - row3_ptr->data()[0] = { 0, k.tex_coord_mat.row3.x }; - row3_ptr->data()[1] = { 0, k.tex_coord_mat.row3.y }; - row3_ptr->data()[2] = { 0, k.tex_coord_mat.row3.z }; - row3_ptr->data()[3] = { 0, k.tex_coord_mat.row3.w }; + msgpack* reserved = tex.append("reserved", msgpack_array()); + if (reserved) { + msgpack_array* ptr = reserved->data.arr; + ptr->resize(8); + for (int32_t l = 0; l < 8; l++) + ptr->data()[l] = k.reserved[l]; } + } + } - tex.append(tex_coord_mat); + msgpack* attrib = material.append("attrib", msgpack_map()); + if (attrib) { + attrib->append("alpha_texture", (bool)mat.attrib.m.alpha_texture); + attrib->append("alpha_material", (bool)mat.attrib.m.alpha_material); + attrib->append("punch_through", (bool)mat.attrib.m.punch_through); + attrib->append("double_sided", (bool)mat.attrib.m.double_sided); + attrib->append("normal_dir_light", (bool)mat.attrib.m.normal_dir_light); + attrib->append("src_blend_factor", mat.attrib.m.src_blend_factor); + attrib->append("dst_blend_factor", mat.attrib.m.dst_blend_factor); + attrib->append("blend_operation", mat.attrib.m.blend_operation); + attrib->append("zbias", mat.attrib.m.zbias); + attrib->append("no_fog", (bool)mat.attrib.m.no_fog); + attrib->append("translucent_priority", mat.attrib.m.translucent_priority); + attrib->append("has_fog_height", (bool)mat.attrib.m.has_fog_height); + attrib->append("flag_28", (bool)mat.attrib.m.flag_28); + attrib->append("fog_height", (bool)mat.attrib.m.fog_height); + attrib->append("flag_30", (bool)mat.attrib.m.flag_30); + attrib->append("flag_31", (bool)mat.attrib.m.flag_31); + } + + msgpack* color = material.append("color", msgpack_map()); + if (color) { + msgpack* diffuse = color->append("diffuse", msgpack_map()); + if (diffuse) { + diffuse->append("r", mat.color.diffuse.x); + diffuse->append("g", mat.color.diffuse.y); + diffuse->append("b", mat.color.diffuse.z); + diffuse->append("a", mat.color.diffuse.w); } - { - msgpack reserved = msgpack("reserved", true, 8); - msgpack_array* ptr = MSGPACK_SELECT(msgpack_array, reserved); - for (int32_t l = 0; l < 8; l++) - ptr->data()[l] = { 0, k.reserved[l] }; - tex.append(reserved); + msgpack* ambient = color->append("ambient", msgpack_map()); + if (ambient) { + ambient->append("r", mat.color.ambient.x); + ambient->append("g", mat.color.ambient.y); + ambient->append("b", mat.color.ambient.z); + ambient->append("a", mat.color.ambient.w); } - texdata.append(tex); + msgpack* specular = color->append("specular", msgpack_map()); + if (specular) { + specular->append("r", mat.color.specular.x); + specular->append("g", mat.color.specular.y); + specular->append("b", mat.color.specular.z); + specular->append("a", mat.color.specular.w); + } + + msgpack* emission = color->append("emission", msgpack_map()); + if (emission) { + emission->append("r", mat.color.emission.x); + emission->append("g", mat.color.emission.y); + emission->append("b", mat.color.emission.z); + emission->append("a", mat.color.emission.w); + } + + color->append("shininess", mat.color.shininess); + color->append("intensity", mat.color.intensity); + } - material.append(texdata); - } - - { - msgpack attrib = msgpack("attrib", false, 0); - attrib.append({ "alpha_texture", (bool)mat.attrib.m.alpha_texture }); - attrib.append({ "alpha_material", (bool)mat.attrib.m.alpha_material }); - attrib.append({ "punch_through", (bool)mat.attrib.m.punch_through }); - attrib.append({ "double_sided", (bool)mat.attrib.m.double_sided }); - attrib.append({ "normal_dir_light", (bool)mat.attrib.m.normal_dir_light }); - attrib.append({ "src_blend_factor", mat.attrib.m.src_blend_factor }); - attrib.append({ "dst_blend_factor", mat.attrib.m.dst_blend_factor }); - attrib.append({ "blend_operation", mat.attrib.m.blend_operation }); - attrib.append({ "zbias", mat.attrib.m.zbias }); - attrib.append({ "no_fog", (bool)mat.attrib.m.no_fog }); - attrib.append({ "translucent_priority", mat.attrib.m.translucent_priority }); - attrib.append({ "has_fog_height", (bool)mat.attrib.m.has_fog_height }); - attrib.append({ "flag_28", (bool)mat.attrib.m.flag_28 }); - attrib.append({ "fog_height", (bool)mat.attrib.m.fog_height }); - attrib.append({ "flag_30", (bool)mat.attrib.m.flag_30 }); - attrib.append({ "flag_31", (bool)mat.attrib.m.flag_31 }); - material.append(attrib); - } - - { - msgpack color = msgpack("color", false, 0); - - { - msgpack diffuse = msgpack("diffuse", false, 0); - diffuse.append({ "r", mat.color.diffuse.x }); - diffuse.append({ "g", mat.color.diffuse.y }); - diffuse.append({ "b", mat.color.diffuse.z }); - diffuse.append({ "a", mat.color.diffuse.w }); - color.append(diffuse); + msgpack* center = material.append("center", msgpack_map()); + if (center) { + center->append("x", mat.center.x); + center->append("y", mat.center.y); + center->append("z", mat.center.z); } - { - msgpack ambient = msgpack("ambient", false, 0); - ambient.append({ "r", mat.color.ambient.x }); - ambient.append({ "g", mat.color.ambient.y }); - ambient.append({ "b", mat.color.ambient.z }); - ambient.append({ "a", mat.color.ambient.w }); - color.append(ambient); + material.append("radius", mat.radius); + material.append("name", mat.name); + material.append("bump_depth", mat.bump_depth); + + msgpack* reserved = material.append("reserved", msgpack_array()); + if (reserved) { + msgpack_array* ptr = reserved->data.arr; + ptr->resize(15); + for (int32_t k = 0; k < 15; k++) + ptr->data()[k] = mat.reserved[k]; } - - { - msgpack specular = msgpack("specular", false, 0); - specular.append({ "r", mat.color.specular.x }); - specular.append({ "g", mat.color.specular.y }); - specular.append({ "b", mat.color.specular.z }); - specular.append({ "a", mat.color.specular.w }); - color.append(specular); - } - - { - msgpack emission = msgpack("emission", false, 0); - emission.append({ "r", mat.color.emission.x }); - emission.append({ "g", mat.color.emission.y }); - emission.append({ "b", mat.color.emission.z }); - emission.append({ "a", mat.color.emission.w }); - color.append(emission); - } - - color.append({ "shininess", mat.color.shininess }); - color.append({ "intensity", mat.color.intensity }); - - material.append(color); - } - - { - msgpack center = msgpack("center", false, 0); - center.append({ "x", mat.center.x }); - center.append({ "y", mat.center.y }); - center.append({ "z", mat.center.z }); - material.append(center); - } - - material.append({ "radius", mat.radius }); - material.append({ "name", mat.name }); - material.append({ "bump_depth", mat.bump_depth }); - - { - msgpack reserved = msgpack("reserved", true, 15); - msgpack_array* ptr = MSGPACK_SELECT(msgpack_array, reserved); - for (int32_t k = 0; k < 15; k++) - ptr->data()[k] = { 0, mat.reserved[k] }; - material.append(reserved); } } - msgpack* meshes = object.get_by_name("mesh"); - ptr = MSGPACK_SELECT_PTR(msgpack_array, meshes); - for (size_t j = 0; j < obj.num_mesh; j++) { - obj_mesh& mesh = obj.mesh_array[j]; - msgpack& _mesh = ptr->data()[j]; - _mesh = msgpack(0, false, 0); + msgpack* meshes = object.append("mesh", msgpack_array()); + if (meshes) { + msgpack_array* ptr = meshes->data.arr; + ptr->resize(obj.num_mesh); + for (size_t j = 0; j < obj.num_mesh; j++) { + obj_mesh& mesh = obj.mesh_array[j]; + msgpack& _mesh = ptr->data()[j]; + _mesh = msgpack_map(); - _mesh.append(msgpack("name", mesh.name)); - _mesh.append(msgpack("sub_mesh", true, mesh.num_submesh)); + _mesh.append("name", mesh.name); - msgpack* sub_meshes = _mesh.get_by_name("sub_mesh"); - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, sub_meshes); - for (size_t k = 0; k < mesh.num_submesh; k++) { - obj_sub_mesh& sub_mesh = mesh.submesh_array[k]; - msgpack& _sub_mesh = ptr->data()[k]; - _sub_mesh = msgpack(0, false, 0); + msgpack* sub_meshes = _mesh.append("sub_mesh", msgpack_array()); + if (sub_meshes) { + msgpack_array* ptr = sub_meshes->data.arr; + ptr->resize(mesh.num_submesh); + for (size_t k = 0; k < mesh.num_submesh; k++) { + obj_sub_mesh& sub_mesh = mesh.submesh_array[k]; + msgpack& _sub_mesh = ptr->data()[k]; + _sub_mesh = msgpack_map(); - { - msgpack attrib = msgpack("attrib", false, 0); - attrib.append({ "recieve_shadow", (bool)sub_mesh.attrib.m.recieve_shadow }); - attrib.append({ "cast_shadow", (bool)sub_mesh.attrib.m.cast_shadow }); - _sub_mesh.append(attrib); + { + msgpack attrib = msgpack_map(); + attrib.append("recieve_shadow", (bool)sub_mesh.attrib.m.recieve_shadow); + attrib.append("cast_shadow", (bool)sub_mesh.attrib.m.cast_shadow); + _sub_mesh.append("attrib", attrib); + } + } } } } } - msgpack msg = msgpack(0, true, objects); + msgpack msg = objects; sprintf_s(buf, sizeof(buf), "%s\\%s\\config.json", path, set_name); - stream s; + file_stream s; s.open(buf, "wb"); io_json_write(s, &msg); s.close(); @@ -1338,7 +1283,7 @@ void object_material_msgpack_write(const char* path, const char* set_name, uint3 uint32_t index = 0; do for (uint32_t j = 0; j < tex.mipmaps_count; j++) { - uint32_t size = txp::get_size(format, max(width >> j, 1), max(height >> j, 1)); + uint32_t size = txp::get_size(format, max_def(width >> j, 1), max_def(height >> j, 1)); void* data = force_malloc(size); memcpy(data, tex.mipmaps[index].data.data(), size); d.data.push_back(data); @@ -2048,7 +1993,7 @@ inline void object_storage_unload_set(object_database* obj_db, const char* name) int32_t tex_num = handler->tex_num; for (int32_t i = 0; i < tex_num; i++) texture_free(tex_data[i]); - free(tex_data); + free_def(tex_data); handler->tex_data = 0; handler->tex_num = 0; @@ -2080,7 +2025,7 @@ inline void object_storage_unload_set(uint32_t set_id) { int32_t tex_num = handler->tex_num; for (int32_t i = 0; i < tex_num; i++) texture_free(tex_data[i]); - free(tex_data); + free_def(tex_data); handler->tex_data = 0; handler->tex_num = 0; @@ -2128,21 +2073,18 @@ static void obj_set_handler_calc_axis_aligned_bounding_box(obj_set_handler* hand continue; vec3 pos = vertex[indices[l]].position; - vec3_min(_min, pos, _min); - vec3_max(_max, pos, _max); + _min = vec3::min(_min, pos); + _max = vec3::max(_max, pos); } else for (uint32_t l = 0; l < indices_count; l++) { vec3 pos = vertex[indices[l]].position; - vec3_min(_min, pos, _min); - vec3_max(_max, pos, _max); + _min = vec3::min(_min, pos); + _max = vec3::max(_max, pos); } - vec3 center; - vec3 size; - vec3_add(_max, _min, center); - vec3_mult_scalar(center, 0.5f, center); - vec3_sub(_max, center, size); + vec3 center = (_max + _min) * 0.5f; + vec3 size = _max - center; sub_mesh.axis_aligned_bounding_box.center = center; sub_mesh.axis_aligned_bounding_box.size = size; } @@ -2320,7 +2262,7 @@ inline static void obj_skin_block_node_load(obj_skin_block_node* node, } inline static void obj_skin_block_node_free(obj_skin_block_node* node) { - free(node->parent_name); + free_def(node->parent_name); } inline static size_t obj_vertex_format_get_vertex_size(obj_vertex_format format) { diff --git a/src/CRE/ogg_vorbis.cpp b/src/CRE/ogg_vorbis.cpp new file mode 100644 index 00000000..6ee54b9d --- /dev/null +++ b/src/CRE/ogg_vorbis.cpp @@ -0,0 +1,583 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "ogg_vorbis.hpp" +#include "../KKdLib/str_utils.hpp" +#include "../KKdLib/vec.hpp" +#include + +static int32_t ogg_file_counter = 0; +static int32_t ogg_file_handler_counter = 0; + +OggFileBufferChannelData::OggFileBufferChannelData() : left(), right() { + +} + +OggFileBufferData::OggFileBufferData() { + time = -1.0; +} + +OggFileBuffer::OggFileBuffer() : first_sample(), last_sample() { + size = 0x40999; + data.resize(size); +} + +OggFileBuffer::~OggFileBuffer() { + +} + +void OggFileBuffer::Reset() { + data.clear(); + data.resize(size); + first_sample = 0; + last_sample = 0; +} + +OggFile::OggFile() : file(), info(), comments() { + loop_begin = -1; + loop_end = -1; + + thread = new std::thread(OggFile::ThreadMain, this); + if (thread) { + wchar_t buf[0x80]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), L"Ogg File #%d", ogg_file_counter++); + SetThreadDescription((HANDLE)thread->native_handle(), buf); + } +} + +OggFile::~OggFile() { + Reset(); + if (thread) { + thread_state.set(1); + thread->join(); + delete thread; + thread = 0; + } +} + +void OggFile::Ctrl(size_t samples_count) { + std::unique_lock u_lock(file_mtx); + if (!file || !info || !comments) + return; + + OggFileBufferData* _buffer_data = buffer.data.data(); + size_t _buffer_size = buffer.data.size(); + + while (samples_count) { + size_t free_samples_count = GetBufferFreeSamplesCount(); + if (free_samples_count <= 0) + break; + + int64_t samples_to_read = min_def(samples_count, free_samples_count); + int64_t position = ov_pcm_tell(file); + double_t time_start = ov_time_tell(file); + if (loop_end >= 0 && position + samples_to_read > loop_end) { + if (loop_end - position <= 0) { + size_t seek = 0i64; + if (loop_begin >= 0) + seek = loop_begin; + ov_pcm_seek_lap(file, seek); + } + else + samples_to_read = loop_end - position; + } + + float_t** pcm_channels = 0; + int32_t bitstream = 0; + size_t samples_read = ov_read_float(file, &pcm_channels, (int32_t)samples_to_read, &bitstream); + if (samples_read < 1 || !pcm_channels) + break; + + int32_t channels = info->channels; + bool mono = channels == 1; + + std::unique_lock u_lock(mtx); + for (size_t i = 0; i < samples_read; i++) { + OggFileBufferData data; + data.time = (double_t)(int32_t)i / (double_t)info->rate + time_start; + if (channels > 0) { + if (mono) { + float_t value = pcm_channels[0][i]; + data.channel_pair[0].left = value; + data.channel_pair[0].right = value; + } + else { + float_t** _pcm_channels = pcm_channels; + for (int32_t j = 0; j < channels; j += 2, _pcm_channels += 2) { + int32_t pair = j / 2; + if (pair >= 4) + break; + + data.channel_pair[pair].left = _pcm_channels[0][i]; + data.channel_pair[pair].right = _pcm_channels[1][i]; + } + } + } + + if (_buffer_size) { + size_t last_sample = buffer.last_sample; + size_t new_last_sample = last_sample + 1; + if (new_last_sample >= buffer.size) + new_last_sample = 0; + if (new_last_sample != buffer.first_sample) { + _buffer_data[last_sample] = data; + buffer.last_sample = new_last_sample; + } + } + } + samples_count -= samples_read; + } +} + +size_t OggFile::FillBufferData(OggFileBufferData* buffer_data, size_t samples_count) { + std::unique_lock u_lock(mtx); + OggFileBufferData* _buffer_data = buffer.data.data(); + size_t _buffer_size = buffer.data.size(); + size_t _samples_count = 0; + for (; samples_count && buffer.first_sample != buffer.last_sample; + samples_count--, buffer_data++, _samples_count++) { + if (_buffer_size) + *buffer_data = _buffer_data[buffer.first_sample]; + else + *buffer_data = {}; + + if (_buffer_size) { + size_t first_sample = buffer.first_sample; + if (first_sample != buffer.last_sample) { + _buffer_data[first_sample++] = {}; + if (first_sample >= buffer.size) + first_sample = 0; + buffer.first_sample = first_sample; + } + } + } + return _samples_count; +} + +size_t OggFile::GetBufferFreeSamplesCount() { + std::unique_lock u_lock(mtx); + size_t last_sample = buffer.last_sample; + size_t first_sample = buffer.first_sample; + size_t samples_count; + if (last_sample < first_sample) + samples_count = buffer.size - first_sample + last_sample; + else + samples_count = last_sample - first_sample; + return buffer.size - samples_count - 1; +} + +size_t OggFile::GetBufferSamplesCount() { + std::unique_lock u_lock(mtx); + size_t last_sample = buffer.last_sample; + size_t first_sample = buffer.first_sample; + if (last_sample < first_sample) + return buffer.size - first_sample + last_sample; + else + return last_sample - first_sample; +} + +int32_t OggFile::GetChannelPairsCount() { + std::unique_lock u_lock(file_mtx); + if (info) + return (info->channels + 1) / 2; + return 0; +} + +double_t OggFile::GetDuration() { + std::unique_lock u_lock(file_mtx); + if (file) + return ov_time_total(file, -1); + return 0.0; +} + +int32_t OggFile::GetRate() { + std::unique_lock u_lock(file_mtx); + if (info) + return info->rate; + return 0; +} + +bool OggFile::HasLoop() { + std::unique_lock u_lock(file_mtx); + return loop_end >= 0; +} + +bool OggFile::OpenFile(const char* path, double_t time_seek) { + { + std::unique_lock u_lock(file_mtx); + if (file) + goto Reset; + + file = force_malloc_s(OggVorbis_File, 1); + if (!file) + goto Reset; + + if (ov_fopen(path, file) < 0) + goto Reset; + + info = ov_info(file, -1); + comments = ov_comment(file, -1); + loop_begin = -1; + loop_end = -1; + + if (!info || !comments) { + info = 0; + comments = 0; + goto Reset; + } + + char** user_comments = comments->user_comments; + while (*user_comments) { + std::string user_comment = *user_comments++; + for (char& c : user_comment) + if (c > 0x40 && c < 0x5B) + c += 0x20; + + if (user_comment.size() >= 10 && !memcmp(user_comment.c_str(), "loop_begin", 10)) { + const char* t = strchr(user_comment.c_str(), '='); + if (t) { + t++; + sscanf_s(t, "%lld", &loop_begin); + } + } + else if (user_comment.size() >= 8 && !memcmp(user_comment.c_str(), "loop_end", 8)) { + const char* t = strchr(user_comment.c_str(), '='); + if (t) { + t++; + sscanf_s(t, "%lld", &loop_end); + } + } + } + + if (ov_time_seek(this->file, time_seek) >= 0) + return true; + } + +Reset: + Reset(); + return false; +} + +void OggFile::Reset() { + std::unique_lock u_lock(file_mtx); + if (file) { + ov_clear(file); + free(file); + } + + buffer.Reset(); + file = 0; + info = 0; + comments = 0; + loop_begin = -1; + loop_end = -1; +} + +void OggFile::ThreadMain(OggFile* of) { + if (!of) + return; + + waitable_timer timer; + while (!of->thread_state.get()) { + of->Ctrl(of->info ? of->info->rate : 44100); + timer.sleep(8); + } + of->thread_state.set(0); +} + +OggFileHandler::OggFileHandler(size_t index) : time_seek(), channel_pairs_count(), +duration(), time(), channel_pairs_count_dup(), duration_dup(), time_dup(), +channel_pair_volume_pan(), master_volume(), channel_pair_volume(), req_time(), loop() { + this->index = index; + + for (int32_t i = 0; i < 4; i++) + for (int32_t j = 0; j < 2; j++) + for (int32_t k = 0; k < 4; k++) + channel_pair_volume_pan[i][j][k] = -10000; + + channel_pair_volume_pan[0][0][0] = 0; + channel_pair_volume_pan[0][1][1] = 0; + rate = 1; + + thread = new std::thread(OggFileHandler::ThreadMain, this); + if (thread) { + wchar_t buf[0x80]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), L"Ogg File Handler #%d", ogg_file_handler_counter++); + SetThreadDescription((HANDLE)thread->native_handle(), buf); + } +} + +OggFileHandler::~OggFileHandler() { + Reset(); + if (thread) { + thread_state.set(1); + thread->join(); + delete thread; + thread = 0; + } +} + +void OggFileHandler::Ctrl() { + int32_t _playback_state = 0; + { + std::unique_lock u_lock(mtx); + _playback_state = playback_state.get(); + playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_NONE); + switch (_playback_state) { + case OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY: + Reset(false); + file_state.set(OGG_FILE_HANDLER_FILE_STATE_LOADING); + OpenFile(); + file_state.set(OGG_FILE_HANDLER_FILE_STATE_READY); + req_time = 0.0; + ReadBufferProt(0, 0); + break; + case OGG_FILE_HANDLER_PLAYBACK_STATE_STOP: + Reset(true); + break; + } + } + + sound::wasapi::System* sound_wasapi_system = sound_wasapi_system_data_get(); + if (sound_wasapi_system) { + sound::wasapi::Mixer* mixer = sound_wasapi_system->mixer; + if (mixer) { + sound::wasapi::StreamingChannel* streaming_channel = mixer->GetStreamingChannel(index); + if (streaming_channel) { + switch (_playback_state) { + case OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY: + if (sound_wasapi_system->pClockAdjustment) + sound_wasapi_system->pClockAdjustment->SetSampleRate((float_t)rate); + + streaming_channel->SetMasterVolume(1.0f); + streaming_channel->SetCallback(OggFileHandler::FillBufferStatic, this); + break; + case OGG_FILE_HANDLER_PLAYBACK_STATE_STOP: + streaming_channel->reset_state.set(1); + break; + } + } + } + } + + int32_t _channel_pairs_count = 0; + double_t _duration = 0.0; + double_t _time = 0.0; + + { + std::unique_lock u_lock(file_mtx); + _channel_pairs_count = channel_pairs_count; + _duration = duration; + _time = time; + } + + { + std::unique_lock u_lock(dup_mtx); + channel_pairs_count_dup = _channel_pairs_count; + duration_dup = _duration; + time_dup = _time; + } + + int32_t value = ratio_to_db(1.0); + if (!_channel_pairs_count) + _channel_pairs_count = 2; + + if (_channel_pairs_count >= 3 && _channel_pairs_count <= 4) { + for (int32_t i = 0; i < 2; i++) { + SetChannelPairVolumePan(i, 0, 0, value); + SetChannelPairVolumePan(i, 1, 1, value); + SetChannelPairVolumePan(i, 0, 2, -10000); + SetChannelPairVolumePan(i, 1, 3, -10000); + } + + for (int32_t i = _channel_pairs_count - 2; i < _channel_pairs_count; i++) { + SetChannelPairVolumePan(i, 0, 0, -10000); + SetChannelPairVolumePan(i, 1, 1, -10000); + SetChannelPairVolumePan(i, 0, 2, value); + SetChannelPairVolumePan(i, 1, 3, value); + } + } + else + for (int32_t i = 0; i < _channel_pairs_count; i++) { + SetChannelPairVolumePan(i, 0, 0, value); + SetChannelPairVolumePan(i, 1, 1, value); + SetChannelPairVolumePan(i, 0, 2, value); + SetChannelPairVolumePan(i, 1, 3, value); + } +} + +void OggFileHandler::FillBuffer(sound_buffer_data* buffer, size_t samples_count) { + int32_t _file_state = file_state.get(); + file_state.set(OGG_FILE_HANDLER_FILE_STATE_NONE); + + int32_t _playback_state = playback_state.get(); + playback_state.set(0); + + if (_file_state == OGG_FILE_HANDLER_FILE_STATE_PLAYING + && _playback_state != OGG_FILE_HANDLER_PLAYBACK_STATE_STOP) { + std::unique_lock u_lock(mtx); + ReadBufferProt(buffer, samples_count); + } +} + +void OggFileHandler::OpenFile() { + std::unique_lock u_lock(file_mtx); + if (file.OpenFile(path.c_str(), time_seek)) { + channel_pairs_count = file.GetChannelPairsCount(); + duration = file.GetDuration(); + time = 0.0; + rate = file.GetRate(); + loop = file.HasLoop(); + } +} + +void OggFileHandler::ReadBuffer(sound_buffer_data* buffer, size_t samples_count) { + if (!samples_count) + return; + + vec4 channel_pair_volume_pan[4][2]; + float_t channel_pair_volume[4]; + { + std::unique_lock u_lock(volume_mtx); + float_t master_volume = db_to_ratio(this->master_volume); + for (int32_t i = 0; i < 4; i++) { + for (int32_t j = 0; j < 2; j++) + for (int32_t k = 0; k < 4; k++) + ((float_t*)&channel_pair_volume_pan[i][j])[k] + = db_to_ratio(this->channel_pair_volume_pan[i][j][k]); + channel_pair_volume[i] = db_to_ratio(this->channel_pair_volume[i]) * master_volume; + } + } + + size_t samples_count_in_buffer = file.GetBufferSamplesCount(); + if (samples_count > samples_count_in_buffer) { + file.Ctrl(samples_count - samples_count_in_buffer); + file.GetBufferSamplesCount(); + } + + buffer_data.resize(samples_count); + if (!buffer_data.size()) + return; + + OggFileBufferData* _buffer_data = buffer_data.data(); + size_t _samples_count = file.FillBufferData(_buffer_data, samples_count); + if (_samples_count) + req_time = _buffer_data->time; + else { + double_t _samples_count = (double_t)(int32_t)samples_count; + if (samples_count < 0) + _samples_count += 1.844674407370955e19; + req_time += _samples_count / (double_t)rate; + } + + if (_samples_count) { + for (size_t i = _samples_count; i; i--, buffer++, _buffer_data++) { + OggFileBufferChannelData* channel_pair = _buffer_data->channel_pair; + vec4 value = vec4_null; + for (size_t j = 0; j < 4; j++, channel_pair++) { + value += (channel_pair_volume_pan[j][0] * (channel_pair_volume[j] * channel_pair->left)); + value += (channel_pair_volume_pan[j][1] * (channel_pair_volume[j] * channel_pair->right)); + } + *(vec4*)buffer = value; + } + } + else + memset(buffer, 0, sizeof(sound_buffer_data) * samples_count); +} + +void OggFileHandler::ReadBufferProt(sound_buffer_data* buffer, size_t samples_count) { + file_state.set(OGG_FILE_HANDLER_FILE_STATE_PLAYING); + if (pause_state.get() != OGG_FILE_HANDLER_PAUSE_STATE_PLAY) + samples_count = 0; + + bool process = false; + { + std::unique_lock u_lock(file_mtx); + time = req_time; + process = req_time < duration; + } + + if (process || loop) + ReadBuffer(buffer, samples_count); + else + playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_STOP); +} + +void OggFileHandler::Reset(bool reset) { + if (reset) { + SetFileState(OGG_FILE_HANDLER_FILE_STATE_STOPPING); + std::unique_lock u_lock(file_mtx); + channel_pairs_count = 0; + duration = 0.0; + time = 0.0; + } + + file.Reset(); + if (reset) { + SetFileState(OGG_FILE_HANDLER_FILE_STATE_STOPPED); + SetFileState(OGG_FILE_HANDLER_FILE_STATE_NONE); + } +} + +void OggFileHandler::SetChannelPairVolumePan(size_t src_channel_pair, + int32_t src_channel, int32_t dst_channel, int32_t value) { + if (src_channel_pair < 0 || src_channel_pair >= 4 || src_channel < 0 + || src_channel >= 2 || dst_channel < 0 || dst_channel >= 4) + return; + + value = clamp_def(value, -10000, 0); + + std::unique_lock u_lock(volume_mtx); + channel_pair_volume_pan[src_channel_pair][src_channel][dst_channel] = value; +} + +void OggFileHandler::SetFileState(OggFileHandlerFileState state) { + file_state.set(state); + if (state == OGG_FILE_HANDLER_PLAYBACK_STATE_MAX) + Reset(false); +} + +void OggFileHandler::SetPath(std::string& path) { + std::unique_lock u_lock(mtx); + file_state.set(1); + playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY); + + { + std::unique_lock u_lock(file_mtx); + this->path.assign(path); + channel_pairs_count = 0; + duration = 0.0; + time = 0.0; + } +} + +void OggFileHandler::SetPath(std::string&& path) { + SetPath(*(std::string*)&path); +} + +void OggFileHandler::FillBufferStatic(sound_buffer_data* buffer, size_t samples_count, void* data) { + if (data) + ((OggFileHandler*)data)->FillBuffer(buffer, samples_count); +} + +bool OggFileHandler::LoadFile(void* data, const char* path, const char* file, uint32_t hash) { + OggFileHandler* ofh = (OggFileHandler*)data; + ofh->SetPath(std::string(path) + file); + return true; +} + +void OggFileHandler::ThreadMain(OggFileHandler* ofh) { + if (!ofh) + return; + + waitable_timer timer; + while (!ofh->thread_state.get()) { + ofh->Ctrl(); + timer.sleep(8); + } + ofh->playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_STOP); + ofh->Ctrl(); + ofh->thread_state.set(0); +} diff --git a/src/CRE/ogg_vorbis.hpp b/src/CRE/ogg_vorbis.hpp new file mode 100644 index 00000000..663b9c4e --- /dev/null +++ b/src/CRE/ogg_vorbis.hpp @@ -0,0 +1,150 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../CRE/waitable_timer.hpp" +#include "lock.hpp" +#include "sound.hpp" +#include +#include +#include +#include +#include +#include + +enum AudioBitFormat { + AUDIO_BIT_FORMAT_S16 = 0, + AUDIO_BIT_FORMAT_S24, + AUDIO_BIT_FORMAT_S32, + AUDIO_BIT_FORMAT_F32, +}; + +enum OggFileHandlerFileState { + OGG_FILE_HANDLER_FILE_STATE_NONE = 0, + OGG_FILE_HANDLER_FILE_STATE_LOADING, + OGG_FILE_HANDLER_FILE_STATE_READY, + OGG_FILE_HANDLER_FILE_STATE_PLAYING, + OGG_FILE_HANDLER_FILE_STATE_STOPPING, + OGG_FILE_HANDLER_FILE_STATE_STOPPED, + OGG_FILE_HANDLER_FILE_STATE_MAX, +}; + +enum OggFileHandlerPauseState { + OGG_FILE_HANDLER_PAUSE_STATE_PLAY = 0, + OGG_FILE_HANDLER_PAUSE_STATE_PAUSE, + OGG_FILE_HANDLER_PAUSE_STATE_MAX, +}; + +enum OggFileHandlerPlaybackState { + OGG_FILE_HANDLER_PLAYBACK_STATE_NONE = 0, + OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY, + OGG_FILE_HANDLER_PLAYBACK_STATE_STOP, + OGG_FILE_HANDLER_PLAYBACK_STATE_MAX, +}; + +struct OggFileBufferChannelData { + float_t left; + float_t right; + + OggFileBufferChannelData(); +}; + +struct OggFileBufferData { + double_t time; + OggFileBufferChannelData channel_pair[4]; + + OggFileBufferData(); +}; + +struct OggFileBuffer { + size_t size; + std::vector data; + size_t first_sample; + size_t last_sample; + + OggFileBuffer(); + ~OggFileBuffer(); + + void Reset(); +}; + +struct OggFile { + std::mutex mtx; + lock_uint32_t thread_state; + std::thread* thread; + OggFileBuffer buffer; + OggVorbis_File* file; + vorbis_info* info; + vorbis_comment* comments; + int64_t loop_begin; + int64_t loop_end; + std::mutex file_mtx; + + OggFile(); + virtual ~OggFile(); + + void Ctrl(size_t samples_count); + size_t FillBufferData(OggFileBufferData* buffer_data, size_t samples_count); + size_t GetBufferFreeSamplesCount(); + size_t GetBufferSamplesCount(); + int32_t GetChannelPairsCount(); + double_t GetDuration(); + int32_t GetRate(); + bool HasLoop(); + bool OpenFile(const char* path, double_t time_seek); + void Reset(); + + static void ThreadMain(OggFile* of); +}; + +struct OggFileHandler { + std::mutex mtx; + lock_uint32_t thread_state; + std::thread* thread; + size_t index; + OggFile file; + std::mutex file_mtx; + std::string path; + float_t time_seek; + int32_t channel_pairs_count; + double_t duration; + double_t time; + std::mutex dup_mtx; + int32_t channel_pairs_count_dup; + double_t duration_dup; + double_t time_dup; + std::mutex volume_mtx; + int32_t channel_pair_volume_pan[4][2][4]; + int32_t master_volume; + int32_t channel_pair_volume[4]; + lock_uint32_t file_state; + lock_uint32_t playback_state; + lock_uint32_t pause_state; + double_t req_time; + int32_t rate; + bool loop; + std::vector buffer_data; + + OggFileHandler(size_t index = 0); + virtual ~OggFileHandler(); + + void Ctrl(); + void FillBuffer(sound_buffer_data* buffer, size_t samples_count); + void OpenFile(); + void ReadBuffer(sound_buffer_data* buffer, size_t samples_count); + void ReadBufferProt(sound_buffer_data* buffer, size_t samples_count); + void Reset(bool reset = false); + void SetChannelPairVolumePan(size_t src_channel_pair, + int32_t src_channel, int32_t dst_channel, int32_t value); + void SetFileState(OggFileHandlerFileState state); + void SetPath(std::string& path); + void SetPath(std::string&& path); + + static void FillBufferStatic(sound_buffer_data* buffer, size_t samples_count, void* data); + static bool LoadFile(void* data, const char* path, const char* file, uint32_t hash); + static void ThreadMain(OggFileHandler* ofh); +}; diff --git a/src/CRE/post_process.cpp b/src/CRE/post_process.cpp index cdbb721b..c1037af5 100644 --- a/src/CRE/post_process.cpp +++ b/src/CRE/post_process.cpp @@ -15,7 +15,7 @@ extern bool task_stage_is_modern; -post_process::post_process() : ssaa(), mlaa(), parent_bone_node(), render_textures_data(), +post_process::post_process() : ssaa(), mlaa(), ss_alpha_mask(), render_textures_data(), movie_textures_data(), lens_flare_texture(), lens_shaft_texture(), lens_ghost_texture(), lens_flare_count(), lens_flare_pos(), lens_shaft_scale(), lens_shaft_inv_scale(), lens_flare_power(), field_A10(), lens_flare_appear_power(), render_width(), render_height(), @@ -39,7 +39,7 @@ sprite_height(), screen_x_offset(), screen_y_offset(), screen_width(), screen_he "layout(location = 0) out vec4 result;\n" "\n" "void main() {\n" - " result = vec4(0.0); \n" + " result = vec4(0.0);\n" "}\n"; static const char* alpha_layer_vert_shader = @@ -86,12 +86,12 @@ sprite_height(), screen_x_offset(), screen_y_offset(), screen_width(), screen_he glGenSamplers(2, samplers); glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_LINEAR); glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(samplers[0], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_NEAREST); glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(samplers[1], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); const float_t verts_quad[] = { -1.0f, 1.0f, 0.15f, 0.85f, @@ -192,7 +192,7 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param blur->tex[0].color_texture->tex, exposure->exposure.color_texture->tex, npr_param); if (mlaa) - aa->apply_mlaa(&rend_texture, &buf_texture, samplers, parent_bone_node); + aa->apply_mlaa(&rend_texture, &buf_texture, samplers, ss_alpha_mask); for (int32_t i = 0; i < 16; i++) { if (!render_textures_data[i]) @@ -223,12 +223,12 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param if (ssaa) { gl_state_active_bind_texture_2d(0, rend_texture.color_texture->tex); gl_state_bind_sampler(0, samplers[0]); - uniform_value[U01] = parent_bone_node ? 1 : 0; + uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; uniform_value[U_REDUCE] = 0; shaders_ft.set(SHADER_FT_REDUCE); render_texture::draw_params(&shaders_ft, render_width, render_height, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - uniform_value[U01] = 0; + uniform_value[U_ALPHA_MASK] = 0; } else { gl_state_active_bind_texture_2d(0, rend_texture.color_texture->tex); @@ -279,19 +279,12 @@ void post_process::ctrl(camera* cam) { reset_exposure = cam->fast_change_hist1 && !cam->fast_change_hist0; if (reset_exposure) { - float_t view_point_dist; - vec3_distance(view_point, view_point_prev, view_point_dist); + float_t view_point_dist = vec3::distance(view_point, view_point_prev); - vec3 dir; - vec3_sub(interest, view_point, dir); - vec3_normalize(dir, dir); + vec3 dir = vec3::normalize(interest - view_point); + vec3 dir_prev = vec3::normalize(interest_prev - view_point_prev); - vec3 dir_prev; - vec3_sub(interest_prev, view_point_prev, dir_prev); - vec3_normalize(dir_prev, dir_prev); - - float_t dir_diff_angle; - vec3_dot(dir, dir_prev, dir_diff_angle); + float_t dir_diff_angle = vec3::dot(dir, dir_prev); if (dir_diff_angle < 0.5f) dir_diff_angle = 0.0f; if (view_point_dist < dir_diff_angle * 0.4f) @@ -310,7 +303,6 @@ void post_process::draw_query_samples(GLuint query, float_t scale, mat4& mat) { gl_state_bind_vertex_array(0); glEndQuery(GL_SAMPLES_PASSED); } - void post_process::init_fbo(int32_t render_width, int32_t render_height, int32_t sprite_width, int32_t sprite_height, int32_t screen_width, int32_t screen_height) { if (this->render_width == render_width && this->render_height == render_height @@ -323,12 +315,12 @@ void post_process::init_fbo(int32_t render_width, int32_t render_height, dof->init_fbo(render_width, render_height); exposure->init_fbo(); tone_map->init_fbo(); - rend_texture.init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH24_STENCIL8); + rend_texture.init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F); buf_texture.init(render_width, render_height, 0, GL_RGBA16F, 0); - sss_contour_texture.init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH24_STENCIL8); + sss_contour_texture.init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F); pre_texture.init(render_width, render_height, 0, GL_RGBA16F, 0); post_texture.init(render_width, render_height, 0, GL_RGBA16F, 0); - alpha_layer_texture.init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH24_STENCIL8); + alpha_layer_texture.init(render_width, render_height, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F); gl_state_bind_texture_2d(rend_texture.depth_texture->tex); GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); @@ -347,7 +339,7 @@ void post_process::init_fbo(int32_t render_width, int32_t render_height, if (this->screen_width != screen_width || this->screen_height != screen_height) { fbo_texture.init(screen_width, screen_height, 0, GL_RGBA16F, 0); - screen_texture.init(screen_width, screen_height, 0, GL_R11F_G11F_B10F, 0); + screen_texture.init(screen_width, screen_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F this->screen_width = screen_width; this->screen_height = screen_height; } diff --git a/src/CRE/post_process.hpp b/src/CRE/post_process.hpp index 9e2ab75c..10a76389 100644 --- a/src/CRE/post_process.hpp +++ b/src/CRE/post_process.hpp @@ -27,7 +27,7 @@ enum post_process_mag_filter_type { struct post_process { bool ssaa; bool mlaa; - int32_t parent_bone_node; + int32_t ss_alpha_mask; render_texture rend_texture; render_texture buf_texture; render_texture sss_contour_texture; diff --git a/src/CRE/post_process/aa.cpp b/src/CRE/post_process/aa.cpp index 6c106f3f..09a6eb63 100644 --- a/src/CRE/post_process/aa.cpp +++ b/src/CRE/post_process/aa.cpp @@ -36,12 +36,14 @@ post_process_aa::~post_process_aa() { } void post_process_aa::apply_mlaa(render_texture* rt, - render_texture* buf_rt, GLuint* samplers, int32_t a4) { + render_texture* buf_rt, GLuint* samplers, int32_t ss_alpha_mask) { mlaa_buffer->bind(); gl_state_active_bind_texture_2d(0, rt->color_texture->tex); gl_state_bind_sampler(0, samplers[1]); - uniform_value[U_MLAA] = 0; - shaders_ft.set(SHADER_FT_MLAA); + //uniform_value[U_MLAA] = 0; + //shaders_ft.set(SHADER_FT_MLAA); + uniform_value[U_ALPHA_MASK] = 0; + shaders_ft.set(SHADER_FT_MLAA_EDGE); render_texture::draw_params(&shaders_ft, width, height, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); mlaa_buffer[1].bind(); @@ -49,20 +51,24 @@ void post_process_aa::apply_mlaa(render_texture* rt, gl_state_active_bind_texture_2d(1, mlaa_area_texture); gl_state_bind_sampler(0, samplers[0]); gl_state_bind_sampler(1, samplers[1]); - uniform_value[U20] = 2; - uniform_value[U_MLAA] = 1; - shaders_ft.set(SHADER_FT_MLAA); + //uniform_value[U_MLAA_SEARCH] = 2; + //uniform_value[U_MLAA] = 1; + //shaders_ft.set(SHADER_FT_MLAA); + uniform_value[U_MLAA_SEARCH] = 2; + shaders_ft.set(SHADER_FT_MLAA_AREA); render_texture::draw_params(&shaders_ft, width, height, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); buf_rt->bind(); gl_state_active_bind_texture_2d(0, rt->color_texture->tex); gl_state_active_bind_texture_2d(1, mlaa_buffer[1].color_texture->tex); gl_state_bind_sampler(0, samplers[1]); - uniform_value[U_MLAA] = 2; - uniform_value[U01] = a4 ? 1 : 0; - shaders_ft.set(SHADER_FT_MLAA); + //uniform_value[U_MLAA] = 2; + //uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + //shaders_ft.set(SHADER_FT_MLAA); + uniform_value[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + shaders_ft.set(SHADER_FT_MLAA_BLEND); render_texture::draw_params(&shaders_ft, width, height, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - uniform_value[U01] = 0; + uniform_value[U_ALPHA_MASK] = 0; gl_state_active_bind_texture_2d(0, 0); gl_state_active_bind_texture_2d(1, 0); @@ -75,8 +81,8 @@ void post_process_aa::init_fbo(int32_t width, int32_t height) { if (!this || (this->width == width && this->height == height)) return; - this->width = max(width, 1); - this->height = max(height, 1); + this->width = max_def(width, 1); + this->height = max_def(height, 1); mlaa_buffer[0].init(this->width, this->height, 0, GL_RGBA8, 0); mlaa_buffer[1].init(this->width, this->height, 0, GL_RGBA8, 0); @@ -101,7 +107,7 @@ static void post_process_aa_calculate_area_texture_data_sub(float_t* a2, float_t v8 = 0.0f; float_t v10 = 0.0f; int32_t v11 = a6 + a7 + 1; - v11 = min(v11, 7); + v11 = min_def(v11, 7); int32_t v12; if (((a6 + a7 + 1) & 1) != 0) diff --git a/src/CRE/post_process/aa.hpp b/src/CRE/post_process/aa.hpp index 7d96babb..0c90e819 100644 --- a/src/CRE/post_process/aa.hpp +++ b/src/CRE/post_process/aa.hpp @@ -20,6 +20,6 @@ struct post_process_aa { virtual ~post_process_aa(); void apply_mlaa(render_texture* rt, - render_texture* buf_rt, GLuint* samplers, int32_t a4); + render_texture* buf_rt, GLuint* samplers, int32_t ss_alpha_mask); void init_fbo(int32_t width, int32_t height); }; diff --git a/src/CRE/post_process/blur.cpp b/src/CRE/post_process/blur.cpp index 09a8e472..c86e74da 100644 --- a/src/CRE/post_process/blur.cpp +++ b/src/CRE/post_process/blur.cpp @@ -29,13 +29,13 @@ post_process_blur:: ~post_process_blur() { for (int32_t i = 0; i < count_down; i++) tex_down[i].free_data(); - free(tex_down); - free(height_down); - free(width_down); + free_def(tex_down); + free_def(height_down); + free_def(width_down); } void post_process_blur::get_blur(render_texture* rt) { - uniform_value[U01] = 0; + uniform_value[U_ALPHA_MASK] = 0; int32_t i = 0; if (count_down > 0) { @@ -110,7 +110,7 @@ void post_process_blur::get_blur(render_texture* rt) { vec3 v[POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE]; for (int32_t i = 0; i < POST_PROCESS_BLUR_GAUSSIAN_KERNEL_SIZE; i++) - vec3_mult(gauss[i], intensity, v[i]); + v[i] = gauss[i] * intensity; uniform_value[U_GAUSS] = 0; render_texture::shader_set(&shaders_ft, SHADER_FT_GAUSS); @@ -205,7 +205,7 @@ void post_process_blur::init_fbo(int32_t width, int32_t height) { else if (count_down < i) { render_texture* temp = force_malloc_s(render_texture, i); memcpy(temp, tex_down, sizeof(render_texture) * count_down); - free(tex_down); + free_def(tex_down); tex_down = temp; } @@ -214,7 +214,7 @@ void post_process_blur::init_fbo(int32_t width, int32_t height) { else if (count_down < i) { int32_t* temp = force_malloc_s(int32_t, i); memcpy(temp, width_down, sizeof(int32_t) * count_down); - free(width_down); + free_def(width_down); width_down = temp; } @@ -223,7 +223,7 @@ void post_process_blur::init_fbo(int32_t width, int32_t height) { else if (count_down < i) { int32_t* temp = force_malloc_s(int32_t, i); memcpy(temp, height_down, sizeof(int32_t) * count_down); - free(height_down); + free_def(height_down); height_down = temp; } @@ -249,12 +249,12 @@ void post_process_blur::init_fbo(int32_t width, int32_t height) { } void post_process_blur::initialize_data(const vec3& radius, const vec3& intensity) { - data.radius.x = clamp(radius.x, 1.0f, 3.0f); - data.radius.y = clamp(radius.y, 1.0f, 3.0f); - data.radius.z = clamp(radius.z, 1.0f, 3.0f); - data.intensity.x = clamp(intensity.x, 0.0f, 2.0f); - data.intensity.y = clamp(intensity.y, 0.0f, 2.0f); - data.intensity.z = clamp(intensity.z, 0.0f, 2.0f); + data.radius.x = clamp_def(radius.x, 1.0f, 3.0f); + data.radius.y = clamp_def(radius.y, 1.0f, 3.0f); + data.radius.z = clamp_def(radius.z, 1.0f, 3.0f); + data.intensity.x = clamp_def(intensity.x, 0.0f, 2.0f); + data.intensity.y = clamp_def(intensity.y, 0.0f, 2.0f); + data.intensity.z = clamp_def(intensity.z, 0.0f, 2.0f); post_process_blur_radius_calculate(this); } @@ -263,9 +263,9 @@ vec3 post_process_blur::get_intensity() { } void post_process_blur::set_intensity(const vec3& value) { - data.intensity.x = clamp(value.x, 0.0f, 2.0f); - data.intensity.y = clamp(value.y, 0.0f, 2.0f); - data.intensity.z = clamp(value.z, 0.0f, 2.0f); + data.intensity.x = clamp_def(value.x, 0.0f, 2.0f); + data.intensity.y = clamp_def(value.y, 0.0f, 2.0f); + data.intensity.z = clamp_def(value.z, 0.0f, 2.0f); } vec3 post_process_blur::get_radius() { @@ -274,9 +274,9 @@ vec3 post_process_blur::get_radius() { void post_process_blur::set_radius(const vec3& value) { vec3 temp; - temp.x = clamp(value.x, 1.0f, 3.0f); - temp.y = clamp(value.y, 1.0f, 3.0f); - temp.z = clamp(value.z, 1.0f, 3.0f); + temp.x = clamp_def(value.x, 1.0f, 3.0f); + temp.y = clamp_def(value.y, 1.0f, 3.0f); + temp.z = clamp_def(value.z, 1.0f, 3.0f); if (memcmp(&temp, &data.radius, sizeof(vec3))) { data.radius = temp; post_process_blur_radius_calculate(this); diff --git a/src/CRE/post_process/dof.cpp b/src/CRE/post_process/dof.cpp index fae07c29..d3ed1aba 100644 --- a/src/CRE/post_process/dof.cpp +++ b/src/CRE/post_process/dof.cpp @@ -566,8 +566,14 @@ static const char* dof_frag_shader_upsample = " is thinly combined with the actual resolution because it's not good\n" " combined_factor = clamp(combined_factor, 0.0, 1.0);\n" "#endif\n" +"#if 1\n" +" // Fix alpha\n" +" result.rgb = max(tone_map(mix(half_res.rgb, full_res.rgb, combined_factor), 1.0), vec3(0.0));\n" +" result.a = full_res.a;\n" +"#else\n" " result = mix(half_res, full_res, combined_factor);\n" " result.rgb = max(tone_map(result.rgb, 1.0), vec3(0.0));\n" +"#endif\n" "}\n"; static const dof_debug dof_debug_default = { @@ -668,20 +674,20 @@ void post_process_dof::apply(render_texture* rt, GLuint* samplers, camera* cam) mat4 view_transpose; mat4_transpose(&cam->view, &view_transpose); - vec3_dot(*(vec3*)&view_transpose.row2, chara_trans, focus); - focus = -focus - view_transpose.row2.w - 0.1f; + focus = -vec3::dot(*(vec3*)&view_transpose.row2, chara_trans) + - view_transpose.row2.w - 0.1f; break; } } - focus = max(focus, (float_t)cam->min_distance); + focus = max_def(focus, (float_t)cam->min_distance); renderer::DOF3::apply_physical(this, rt, samplers, rt->color_texture->tex, rt->depth_texture->tex, (float_t)cam->min_distance, (float_t)cam->max_distance, focus, data.debug.focal_length, (float_t)cam->fov_rad, data.debug.f_number); } else { - float_t fuzzing_range = max(data.debug.f2.fuzzing_range, 0.01f); + float_t fuzzing_range = max_def(data.debug.f2.fuzzing_range, 0.01f); renderer::DOF3::apply_f2(this, rt, samplers, rt->color_texture->tex, rt->depth_texture->tex, (float_t)cam->min_distance, (float_t)cam->max_distance, (float_t)cam->fov_rad, @@ -691,7 +697,7 @@ void post_process_dof::apply(render_texture* rt, GLuint* samplers, camera* cam) } } else if (data.pv.enable && data.pv.f2.ratio > 0.0f) { - float_t fuzzing_range = max(data.pv.f2.fuzzing_range, 0.01f); + float_t fuzzing_range = max_def(data.pv.f2.fuzzing_range, 0.01f); renderer::DOF3::apply_f2(this, rt, samplers, rt->color_texture->tex, rt->depth_texture->tex, (float_t)cam->min_distance, (float_t)cam->max_distance, (float_t)cam->fov_rad, @@ -725,10 +731,10 @@ void post_process_dof::init_fbo(int32_t width, int32_t height) { this->width = width; this->height = height; - int32_t w20 = max(width / 20, 1); - int32_t h20 = max(height / 20, 1); - int32_t w2 = max(width / 2, 1); - int32_t h2 = max(height / 2, 1); + int32_t w20 = max_def(width / 20, 1); + int32_t h20 = max_def(height / 20, 1); + int32_t w2 = max_def(width / 2, 1); + int32_t h2 = max_def(height / 2, 1); glGenTextures(6, textures); gl_state_bind_texture_2d(textures[0]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); @@ -828,10 +834,7 @@ static void post_process_dof_calculate_texcoords(vec2* data, float_t size) { v8 *= size; v11 = v9 * (float_t)(M_PI * 0.25); - vec2 t; - t.x = cosf(v11); - t.y = sinf(v11); - vec2_mult_scalar(t, v8, *data++); + *data++ = vec2(cosf(v11), sinf(v11)) * v8; } } } @@ -865,27 +868,27 @@ static void post_process_dof_load_shaders(post_process_dof* dof) { t0 = str_utils_copy(dof_frag_shader_version); t1 = str_utils_add(t0, shared); frag_shader_string[1 + i * 4] = str_utils_add(t1, dof_frag_shader_render_tiles_part_1); - free(t0); - free(t1); + free_def(t0); + free_def(t1); t0 = str_utils_copy(dof_frag_shader_version); t1 = str_utils_add(t0, shared); frag_shader_string[2 + i * 4] = str_utils_add(t1, dof_frag_shader_downsample); - free(t0); - free(t1); + free_def(t0); + free_def(t1); t0 = str_utils_copy(dof_frag_shader_version); t1 = str_utils_add(t0, shared); frag_shader_string[3 + i * 4] = str_utils_add(t1, dof_frag_shader_apply_main_filter); - free(t0); - free(t1); + free_def(t0); + free_def(t1); t0 = str_utils_copy(dof_frag_shader_version); t1 = str_utils_add(t0, shared); frag_shader_string[4 + i * 4] = str_utils_add(t1, dof_frag_shader_upsample); - free(t0); - free(t1); - free(shared); + free_def(t0); + free_def(t1); + free_def(shared); } GLuint vert_shader = post_process_dof_shader_compile(GL_VERTEX_SHADER, dof_vert_shader); @@ -893,7 +896,7 @@ static void post_process_dof_load_shaders(post_process_dof* dof) { GLuint frag_shader = post_process_dof_shader_compile(GL_FRAGMENT_SHADER, frag_shader_string[i]); dof->program[i] = post_process_dof_program_link(vert_shader, frag_shader); glDeleteShader(frag_shader); - free(frag_shader_string[i]); + free_def(frag_shader_string[i]); } glDeleteShader(vert_shader); } @@ -911,10 +914,10 @@ static GLuint post_process_dof_shader_compile(GLenum type, const char* data) { if (!success) { GLchar* info_log = force_malloc_s(GLchar, 0x10000); glGetShaderInfoLog(shader, 0x10000, 0, info_log); - printf("Shader compile error: "); + printf("DOF Shader compile error: "); printf(info_log); putchar('\n'); - free(info_log); + free_def(info_log); } return shader; } @@ -932,10 +935,10 @@ static GLuint post_process_dof_program_link(GLuint vert_shad, GLuint frag_shad) if (!success) { GLchar* info_log = force_malloc_s(GLchar, 0x10000); glGetProgramInfoLog(program, 0x10000, 0, info_log); - printf("DOF Program Shader linking error:\n"); + printf("DOF shader linking error:\n"); printf(info_log); putchar('\n'); - free(info_log); + free_def(info_log); glDeleteProgram(program); return 0; } diff --git a/src/CRE/post_process/exposure.cpp b/src/CRE/post_process/exposure.cpp index 274deabe..c5ac1e41 100644 --- a/src/CRE/post_process/exposure.cpp +++ b/src/CRE/post_process/exposure.cpp @@ -12,15 +12,14 @@ static void sub_1405163C0(rob_chara* rob_chr, int32_t a2, mat4* mat); +post_process_exposure_chara_data::post_process_exposure_chara_data() : field_80(), query(), query_data() { + for (GLuint& i : query_data) + i = -1; +} + post_process_exposure::post_process_exposure() : exposure_history_counter(), chara_data(), query_index() { chara_data = new post_process_exposure_chara_data[ROB_CHARA_COUNT]; - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { - memset(&chara_data[i], 0, sizeof(post_process_exposure_chara_data)); - chara_data[i].query_data[0] = -1; - chara_data[i].query_data[1] = -1; - chara_data[i].query_data[2] = -1; - } } post_process_exposure::~post_process_exposure() { diff --git a/src/CRE/post_process/exposure.hpp b/src/CRE/post_process/exposure.hpp index c2df9111..136962ed 100644 --- a/src/CRE/post_process/exposure.hpp +++ b/src/CRE/post_process/exposure.hpp @@ -16,6 +16,8 @@ struct post_process_exposure_chara_data { float_t field_80; GLuint query[3]; GLuint query_data[3]; + + post_process_exposure_chara_data(); }; struct post_process_exposure { diff --git a/src/CRE/post_process/tone_map.cpp b/src/CRE/post_process/tone_map.cpp index c2eafb59..f88d937c 100644 --- a/src/CRE/post_process/tone_map.cpp +++ b/src/CRE/post_process/tone_map.cpp @@ -12,7 +12,13 @@ static void post_process_tone_map_calculate_data(post_process_tone_map* tm); static void post_process_tone_map_calculate_tex(post_process_tone_map* tm); -post_process_tone_map::post_process_tone_map() : data(), shader_data(), tone_map() { +post_process_tone_map_data::post_process_tone_map_data() : tex(), exposure(), auto_exposure(), gamma(), +gamma_rate(), saturate_power(), saturate_coeff(), scene_fade_blend_func(), tone_map_method(), lens_flare(), +lens_shaft(), lens_ghost(), lens_flare_power(), lens_flare_appear_power(), update(), update_tex() { + +} + +post_process_tone_map::post_process_tone_map() : shader_data(), tone_map() { } @@ -130,24 +136,24 @@ void post_process_tone_map::initialize_data(float_t exposure, bool auto_exposure float_t gamma, float_t gamma_rate, int32_t saturate_power, float_t saturate_coeff, const vec3& scene_fade_color, float_t scene_fade_alpha, int32_t scene_fade_blend_func, const vec3& tone_trans_start, const vec3& tone_trans_end, tone_map_method tone_map_method) { - data.exposure = clamp(exposure, 0.0f, 4.0f); + data.exposure = clamp_def(exposure, 0.0f, 4.0f); data.auto_exposure = auto_exposure; - data.gamma = clamp(gamma, 0.2f, 2.2f); - data.gamma_rate = clamp(gamma_rate, 0.5f, 2.0f); - data.saturate_power = clamp(saturate_power, 1, 6); - data.saturate_coeff = clamp(saturate_coeff, 0.0f, 1.0f); - data.scene_fade.x = clamp(scene_fade_color.x, 0.0f, 1.0f); - data.scene_fade.y = clamp(scene_fade_color.y, 0.0f, 1.0f); - data.scene_fade.z = clamp(scene_fade_color.z, 0.0f, 1.0f); - data.scene_fade.w = clamp(scene_fade_alpha, 0.0f, 1.0f); - data.scene_fade_blend_func = clamp(scene_fade_blend_func, 0, 2); - data.tone_trans_start.x = clamp(tone_trans_start.x, 0.0f, 1.0f); - data.tone_trans_start.y = clamp(tone_trans_start.y, 0.0f, 1.0f); - data.tone_trans_start.z = clamp(tone_trans_start.z, 0.0f, 1.0f); - data.tone_trans_end.x = clamp(tone_trans_end.x, 0.0f, 1.0f); - data.tone_trans_end.y = clamp(tone_trans_end.y, 0.0f, 1.0f); - data.tone_trans_end.z = clamp(tone_trans_end.z, 0.0f, 1.0f); - data.tone_map_method = clamp(tone_map_method, TONE_MAP_YCC_EXPONENT, TONE_MAP_RGB_LINEAR2); + data.gamma = clamp_def(gamma, 0.2f, 2.2f); + data.gamma_rate = clamp_def(gamma_rate, 0.5f, 2.0f); + data.saturate_power = clamp_def(saturate_power, 1, 6); + data.saturate_coeff = clamp_def(saturate_coeff, 0.0f, 1.0f); + data.scene_fade.x = clamp_def(scene_fade_color.x, 0.0f, 1.0f); + data.scene_fade.y = clamp_def(scene_fade_color.y, 0.0f, 1.0f); + data.scene_fade.z = clamp_def(scene_fade_color.z, 0.0f, 1.0f); + data.scene_fade.w = clamp_def(scene_fade_alpha, 0.0f, 1.0f); + data.scene_fade_blend_func = clamp_def(scene_fade_blend_func, 0, 2); + data.tone_trans_start.x = clamp_def(tone_trans_start.x, 0.0f, 1.0f); + data.tone_trans_start.y = clamp_def(tone_trans_start.y, 0.0f, 1.0f); + data.tone_trans_start.z = clamp_def(tone_trans_start.z, 0.0f, 1.0f); + data.tone_trans_end.x = clamp_def(tone_trans_end.x, 0.0f, 1.0f); + data.tone_trans_end.y = clamp_def(tone_trans_end.y, 0.0f, 1.0f); + data.tone_trans_end.z = clamp_def(tone_trans_end.z, 0.0f, 1.0f); + data.tone_map_method = clamp_def(tone_map_method, TONE_MAP_YCC_EXPONENT, TONE_MAP_RGB_LINEAR2); data.update_tex = false; data.update = true; data.update_tex = true; @@ -170,7 +176,7 @@ float_t post_process_tone_map::get_exposure() { } void post_process_tone_map::set_exposure(float_t value) { - value = clamp(value, 0.0f, 4.0f); + value = clamp_def(value, 0.0f, 4.0f); if (value != data.exposure) { data.exposure = value; data.update = true; @@ -183,7 +189,7 @@ float_t post_process_tone_map::get_gamma() { } void post_process_tone_map::set_gamma(float_t value) { - value = clamp(value, 0.2f, 2.2f); + value = clamp_def(value, 0.2f, 2.2f); if (value != data.gamma) { data.gamma = value; data.update = true; @@ -196,7 +202,7 @@ float_t post_process_tone_map::get_gamma_rate() { } void post_process_tone_map::set_gamma_rate(float_t value) { - value = clamp(value, 0.5f, 2.0f); + value = clamp_def(value, 0.5f, 2.0f); if (value != data.gamma_rate) { data.gamma_rate = value; data.update_tex = true; @@ -208,7 +214,7 @@ float_t post_process_tone_map::get_lens_flare() { } void post_process_tone_map::set_lens_flare(float_t value) { - value = clamp(value, 0.0f, 1.0f); + value = clamp_def(value, 0.0f, 1.0f); if (value != data.lens_flare) { data.lens_flare = value; data.update = true; @@ -220,7 +226,7 @@ float_t post_process_tone_map::get_lens_ghost() { } void post_process_tone_map::set_lens_ghost(float_t value) { - data.lens_ghost = clamp(value, 0.0f, 1.0f); + data.lens_ghost = clamp_def(value, 0.0f, 1.0f); } float_t post_process_tone_map::get_lens_shaft() { @@ -228,7 +234,7 @@ float_t post_process_tone_map::get_lens_shaft() { } void post_process_tone_map::set_lens_shaft(float_t value) { - value = clamp(value, 0.0f, 1.0f); + value = clamp_def(value, 0.0f, 1.0f); if (value != data.lens_shaft) { data.lens_shaft = value; data.update = true; @@ -240,7 +246,7 @@ float_t post_process_tone_map::get_saturate_coeff() { } void post_process_tone_map::set_saturate_coeff(float_t value) { - value = clamp(value, 0.0f, 1.0f); + value = clamp_def(value, 0.0f, 1.0f); if (value != data.saturate_coeff) { data.saturate_coeff = value; data.update_tex = true; @@ -252,7 +258,7 @@ int32_t post_process_tone_map::get_saturate_power() { } void post_process_tone_map::set_saturate_power(int32_t value) { - value = clamp(value, 1, 6); + value = clamp_def(value, 1, 6); if (value != data.saturate_power) { data.saturate_power = value; data.update_tex = true; @@ -265,10 +271,10 @@ vec4 post_process_tone_map::get_scene_fade() { void post_process_tone_map::set_scene_fade(const vec4& value) { vec4 temp; - temp.x = clamp(value.x, 0.0f, 1.0f); - temp.y = clamp(value.y, 0.0f, 1.0f); - temp.z = clamp(value.z, 0.0f, 1.0f); - temp.z = clamp(value.w, 0.0f, 1.0f); + temp.x = clamp_def(value.x, 0.0f, 1.0f); + temp.y = clamp_def(value.y, 0.0f, 1.0f); + temp.z = clamp_def(value.z, 0.0f, 1.0f); + temp.z = clamp_def(value.w, 0.0f, 1.0f); if (memcmp(&temp, &data.scene_fade, sizeof(vec4))) { data.scene_fade = temp; data.update = true; @@ -280,7 +286,7 @@ float_t post_process_tone_map::get_scene_fade_alpha() { } void post_process_tone_map::set_scene_fade_alpha(float_t value) { - value = clamp(value, 0.0f, 1.0f); + value = clamp_def(value, 0.0f, 1.0f); if (value != data.scene_fade.w) { data.scene_fade.w = value; data.update = true; @@ -292,7 +298,7 @@ int32_t post_process_tone_map::get_scene_fade_blend_func() { } void post_process_tone_map::set_scene_fade_blend_func(int32_t value) { - value = clamp(value, 0, 2); + value = clamp_def(value, 0, 2); if (value != data.scene_fade_blend_func) { data.scene_fade_blend_func = value; data.update = true; @@ -305,9 +311,9 @@ vec3 post_process_tone_map::get_scene_fade_color() { void post_process_tone_map::set_scene_fade_color(const vec3& value) { vec3 temp; - temp.x = clamp(value.x, 0.0f, 1.0f); - temp.y = clamp(value.y, 0.0f, 1.0f); - temp.z = clamp(value.z, 0.0f, 1.0f); + temp.x = clamp_def(value.x, 0.0f, 1.0f); + temp.y = clamp_def(value.y, 0.0f, 1.0f); + temp.z = clamp_def(value.z, 0.0f, 1.0f); if (memcmp(&temp, &data.scene_fade, sizeof(vec3))) { *(vec3*)&data.scene_fade = temp; data.update = true; @@ -319,7 +325,7 @@ tone_map_method post_process_tone_map::get_tone_map_method() { } void post_process_tone_map::set_tone_map_method(tone_map_method value) { - value = clamp(value, TONE_MAP_YCC_EXPONENT, TONE_MAP_RGB_LINEAR2); + value = clamp_def(value, TONE_MAP_YCC_EXPONENT, TONE_MAP_RGB_LINEAR2); if (value != data.tone_map_method) { data.tone_map_method = value; data.update = true; @@ -342,9 +348,9 @@ vec3 post_process_tone_map::get_tone_trans_end() { void post_process_tone_map::set_tone_trans_end(const vec3& value) { vec3 temp; - temp.x = clamp(value.x, 0.0f, 1.0f); - temp.y = clamp(value.y, 0.0f, 1.0f); - temp.z = clamp(value.z, 0.0f, 1.0f); + temp.x = clamp_def(value.x, 0.0f, 1.0f); + temp.y = clamp_def(value.y, 0.0f, 1.0f); + temp.z = clamp_def(value.z, 0.0f, 1.0f); if (memcmp(&temp, &data.tone_trans_end, sizeof(vec3))) { data.tone_trans_end = temp; data.update = true; @@ -357,9 +363,9 @@ vec3 post_process_tone_map::get_tone_trans_start() { void post_process_tone_map::set_tone_trans_start(const vec3& value) { vec3 temp; - temp.x = clamp(value.x, 0.0f, 1.0f); - temp.y = clamp(value.y, 0.0f, 1.0f); - temp.z = clamp(value.z, 0.0f, 1.0f); + temp.x = clamp_def(value.x, 0.0f, 1.0f); + temp.y = clamp_def(value.y, 0.0f, 1.0f); + temp.z = clamp_def(value.z, 0.0f, 1.0f); if (memcmp(&temp, &data.tone_trans_start, sizeof(vec3))) { data.tone_trans_start = temp; data.update = true; @@ -367,11 +373,8 @@ void post_process_tone_map::set_tone_trans_start(const vec3& value) { } static void post_process_tone_map_calculate_data(post_process_tone_map* tm) { - vec3 tone_trans, tone_trans_scale, tone_trans_offset; - vec3_sub(tm->data.tone_trans_end, tm->data.tone_trans_start, tone_trans); - vec3_rcp(tone_trans, tone_trans_scale); - vec3_mult(tone_trans_scale, tm->data.tone_trans_start, tone_trans_offset); - vec3_negate(tone_trans_offset, tone_trans_offset); + vec3 tone_trans_scale = vec3::rcp(tm->data.tone_trans_end - tm->data.tone_trans_start); + vec3 tone_trans_offset = -(tone_trans_scale * tm->data.tone_trans_start); post_process_tone_map_shader_data* v = &tm->shader_data; v->p_exposure.x = tm->data.exposure; @@ -385,7 +388,7 @@ static void post_process_tone_map_calculate_data(post_process_tone_map* tm) { v->p_flare_coef.w = 0.0f; v->p_fade_color = tm->data.scene_fade; if (tm->data.scene_fade_blend_func == 1 || tm->data.scene_fade_blend_func == 2) - vec3_mult_scalar(*(vec3*)&v->p_fade_color, v->p_fade_color.w, *(vec3*)&v->p_fade_color); + *(vec3*)&v->p_fade_color = *(vec3*)&v->p_fade_color * v->p_fade_color.w; v->p_tone_scale.x = tone_trans_scale.x; v->p_tone_scale.y = tone_trans_scale.y; v->p_tone_scale.z = tone_trans_scale.z; diff --git a/src/CRE/post_process/tone_map.hpp b/src/CRE/post_process/tone_map.hpp index 9c7488ad..79b90dc9 100644 --- a/src/CRE/post_process/tone_map.hpp +++ b/src/CRE/post_process/tone_map.hpp @@ -43,6 +43,8 @@ struct post_process_tone_map_data { float_t lens_flare_appear_power; bool update; bool update_tex; + + post_process_tone_map_data(); }; struct post_process_tone_map { diff --git a/src/CRE/pv_db.cpp b/src/CRE/pv_db.cpp index dc75cb71..f9da3635 100644 --- a/src/CRE/pv_db.cpp +++ b/src/CRE/pv_db.cpp @@ -775,7 +775,7 @@ namespace pv_db { if (!kv.has_key(buf) || !kv.open_scope(buf)) return false; - size_t base_scope_index = kv.curr_scope - kv.scope.data();; + size_t base_scope_index = kv.curr_scope - kv.scope.data(); std::string song_name; if (!kv.read("song_name", song_name)) { @@ -1777,7 +1777,7 @@ namespace pv_db { if (!kv.open_scope_fmt("%02d", k)) continue; - pv_db_pv_field field;; + pv_db_pv_field field; const char* stage; if (kv.read("stage", stage)) diff --git a/src/CRE/pv_expression.cpp b/src/CRE/pv_expression.cpp index 8905321c..2a84ec9a 100644 --- a/src/CRE/pv_expression.cpp +++ b/src/CRE/pv_expression.cpp @@ -37,7 +37,7 @@ struct pv_expression { bool set_motion(uint32_t, int32_t motion_id); }; -pv_expression pv_expression_array[6]; +pv_expression pv_expression_array[ROB_CHARA_COUNT]; extern render_context* rctx_ptr; @@ -178,6 +178,7 @@ void pv_expression_file_unload(const char* file) { i->file_handler.free_data(); } + delete i; pv_expression_file_storage.erase(pv_expression_file_storage.begin() + (&i - pv_expression_file_storage.data())); diff --git a/src/CRE/pv_param.cpp b/src/CRE/pv_param.cpp index 163ef593..14e4a67d 100644 --- a/src/CRE/pv_param.cpp +++ b/src/CRE/pv_param.cpp @@ -6,6 +6,7 @@ #include "pv_param.hpp" #include "post_process.hpp" #include "render_context.hpp" +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/str_utils.hpp" extern render_context* rctx_ptr; @@ -100,13 +101,13 @@ namespace pv_param { char* buf; char** lines; size_t count; - if (!str_utils_text_file_parse(data.c_str(), data.size(), &buf, &lines, &count)) + if (!str_utils_text_file_parse(data.c_str(), data.size(), buf, lines, count)) return false; if (count <= 1 || str_utils_compare(lines[0], "ID,ColorR,ColorG,ColorB,BrightpassR,BrightpassG,BrightpassB,Range")) { - free(buf); - free(lines); + free_def(buf); + free_def(lines); return false; } @@ -128,8 +129,8 @@ namespace pv_param { lines--; - free(buf); - free(lines); + free_def(buf); + free_def(lines); return true; } @@ -141,13 +142,13 @@ namespace pv_param { char* buf; char** lines; size_t count; - if (!str_utils_text_file_parse(data.c_str(), data.size(), &buf, &lines, &count)) + if (!str_utils_text_file_parse(data.c_str(), data.size(), buf, lines, count)) return false; if (count <= 1 || str_utils_compare(lines[0], "ID,Hue,Saturation,Lightness,Exposure,GammaR,GammaG,GammaB,Contrast")) { - free(buf); - free(lines); + free_def(buf); + free_def(lines); return false; } @@ -169,8 +170,8 @@ namespace pv_param { lines--; - free(buf); - free(lines); + free_def(buf); + free_def(lines); return true; } @@ -182,13 +183,13 @@ namespace pv_param { char* buf; char** lines; size_t count; - if (!str_utils_text_file_parse(data.c_str(), data.size(), &buf, &lines, &count)) + if (!str_utils_text_file_parse(data.c_str(), data.size(), buf, lines, count)) return false; if (count <= 1 || str_utils_compare(lines[0], "ID,Focus,FocusRange,FuzzingRange,Ratio,Quality")) { - free(buf); - free(lines); + free_def(buf); + free_def(lines); return false; } @@ -210,8 +211,8 @@ namespace pv_param { lines--; - free(buf); - free(lines); + free_def(buf); + free_def(lines); return true; } @@ -410,14 +411,14 @@ namespace pv_param { } static bool load_text_file(void* data, const char* path, const char* file, uint32_t hash) { - stream s; + file_stream s; s.open((std::string(path) + file).c_str(), "rb"); - if (!s.io.stream) - return false; - - *(std::string*)data = s.read_string(s.length); - s.close(); - return true; + if (s.check_not_null()) { + *(std::string*)data = s.read_string(s.length); + s.close(); + return true; + } + return false; } } @@ -459,7 +460,7 @@ namespace pv_param_task { else if (duration < 0.0f) value = data.data_prev.color; else - vec3_lerp_scalar(data.data_prev.color, data.data.color, value, frame / duration); + value = vec3::lerp(data.data_prev.color, data.data.color, frame / duration); rctx_ptr->post_process.blur->set_intensity(value); @@ -509,10 +510,10 @@ namespace pv_param_task { } else { float_t t = frame / duration; - saturation = lerp(data.data_prev.saturation, data.data.saturation, t); - exposure = lerp(data.data_prev.exposure, data.data.exposure, t); - vec3_lerp_scalar(data.data_prev.gamma, data.data.gamma, gamma, t); - contrast = lerp(data.data_prev.contrast, data.data.contrast, t); + saturation = lerp_def(data.data_prev.saturation, data.data.saturation, t); + exposure = lerp_def(data.data_prev.exposure, data.data.exposure, t); + gamma = vec3::lerp(data.data_prev.gamma, data.data.gamma, t); + contrast = lerp_def(data.data_prev.contrast, data.data.contrast, t); } post_process_tone_map* tone_map = rctx_ptr->post_process.tone_map; @@ -536,7 +537,7 @@ namespace pv_param_task { } void PostProcessCtrlCC::CalcToneTrans(float_t value, float_t& tone_trans_start, float_t& tone_trans_end) { - float_t pow = max(value, 0.125f) * 0.5f; + float_t pow = max_def(value, 0.125f) * 0.5f; if (fabsf(value - 2.0f) < 0.000001f) { tone_trans_start = 0.0f; tone_trans_end = 1.0f; @@ -582,7 +583,7 @@ namespace pv_param_task { else if (i.duration <= 0.0) value = i.prev_alpha; else - value = lerp(i.prev_alpha, i.alpha, i.frame / i.duration); + value = lerp_def(i.prev_alpha, i.alpha, i.frame / i.duration); draw_task_flags draw_task_flags; switch (i.type) { @@ -642,7 +643,7 @@ namespace pv_param_task { else if (i.duration <= 0.0) value = i.prev_alpha; else - value = lerp(i.prev_alpha, i.alpha, i.frame / i.duration); + value = lerp_def(i.prev_alpha, i.alpha, i.frame / i.duration); if (callback) callback[index](callback_data[index], index, i.type, value); @@ -707,7 +708,7 @@ namespace pv_param_task { cam->get_view_point(view_point); float_t fov = (float_t)cam->get_fov(); - vec3_distance(trans, view_point, focus); + focus = vec3::distance(trans, view_point); float_t v5 = tanf(fov * DEG_TO_RAD_FLOAT * 0.5f); float_t v6 = focus * 1000.0f; @@ -773,10 +774,10 @@ namespace pv_param_task { } else { float_t t = frame / duration; - focus = lerp(data.data_prev.focus, data.data.focus, t); - focus_range = lerp(data.data_prev.focus_range, data.data.focus_range, t); - fuzzing_range = lerp(data.data_prev.fuzzing_range, data.data.fuzzing_range, t); - ratio = lerp(data.data_prev.ratio, data.data.ratio, t); + focus = lerp_def(data.data_prev.focus, data.data.focus, t); + focus_range = lerp_def(data.data_prev.focus_range, data.data.focus_range, t); + fuzzing_range = lerp_def(data.data_prev.fuzzing_range, data.data.fuzzing_range, t); + ratio = lerp_def(data.data_prev.ratio, data.data.ratio, t); } #if DOF_FIX diff --git a/src/CRE/random.cpp b/src/CRE/random.cpp index fd26cc80..6375aedc 100644 --- a/src/CRE/random.cpp +++ b/src/CRE/random.cpp @@ -15,17 +15,17 @@ RandState::~RandState() { } -inline void rand_state_array_init() { +void rand_state_array_init() { rand_state_array = new RandState[5]; } -inline RandState* rand_state_array_get(int32_t id) { +RandState* rand_state_array_get(int32_t id) { if (id > -1 && id < 5) return &rand_state_array[id]; return 0; } -inline float_t rand_state_array_get_float(int32_t id) { +float_t rand_state_array_get_float(int32_t id) { RandState* rand_state = rand_state_array_get(id); if (rand_state) { std::uniform_int_distribution dis; @@ -34,7 +34,7 @@ inline float_t rand_state_array_get_float(int32_t id) { return 0.0f; } -inline uint32_t rand_state_array_get_int(int32_t id) { +uint32_t rand_state_array_get_int(int32_t id) { RandState* rand_state = rand_state_array_get(id); if (rand_state) { std::uniform_int_distribution dis; @@ -43,7 +43,7 @@ inline uint32_t rand_state_array_get_int(int32_t id) { return 0; } -inline uint32_t rand_state_array_get_int(uint32_t min, uint32_t max, int32_t id) { +uint32_t rand_state_array_get_int(uint32_t min, uint32_t max, int32_t id) { uint64_t _min = min; uint64_t _max = max; RandState* rand_state = rand_state_array_get(id); @@ -54,6 +54,6 @@ inline uint32_t rand_state_array_get_int(uint32_t min, uint32_t max, int32_t id) return 0; } -inline void rand_state_array_free() { +void rand_state_array_free() { delete[] rand_state_array; } diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 88ecb20b..347f3a1d 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -10,6 +10,7 @@ #include "draw_task.hpp" #include "file_handler.hpp" #include "shader_ft.hpp" +#include "sound.hpp" #include "stage.hpp" float_t delta_frame_history = 0; @@ -24,7 +25,7 @@ sss_data::sss_data() : init(), enable(), npr_contour(), param() { npr_contour = true; param = { 0.0f, 0.0f, 0.0f, 1.0f }; - textures[0].init(640, 360, 0, GL_RGBA16F, GL_DEPTH24_STENCIL8); + textures[0].init(640, 360, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F); textures[1].init(320, 180, 0, GL_RGBA16F, GL_ZERO); textures[2].init(320, 180, 0, GL_RGBA16F, GL_ZERO); textures[3].init(320, 180, 0, GL_RGBA16F, GL_ZERO); @@ -46,8 +47,8 @@ field_2F8(), sss_texture(), npr_param(), field_31C(), field_31D(), field_31E(), alpha_z_sort = true; for (bool& i : draw_pass_3d) i = true; - reflect_texture.init(512, 256, 0, GL_RGBA16F, GL_DEPTH24_STENCIL8); - refract_texture.init(512, 256, 0, GL_RGBA8, GL_DEPTH24_STENCIL8); + reflect_texture.init(512, 256, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F); + refract_texture.init(512, 256, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F); shadow_ptr = new ::shadow; if (shadow_ptr) shadow_ptr->init_data(); @@ -99,9 +100,9 @@ texture_transform_struct::texture_transform_struct(uint32_t id, mat4& mat) : id( } light_proj::light_proj(int32_t width, int32_t height) : enable(), texture_id() { - shadow_texture[0].init(2048, 512, 0, GL_R32F, GL_DEPTH24_STENCIL8); + shadow_texture[0].init(2048, 512, 0, GL_R32F, GL_DEPTH_COMPONENT32F); shadow_texture[1].init(2048, 512, 0, GL_R32F, GL_ZERO); - draw_texture.init(width, height, 0, GL_RGBA8, GL_DEPTH24_STENCIL8); + draw_texture.init(width, height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F); } light_proj::~light_proj() { @@ -112,7 +113,7 @@ void light_proj::resize(int32_t width, int32_t height) { if (!this) return; - draw_texture.init(width, height, 0, GL_RGBA8, GL_DEPTH24_STENCIL8); + draw_texture.init(width, height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F); } bool light_proj::set(render_context* rctx) { @@ -183,16 +184,13 @@ bool light_proj::set_mat(render_context* rctx, bool set_mat) { data->get_position(position); data->get_spot_direction(spot_direction); - float_t length; - vec3_length_squared(spot_direction, length); - if (length <= 0.000001f) + if (vec3::length_squared(spot_direction) <= 0.000001f) return false; float_t spot_cutoff = data->get_spot_cutoff(); float_t fov = atanf(tanf(spot_cutoff * DEG_TO_RAD_FLOAT) * 0.25f) * (RAD_TO_DEG_FLOAT * 2.0f); - vec3 interest; - vec3_add(position, spot_direction, interest); + vec3 interest = position + spot_direction; if (set_mat) { mat4 mat; get_proj_mat(&position, &interest, fov, &mat); @@ -215,7 +213,7 @@ object_data_buffer::object_data_buffer() { } object_data_buffer::~object_data_buffer() { - free(data); + free_def(data); } draw_task* object_data_buffer::add_draw_task(draw_task_type type) { @@ -297,15 +295,33 @@ void object_data::add_vertex_array(draw_object* draw) { GLuint array_buffer = draw->array_buffer; GLuint morph_array_buffer = draw->morph_array_buffer; + int32_t texcoord_array[2] = { -1, -1 }; + int32_t color_tex_index = 0; + for (obj_material_texture_data& i : material->material.texdata) { + if (i.tex_index == -1) + continue; + + int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( + i.shader_info.m.tex_type, color_tex_index); + if (texcoord_index < 0) + continue; + + texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; + + if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + color_tex_index++; + } + object_data_vertex_array* vertex_array_data = 0; for (object_data_vertex_array& i : vertex_array_cache) - if (i.alive_time >= 0 && i.array_buffer == array_buffer && i.morph_array_buffer == morph_array_buffer) { + if (i.alive_time >= 0 && i.array_buffer == array_buffer && i.morph_array_buffer == morph_array_buffer + && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) { if (!i.vertex_array) { vertex_array_data = &i; break; } - i.alive_time = 60; + i.alive_time = 2; return; } @@ -327,7 +343,8 @@ void object_data::add_vertex_array(draw_object* draw) { vertex_array_data->array_buffer = array_buffer; vertex_array_data->morph_array_buffer = morph_array_buffer; - vertex_array_data->alive_time = 60; + vertex_array_data->alive_time = 2; + memcpy(&vertex_array_data->texcoord_array, texcoord_array, sizeof(texcoord_array)); bool compressed = mesh->attrib.m.compressed; GLsizei size_vertex = (GLsizei)mesh->size_vertex; @@ -339,15 +356,26 @@ void object_data::add_vertex_array(draw_object* draw) { size_t offset = 0; if (vertex_format & OBJ_VERTEX_POSITION) { - glEnableVertexAttribArray(0); + if (!vertex_array_data->vertex_attrib_array[0]) { + glEnableVertexAttribArray(0); + vertex_array_data->vertex_attrib_array[0] = true; + } + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 12; } - else + else if (vertex_array_data->vertex_attrib_array[0]) { + glDisableVertexAttribArray(0); glVertexAttrib4f(0, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[0] = false; + } if (vertex_format & OBJ_VERTEX_NORMAL) { - glEnableVertexAttribArray(2); + if (!vertex_array_data->vertex_attrib_array[2]) { + glEnableVertexAttribArray(2); + vertex_array_data->vertex_attrib_array[2] = true; + } + if (!compressed) { glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 12; @@ -357,11 +385,18 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 8; } } - else + else if (vertex_array_data->vertex_attrib_array[2]) { + glDisableVertexAttribArray(2); glVertexAttrib4f(2, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[2] = false; + } if (vertex_format & OBJ_VERTEX_TANGENT) { - glEnableVertexAttribArray(6); + if (!vertex_array_data->vertex_attrib_array[6]) { + glEnableVertexAttribArray(6); + vertex_array_data->vertex_attrib_array[6] = true; + } + if (!compressed) { glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 16; @@ -371,42 +406,40 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 8; } } - else - glVertexAttrib4f(5, 0.0f, 0.0f, 0.0f, 1.0f); + else if (vertex_array_data->vertex_attrib_array[6]) { + glDisableVertexAttribArray(6); + glVertexAttrib4f(6, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[6] = false; + } if (!compressed && vertex_format & OBJ_VERTEX_BINORMAL) offset += 12; - bool texture_vertex_attrib_array_set[4] = { false }; - for (int32_t i = 0, j = 0, l = 0; i < 4; i++) { - if (material->material.texdata[i].tex_index == -1) + for (int32_t i = 0; i < 2; i++) { + int32_t texcoord_index = texcoord_array[i]; + if (texcoord_index < 0) { + if (vertex_array_data->vertex_attrib_array[8 + i]) { + glDisableVertexAttribArray(8 + i); + glVertexAttrib4f(8 + i, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[8 + i] = false; + } continue; - - int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( - material->material.texdata[i].shader_info.m.tex_type, j); - if (texcoord_index < 0) - continue; - - if (material->material.texdata[i].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) - j++; - - if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << sub_mesh->uv_index[l]) - && !texture_vertex_attrib_array_set[sub_mesh->uv_index[l]]) { - glEnableVertexAttribArray(8 + texcoord_index); - if (!compressed) - glVertexAttribPointer(8 + texcoord_index, 2, GL_FLOAT, GL_FALSE, - size_vertex, (void*)(offset + 8ULL * sub_mesh->uv_index[l])); - else - glVertexAttribPointer(8 + texcoord_index, 2, GL_HALF_FLOAT, GL_FALSE, - size_vertex, (void*)(offset + 4ULL * sub_mesh->uv_index[l])); - texture_vertex_attrib_array_set[sub_mesh->uv_index[l]] = true; } - l++; - } - for (int32_t i = 0; i < 4; i++) - if (!texture_vertex_attrib_array_set[i]) - glVertexAttrib4f(8 + i, 0.0f, 0.0f, 0.0f, 1.0f); + if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << i)) { + if (!vertex_array_data->vertex_attrib_array[8 + i]) { + glEnableVertexAttribArray(8 + i); + vertex_array_data->vertex_attrib_array[8 + i] = true; + } + + if (!compressed) + glVertexAttribPointer(8 + i, 2, GL_FLOAT, GL_FALSE, + size_vertex, (void*)(offset + 8ULL * texcoord_index)); + else + glVertexAttribPointer(8 + i, 2, GL_HALF_FLOAT, GL_FALSE, + size_vertex, (void*)(offset + 4ULL * texcoord_index)); + } + } if (!compressed) { if (vertex_format & OBJ_VERTEX_TEXCOORD0) @@ -430,7 +463,11 @@ void object_data::add_vertex_array(draw_object* draw) { } if (vertex_format & OBJ_VERTEX_COLOR0) { - glEnableVertexAttribArray(3); + if (!vertex_array_data->vertex_attrib_array[3]) { + glEnableVertexAttribArray(3); + vertex_array_data->vertex_attrib_array[3] = true; + } + if (!compressed) { glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 16; @@ -440,14 +477,21 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 8; } } - else + else if (vertex_array_data->vertex_attrib_array[3]) { + glDisableVertexAttribArray(3); glVertexAttrib4f(3, 1.0f, 1.0f, 1.0f, 1.0f); + vertex_array_data->vertex_attrib_array[3] = false; + } if (vertex_format & OBJ_VERTEX_COLOR1) offset += 16; if (vertex_format & OBJ_VERTEX_BONE_DATA) { - glEnableVertexAttribArray(1); + if (!vertex_array_data->vertex_attrib_array[1]) { + glEnableVertexAttribArray(1); + vertex_array_data->vertex_attrib_array[1] = true; + } + if (!compressed) { glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 16; @@ -457,7 +501,11 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 8; } - glEnableVertexAttribArray(15); + if (!vertex_array_data->vertex_attrib_array[15]) { + glEnableVertexAttribArray(15); + vertex_array_data->vertex_attrib_array[15] = true; + } + if (!compressed) { glVertexAttribPointer(15, 4, GL_INT, GL_FALSE, size_vertex, (void*)offset); offset += 16; @@ -468,32 +516,59 @@ void object_data::add_vertex_array(draw_object* draw) { } } else { - glVertexAttrib4f(1, 0.0f, 0.0f, 0.0f, 0.0f); - glVertexAttrib4f(15, 0.0f, 0.0f, 0.0f, 0.0f); + if (vertex_array_data->vertex_attrib_array[1]) { + glDisableVertexAttribArray(1); + glVertexAttrib4f(1, 0.0f, 0.0f, 0.0f, 0.0f); + vertex_array_data->vertex_attrib_array[1] = false; + } + + if (vertex_array_data->vertex_attrib_array[15]) { + glDisableVertexAttribArray(15); + glVertexAttrib4f(15, 0.0f, 0.0f, 0.0f, 0.0f); + vertex_array_data->vertex_attrib_array[15] = false; + } } if (!compressed && vertex_format & OBJ_VERTEX_UNKNOWN) { - glEnableVertexAttribArray(7); + if (!vertex_array_data->vertex_attrib_array[7]) { + glEnableVertexAttribArray(7); + vertex_array_data->vertex_attrib_array[7] = true; + } + glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 16; } - else + else if (vertex_array_data->vertex_attrib_array[7]) { + glDisableVertexAttribArray(7); glVertexAttrib4f(7, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[7] = false; + } if (draw->morph_array_buffer) { gl_state_bind_array_buffer(draw->morph_array_buffer); offset = 0; if (vertex_format & OBJ_VERTEX_POSITION) { - glEnableVertexAttribArray(10); + if (!vertex_array_data->vertex_attrib_array[10]) { + glEnableVertexAttribArray(10); + vertex_array_data->vertex_attrib_array[10] = true; + } + glVertexAttribPointer(10, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 12; } - else + else if (vertex_array_data->vertex_attrib_array[10]) { + glDisableVertexAttribArray(10); glVertexAttrib4f(10, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[10] = false; + } if (vertex_format & OBJ_VERTEX_NORMAL) { - glEnableVertexAttribArray(11); + if (!vertex_array_data->vertex_attrib_array[11]) { + glEnableVertexAttribArray(11); + vertex_array_data->vertex_attrib_array[11] = true; + } + if (!compressed) { glVertexAttribPointer(11, 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 12; @@ -503,11 +578,18 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 8; } } - else + else if (vertex_array_data->vertex_attrib_array[11]) { + glDisableVertexAttribArray(11); glVertexAttrib4f(11, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[11] = false; + } if (vertex_format & OBJ_VERTEX_TANGENT) { - glEnableVertexAttribArray(12); + if (!vertex_array_data->vertex_attrib_array[12]) { + glEnableVertexAttribArray(12); + vertex_array_data->vertex_attrib_array[12] = true; + } + if (!compressed) { glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 16; @@ -517,14 +599,21 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 8; } } - else + else if (vertex_array_data->vertex_attrib_array[12]) { + glDisableVertexAttribArray(12); glVertexAttrib4f(12, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[12] = false; + } if (!compressed && vertex_format & OBJ_VERTEX_BINORMAL) offset += 12; if (vertex_format & OBJ_VERTEX_TEXCOORD0) { - glEnableVertexAttribArray(13); + if (!vertex_array_data->vertex_attrib_array[13]) { + glEnableVertexAttribArray(13); + vertex_array_data->vertex_attrib_array[13] = true; + } + if (!compressed) { glVertexAttribPointer(13, 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 8; @@ -534,11 +623,18 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 4; } } - else + else if (vertex_array_data->vertex_attrib_array[13]) { + glDisableVertexAttribArray(13); glVertexAttrib4f(13, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[13] = false; + } if (vertex_format & OBJ_VERTEX_TEXCOORD1) { - glEnableVertexAttribArray(14); + if (!vertex_array_data->vertex_attrib_array[14]) { + glEnableVertexAttribArray(14); + vertex_array_data->vertex_attrib_array[14] = true; + } + if (!compressed) { glVertexAttribPointer(14, 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 8; @@ -548,8 +644,11 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 4; } } - else + else if (vertex_array_data->vertex_attrib_array[14]) { + glDisableVertexAttribArray(14); glVertexAttrib4f(14, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[14] = false; + } if (!compressed) { if (vertex_format & OBJ_VERTEX_TEXCOORD2) @@ -567,7 +666,11 @@ void object_data::add_vertex_array(draw_object* draw) { if (vertex_format & OBJ_VERTEX_COLOR0) { uniform_value[U_MORPH_COLOR] = 1; - glEnableVertexAttribArray(5); + if (!vertex_array_data->vertex_attrib_array[5]) { + glEnableVertexAttribArray(5); + vertex_array_data->vertex_attrib_array[5] = true; + } + if (!compressed) { glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); offset += 16; @@ -577,8 +680,11 @@ void object_data::add_vertex_array(draw_object* draw) { offset += 8; } } - else + else if (vertex_array_data->vertex_attrib_array[5]) { + glDisableVertexAttribArray(5); glVertexAttrib4f(5, 1.0f, 1.0f, 1.0f, 1.0f); + vertex_array_data->vertex_attrib_array[5] = false; + } if (!compressed) { if (vertex_format & OBJ_VERTEX_COLOR1) @@ -594,9 +700,45 @@ void object_data::add_vertex_array(draw_object* draw) { if (vertex_format & OBJ_VERTEX_BONE_DATA) offset += 16; } - - shaders_ft.env_vert_set(13, draw->morph_value, 1.0f - draw->morph_value, 0.0f, 0.0f); } + else { + if (vertex_array_data->vertex_attrib_array[10]) { + glDisableVertexAttribArray(10); + glVertexAttrib4f(10, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[10] = false; + } + + if (vertex_array_data->vertex_attrib_array[11]) { + glDisableVertexAttribArray(11); + glVertexAttrib4f(11, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[11] = false; + } + + if (vertex_array_data->vertex_attrib_array[12]) { + glDisableVertexAttribArray(12); + glVertexAttrib4f(12, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[12] = false; + } + + if (vertex_array_data->vertex_attrib_array[13]) { + glDisableVertexAttribArray(13); + glVertexAttrib4f(13, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[13] = false; + } + + if (vertex_array_data->vertex_attrib_array[14]) { + glDisableVertexAttribArray(14); + glVertexAttrib4f(14, 0.0f, 0.0f, 0.0f, 1.0f); + vertex_array_data->vertex_attrib_array[14] = false; + } + + if (vertex_array_data->vertex_attrib_array[5]) { + glDisableVertexAttribArray(5); + glVertexAttrib4f(5, 1.0f, 1.0f, 1.0f, 1.0f); + vertex_array_data->vertex_attrib_array[5] = false; + } + } + gl_state_bind_array_buffer(0); gl_state_bind_vertex_array(0); gl_state_bind_element_array_buffer(0); @@ -611,9 +753,35 @@ void object_data::check_vertex_arrays() { } } -GLuint object_data::get_vertex_array(GLuint array_buffer, GLuint morph_array_buffer) { +GLuint object_data::get_vertex_array(draw_object* draw) { + obj_mesh* mesh = draw->mesh; + obj_sub_mesh* sub_mesh = draw->sub_mesh; + obj_material_data* material = draw->material; + + GLuint array_buffer = draw->array_buffer; + GLuint morph_array_buffer = draw->morph_array_buffer; + + int32_t texcoord_array[2] = { -1, -1 }; + int32_t color_tex_index = 0; + for (obj_material_texture_data& i : material->material.texdata) { + if (i.tex_index == -1) + continue; + + int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( + i.shader_info.m.tex_type, color_tex_index); + if (texcoord_index < 0) + continue; + + texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; + + if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + color_tex_index++; + } + + object_data_vertex_array* vertex_array_data = 0; for (object_data_vertex_array& i : vertex_array_cache) - if (i.alive_time > 0 && i.array_buffer == array_buffer && i.morph_array_buffer == morph_array_buffer) + if (i.alive_time > 0 && i.array_buffer == array_buffer && i.morph_array_buffer == morph_array_buffer + && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) return i.vertex_array; return 0; } @@ -836,7 +1004,7 @@ void render_context::ctrl() { rctx_ptr = this; app::TaskWork::Ctrl(); - + sound_ctrl(); file_handler_storage_ctrl(); draw_pass.shadow_ptr->ctrl(this); @@ -1006,7 +1174,7 @@ void render_context::light_param_data_ibl_set( light_data* l = &set->lights[LIGHT_CHARA]; l->get_position(pos); - vec3_length(pos, len); + len = vec3::length(pos); if (fabsf(len - 1.0f) < 0.02f) l->set_position(ibl->lit_dir[0]); @@ -1016,7 +1184,7 @@ void render_context::light_param_data_ibl_set( l = &set->lights[LIGHT_STAGE]; l->get_position(pos); - vec3_length(pos, len); + len = vec3::length(pos); if (fabsf(len - 1.0f) < 0.02f) l->set_position(ibl->lit_dir[1]); @@ -1081,8 +1249,7 @@ field_1A8(), view_point_shared(), interest_shared(), field_2F0() { field_2E0 = 0.05f; ambient = 0.4f; field_2EC = 0; - direction = { 0.0f, -1.0f, -1.0f }; - vec3_mult_scalar(direction, 1.0f / sqrtf(2.0f), direction); + direction = vec3(0.0f, -1.0f, -1.0f) * (1.0f / sqrtf(2.0f)); field_2E8 = false; self_shadow = true; blur_filter_enable[0] = true; @@ -1107,14 +1274,12 @@ void shadow::ctrl(render_context* rctx) { light_data* data = &set->lights[LIGHT_CHARA]; vec3 position; - float_t length; data->get_position(position); - vec3_negate(position, position); - vec3_length(position, length); - if (length < 0.000001) + float_t length = vec3::length(position); + if (length < 0.000001f) direction = { 0.0f, 1.0f, 0.0f }; else - vec3_mult_scalar(position, 1.0f / length, direction); + direction = -position * (1.0f / length); for (int32_t i = 0; i < 2; i++) if (draw_task_get_count(rctx, (draw_object_type)((int32_t)DRAW_OBJECT_SHADOW_CHARA + i))) @@ -1140,23 +1305,18 @@ void shadow::ctrl(render_context* rctx) { vec3 v7 = vec3_null; for (vec3& j : field_1D0[i]) - vec3_add(v7, j, v7); + v7 += j; float_t v14 = (float_t)(int32_t)field_1D0[i].size(); if (v14 < 0.0f) v14 += 1.8446744e19f; - vec3_mult_scalar(v7, 1.0f / v14, v7); + v7 *= 1.0f / v14; float_t v15 = 0.0f; for (vec3& j : field_1D0[i]) { - vec3 v22; - vec3_sub(v7, j, v22); - float_t v23; - vec3_dot(v22, direction, v23); - vec3 v25; - vec3_mult_scalar(direction, v23, v25); - float_t v24; - vec3_distance(v25, v22, v24); + vec3 v22 = v7 - j; + vec3 v25 = direction * vec3::dot(v22, direction); + float_t v24 = vec3::distance(v25, v22); v24 -= 0.25f; if (v24 < 0.0f) v24 = 0.0f; @@ -1174,49 +1334,35 @@ void shadow::ctrl(render_context* rctx) { if (!field_2F0[i]) continue; - vec3 v11; - vec3_mult_scalar(direction, field_208, v11); - vec3_sub(field_1A8[i], v11, v11); - float_t v9; - vec3_distance(this->view_point[i], v11, v9); - - float_t v12; - vec3_distance(this->interest[i], field_1A8[i], v12); + vec3 v11 = field_1A8[i] - direction * field_208; + float_t v9 = vec3::distance(this->view_point[i], v11); + float_t v12 = vec3::distance(this->interest[i], field_1A8[i]); if (v9 > 0.1f || v12 > 0.1f) { this->view_point[i] = v11; this->interest[i] = field_1A8[i]; } - vec3_add(view_point, this->view_point[i], view_point); - vec3_add(interest, this->interest[i], interest); + view_point += this->view_point[i]; + interest += this->interest[i]; } - vec3_mult_scalar(view_point, 1.0f / field_2EC, view_point_shared); - vec3_mult_scalar(interest, 1.0f / field_2EC, interest_shared); + view_point_shared = view_point * (1.0f / field_2EC); + interest_shared = interest * (1.0f / field_2EC); } - float_t v2 = max(field_1C8[0], field_1C8[1]); + float_t v2 = max_def(field_1C8[0], field_1C8[1]); field_2F5 = false; view_region = v2 + 1.2f; field_200[0] = 0; field_200[1] = 1; if (field_2EC >= 2) { - vec3 v12; - vec3_sub(field_1A8[0], interest_shared, v12); + vec3 v12 = field_1A8[0] - interest_shared; + vec3 v14 = field_1A8[1] - interest_shared; + float_t v15 = vec3::dot(v12, direction); - vec3 v14; - vec3_sub(field_1A8[1], interest_shared, v14); + vec3 v6 = direction * v15 - v12; - float_t v15; - vec3_dot(v12, direction, v15); - - vec3 v6; - vec3_mult_scalar(direction, v15, v6); - vec3_sub(v6, v12, v6); - - float_t v16; - vec3_length(v6, v16); - v16 -= 0.25f; + float_t v16 = vec3::length(v6) - 0.25f; if (v16 < 0.0f) v16 = 0.0f; @@ -1227,11 +1373,7 @@ void shadow::ctrl(render_context* rctx) { else view_region = v2 + 1.2f + v16; - float_t t3; - float_t t4; - vec3_dot(v12, direction, t3); - vec3_dot(v14, direction, t4); - if (t3 < t4) { + if (vec3::dot(v12, direction) < vec3::dot(v14, direction)) { field_200[1] = 0; field_200[0] = 1; } @@ -1241,11 +1383,9 @@ void shadow::ctrl(render_context* rctx) { vec3 v3; vec3 v86; if (direction.y * direction.y < 0.99f) { - vec3 up = { 0.0f, 1.0f, 0.0f }; - vec3_cross(direction, up, v86); - vec3_cross(v86, direction, v3); - vec3_normalize(v3, v3); - vec3_normalize(v86, v86); + v86 = vec3::cross(direction, vec3(0.0f, 1.0f, 0.0f)); + v3 = vec3::normalize(vec3::cross(v86, direction)); + v86 = vec3::normalize(v86); } else { v3 = { 0.0f, 0.0f, 1.0f }; @@ -1260,7 +1400,7 @@ void shadow::ctrl(render_context* rctx) { vec3 v22 = vec3_null; for (vec3& j : field_1D0[i]) - vec3_add(v22, j, v22); + v22 += j; int32_t v27 = (int32_t)field_1D0[i].size(); float_t v29 = (float_t)v27; @@ -1268,18 +1408,12 @@ void shadow::ctrl(render_context* rctx) { v29 += 1.8446744e19f; float_t v30 = 0.0f; - vec3 v31; - vec3_mult_scalar(v22, 1.0f / v29, v31); + vec3 v31 = v22 * (1.0f / v29); for (vec3& j : field_1D0[i]) { - vec3 v34; - vec3_sub(v31, j, v34); - float_t v38; - float_t v39; - vec3_dot(v34, v3, v38); - vec3_dot(v34, v86, v39); - v38 = fabsf(v38); - v39 = fabsf(v39); + vec3 v34 = v31 - j; + float_t v38 = fabsf(vec3::dot(v34, v3)); + float_t v39 = fabsf(vec3::dot(v34, v86)); if (v39 >= v38) v38 = v39; if (v30 < v38) @@ -1294,13 +1428,9 @@ void shadow::ctrl(render_context* rctx) { if (!field_2F0[i]) continue; - float_t v51; - vec3 v53; - float_t v54; - vec3_mult_scalar(direction, field_208, v53); - vec3_sub(field_1A8[i], v53, v53); - vec3_distance(view_point[i], v53, v51); - vec3_distance(interest[i], field_1A8[i], v54); + vec3 v53 = field_1A8[i] - direction * field_208; + float_t v51 = vec3::distance(view_point[i], v53); + float_t v54 = vec3::distance(interest[i], field_1A8[i]); if (v51 > 0.1f || v54 > 0.1f) { view_point[i] = v53; interest[i] = field_1A8[i]; @@ -1312,47 +1442,40 @@ void shadow::ctrl(render_context* rctx) { int32_t count = 0; for (int32_t i = 0; i < 2; i++) { int32_t c = (int32_t)field_1D0[i].size(); - vec3 view_point_temp; - vec3 interest_temp; - vec3_mult_scalar(this->view_point[i], (float_t)c, view_point_temp); - vec3_mult_scalar(this->interest[i], (float_t)c, interest_temp); - vec3_add(view_point, view_point_temp, view_point); - vec3_add(interest, interest_temp, interest); + view_point += this->view_point[i] * (float_t)c; + interest += this->interest[i] * (float_t)c; count += c; } - vec3_mult_scalar(view_point, 1.0f / (float_t)count, view_point_shared); - vec3_mult_scalar(interest, 1.0f / (float_t)count, interest_shared); + view_point_shared = view_point * (1.0f / (float_t)count); + interest_shared = interest * (1.0f / (float_t)count); } - float_t v2 = 0.0; - float_t v67 = max(field_1C8[0], field_1C8[1]); + float_t v2 = 0.0f; + float_t v67 = max_def(field_1C8[0], field_1C8[1]); field_2F5 = false; view_region = v67 + 1.2f; field_200[0] = 0; field_200[1] = 1; if (field_2EC >= 2) { - float_t v68 = 0.0; - float_t v69 = 0.0; - float_t v70 = 0.0; + float_t v68 = 0.0f; + float_t v69 = 0.0f; + float_t v70 = 0.0f; for (int32_t i = 0; i < 2; i++) { if (!field_2F0[i]) continue; for (vec3& j : field_1D0[i]) { - vec3 v74; - vec3_sub(j, interest_shared, v74); + vec3 v74 = j - interest_shared; - float_t v77; - vec3_dot(v74, v86, v77); - if (v77 < v2) + float_t v77 = vec3::dot(v74, v86); + if (v2 > v77) v2 = v77; else if (v69 < v77) v69 = v77; - float_t v78; - vec3_dot(v74, v3, v78); - if (v78 < v68) + float_t v78 = vec3::dot(v74, v3); + if (v68 > v78) v68 = v78; else if (v70 < v78) v70 = v78; @@ -1374,15 +1497,8 @@ void shadow::ctrl(render_context* rctx) { else view_region = v79 + 1.2f; - vec3 interest_chara; - vec3 interest_stage; - float_t interest_chara_cos; - float_t interest_stage_cos; - vec3_sub(field_1A8[0], interest_shared, interest_chara); - vec3_dot(interest_chara, direction, interest_chara_cos); - vec3_sub(field_1A8[1], interest_shared, interest_stage); - vec3_dot(interest_stage, direction, interest_stage_cos); - if (interest_chara_cos < interest_stage_cos) { + if (vec3::dot(field_1A8[0] - interest_shared, direction) + < vec3::dot(field_1A8[1] - interest_shared, direction)) { field_200[1] = 0; field_200[0] = 1; } @@ -1401,7 +1517,7 @@ int32_t shadow::init_data() { GLenum color_format; GLenum depth_format; } init_params[] = { - { 0x800, 0x800, 0, GL_RGBA8, GL_DEPTH24_STENCIL8 }, + { 0x800, 0x800, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F }, { 0x200, 0x200, 3, GL_RGBA8, GL_ZERO }, { 0x200, 0x200, 3, GL_RGBA8, GL_ZERO }, { 0x800, 0x800, 0, GL_R32F, GL_ZERO }, diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index 15c72816..f737a586 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -441,6 +441,8 @@ struct object_data_vertex_array { GLuint morph_array_buffer; int32_t alive_time; GLuint vertex_array; + bool vertex_attrib_array[16]; + int32_t texcoord_array[2]; }; struct object_data { @@ -480,7 +482,7 @@ struct object_data { void add_vertex_array(draw_object* draw); void check_vertex_arrays(); - GLuint get_vertex_array(GLuint array_buffer, GLuint morph_array_buffer); + GLuint get_vertex_array(draw_object* draw); bool get_chara_color(); ::draw_task_flags get_draw_task_flags(); void get_material_list(int32_t& count, material_list_struct*& value); diff --git a/src/CRE/render_texture.cpp b/src/CRE/render_texture.cpp index 849ba8bf..056c9fc4 100644 --- a/src/CRE/render_texture.cpp +++ b/src/CRE/render_texture.cpp @@ -78,7 +78,7 @@ int32_t render_texture::init(int32_t width, int32_t height, if (max_level < 0) return -1; - max_level = min(max_level, 15); + max_level = min_def(max_level, 15); if (max_level < 0) return 0; free_data(); @@ -158,8 +158,8 @@ void render_texture::draw_custom_glsl() { void render_texture::draw_params(shader_set_data* set, int32_t width, int32_t height, float_t scale, float_t param_x, float_t param_y, float_t param_z, float_t param_w) { - float_t w = (float_t)max(width, 1); - float_t h = (float_t)max(height, 1); + float_t w = (float_t)max_def(width, 1); + float_t h = (float_t)max_def(height, 1); set->local_vert_set(0, scale / w, scale / h, w, h); set->local_frag_set(0, scale / w, scale / h, w, h); set->local_vert_set(3, param_x, param_y, param_z, param_w); @@ -211,7 +211,7 @@ void render_texture_data_init() { "layout(binding = 0) uniform sampler2D g_color;\n" "\n" "void main() {\n" - " result = texture(g_color, frg.texcoord); \n" + " result = texture(g_color, frg.texcoord);\n" "}\n"; shader_glsl_param param = {}; diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index b08a9b2e..2b6fc7a3 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -177,9 +177,8 @@ static const exp_func_op3 exp_func_op3_array[] = { osage_setting osage_setting_data; size_t qword_140FBDF88 = 0; - -static const int32_t rob_cloth_update_vertices_flags = 0x03; -static const bool rob_cloth_update_normals_select = false; +int32_t rob_cloth_update_vertices_flags = 0x03; +bool rob_cloth_update_normals_select = false; ExNodeBlock::ExNodeBlock() : bone_node_ptr(), type(), name(), parent_bone_node(), parent_name(), parent_node(), item_equip_object(), field_58(), field_59(), has_children_node() { @@ -337,10 +336,10 @@ skin_param_hinge::~skin_param_hinge() { } void skin_param_hinge::limit() { - ymin = max(ymin, -179.0f) * DEG_TO_RAD_FLOAT; - ymax = min(ymax, 179.0f) * DEG_TO_RAD_FLOAT; - zmin = max(zmin, -179.0f) * DEG_TO_RAD_FLOAT; - zmax = min(zmax, 179.0f) * DEG_TO_RAD_FLOAT; + ymin = max_def(ymin, -179.0f) * DEG_TO_RAD_FLOAT; + ymax = min_def(ymax, 179.0f) * DEG_TO_RAD_FLOAT; + zmin = max_def(zmin, -179.0f) * DEG_TO_RAD_FLOAT; + zmax = min_def(zmax, 179.0f) * DEG_TO_RAD_FLOAT; } skin_param_osage_node::skin_param_osage_node() : coli_r(0.0f), weight(1.0f), inertial_cancel(0.0f) { @@ -1559,8 +1558,8 @@ void RobOsage::SetForce(float_t force, float_t force_gain) { } void RobOsage::SetHinge(float_t hinge_y, float_t hinge_z) { - hinge_y = min(hinge_y, 179.0f); - hinge_z = min(hinge_z, 179.0f); + hinge_y = min_def(hinge_y, 179.0f); + hinge_z = min_def(hinge_z, 179.0f); hinge_y = hinge_y * DEG_TO_RAD_FLOAT; hinge_z = hinge_z * DEG_TO_RAD_FLOAT; RobOsageNode* i_begin = nodes.data() + 1; @@ -1716,8 +1715,8 @@ void RobOsage::SetOsagePlayData(mat4* parent_mat, for (RobOsageNode* j = j_begin; j != j_end; j++) { float_t rot_y = j->field_1B0.field_0.rotation.y; float_t rot_z = j->field_1B0.field_0.rotation.z; - rot_y = clamp(rot_y, (float_t)-M_PI, (float_t)M_PI); - rot_z = clamp(rot_z, (float_t)-M_PI, (float_t)M_PI); + rot_y = clamp_def(rot_y, (float_t)-M_PI, (float_t)M_PI); + rot_z = clamp_def(rot_z, (float_t)-M_PI, (float_t)M_PI); mat4_rotate_z_mult(&v85, rot_z, &v85); mat4_rotate_y_mult(&v85, rot_y, &v85); j->bone_node_ptr->exp_data.parent_scale = parent_scale; @@ -1920,7 +1919,7 @@ void ExOsageBlock::Field_50() { rob.ColiSet(mats); sub_14047C770(&rob, parent_bone_node->ex_data_mat, &parent_scale, step, 1); float_t step = 0.5f * this->step; - this->step = max(step, 1.0f); + this->step = max_def(step, 1.0f); } void ExOsageBlock::Field_58() { @@ -2288,11 +2287,11 @@ void ExConstraintBlock::sub_1401EB410(mat4* mat, vec3* a2, vec3* target_offset) float_t v18; vec3_dot(v3, v4, v18); - v18 = clamp(v18, -1.0f, 1.0f); + v18 = clamp_def(v18, -1.0f, 1.0f); float_t v19 = 1.0f - v18; float_t v20 = 1.0f - v18 * v18; - v20 = sqrtf(clamp(v20, 0.0f, 1.0f)); + v20 = sqrtf(clamp_def(v20, 0.0f, 1.0f)); sub_1405F10D0(mat, &v13, v18, v20); } @@ -2440,7 +2439,7 @@ void ExExpressionBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, std::string value_type; expression = str_utils_get_next_string(expression, value_type, ' '); if (!value_type.size() || !memcmp(value_type.c_str(), "error", - min(value_type.size(), 5)) && value_type.size() == 5) + min_def(value_type.size(), 5)) && value_type.size() == 5) break; if (value_type[0] == 'n') { @@ -2616,7 +2615,7 @@ void skin_param_osage_root_parse(void* kv, const char* name, float_t air_res = 0.0f; if (_kv->read("air_res", air_res)) - skp_root.air_res = min(air_res, 0.9f); + skp_root.air_res = min_def(air_res, 0.9f); float_t rot_y = 0.0f; float_t rot_z = 0.0f; @@ -3016,11 +3015,11 @@ static float_t exp_lt(float_t v1, float_t v2) { } static float_t exp_max(float_t v1, float_t v2) { - return max(v1, v2); + return max_def(v1, v2); } static float_t exp_min(float_t v1, float_t v2) { - return min(v1, v2); + return min_def(v1, v2); } static float_t exp_mul(float_t v1, float_t v2) { @@ -4029,7 +4028,7 @@ static int32_t sub_140483EA0(vec3* a1, vec3* a2, osage_coli* a3, float_t radius) vec3_dot(v63, a3->bone_pos_diff, v36); v36 *= v25; float_t v37 = v36 * v36; - v37 = min(v37, 1.0f); + v37 = min_def(v37, 1.0f); v22 *= 0.5f; float_t v38 = v22 * v22 - v61; if (v38 < 0.0f) @@ -4468,7 +4467,7 @@ static void sub_140482100(struc_476* a1, opd_blend_data* a2, struc_477* a3) { } static void sub_140482DF0(struc_477* dst, struc_477* src0, struc_477* src1, float_t blend) { - dst->length = lerp(src0->length, src1->length, blend); + dst->length = lerp_def(src0->length, src1->length, blend); vec3_lerp_scalar(src0->rotation, src1->rotation, dst->rotation, blend); } diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index ebd06d1b..9a027ee1 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -14,7 +14,7 @@ #include "../random.hpp" #include "../pv_expression.hpp" #include "../stage.hpp" -#include "../timer.hpp" +#include "../waitable_timer.hpp" struct MotFile { motion_set_info* mot_set_info; @@ -249,6 +249,7 @@ public: ReqData(); ReqData(::chara_index chara_index, int32_t count); virtual ~ReqData(); + virtual void Reset(); }; @@ -259,6 +260,7 @@ public: ReqDataObj(); ReqDataObj(::chara_index chara_index, int32_t count); virtual ~ReqDataObj() override; + virtual void Reset() override; }; @@ -845,7 +847,6 @@ static void osage_play_data_manager_get_opd_file_data(object_info obj_info, static bool pv_osage_manager_array_get_disp(int32_t* chara_id); static PvOsageManager* pv_osage_manager_array_get(int32_t chara_id); -static void pv_osage_manager_array_set_not_reset_true(); static int pv_data_set_motion_quicksort_compare_func(void const* src1, void const* src2); @@ -2219,7 +2220,7 @@ void rob_free() { rob_chara_pv_data_array = 0; } - free(rob_cmn_mottbl_data); + free_def(rob_cmn_mottbl_data); if (rob_thread_handler) { delete rob_thread_handler; @@ -3197,15 +3198,21 @@ static void rob_chara_set_face_motion(rob_chara* rob_chr, static void rob_chara_set_hand_l_motion(rob_chara* rob_chr, RobHandMotion* motion, int32_t type, motion_database* mot_db) { - if (type == 2) + if (type == 2) { rob_chr->data.motion.field_3B0.hand_l.data = motion->data; - else if (type == 1) + if (!(rob_chr->data.motion.field_29 & 0x08) || (rob_chr->data.motion.field_2A & 0x04)) + return; + } + else if (type == 1) { + rob_chr->data.motion.hand_r.data = motion->data; + if ((rob_chr->data.motion.field_29 & 0x08) || !(rob_chr->data.motion.field_2A & 0x04)) + return; + } + else { rob_chr->data.motion.field_150.hand_l.data = motion->data; - else - rob_chr->data.motion.hand_l.data = motion->data; - - if (!(rob_chr->data.motion.field_29 & 0x08) || rob_chr->data.motion.field_2A & 0x04) - return; + if ((rob_chr->data.motion.field_29 & 0x08) || (rob_chr->data.motion.field_2A & 0x04)) + return; + } rob_chara_bone_data_load_hand_l_motion(rob_chr->bone_data, motion->data.motion_id, mot_db); rob_chara_bone_data_set_hand_l_frame(rob_chr->bone_data, motion->data.frame); @@ -3216,15 +3223,21 @@ static void rob_chara_set_hand_l_motion(rob_chara* rob_chr, static void rob_chara_set_hand_r_motion(rob_chara* rob_chr, RobHandMotion* motion, int32_t type, motion_database* mot_db) { - if (type == 2) + if (type == 2) { rob_chr->data.motion.field_3B0.hand_r.data = motion->data; - else if (type == 1) - rob_chr->data.motion.field_150.hand_r.data = motion->data; - else + if (!(rob_chr->data.motion.field_29 & 0x10) || (rob_chr->data.motion.field_2A & 0x08)) + return; + } + else if (type == 1) { rob_chr->data.motion.hand_r.data = motion->data; - - if (!(rob_chr->data.motion.field_29 & 0x10) || rob_chr->data.motion.field_2A & 0x08) - return; + if ((rob_chr->data.motion.field_29 & 0x10) || !(rob_chr->data.motion.field_2A & 0x08)) + return; + } + else { + rob_chr->data.motion.field_150.hand_r.data = motion->data; + if ((rob_chr->data.motion.field_29 & 0x10) || (rob_chr->data.motion.field_2A & 0x08)) + return; + } rob_chara_bone_data_load_hand_r_motion(rob_chr->bone_data, motion->data.motion_id, mot_db); rob_chara_bone_data_set_hand_r_frame(rob_chr->bone_data, motion->data.frame); @@ -3468,10 +3481,10 @@ void rob_chara::set_eyes_mottbl_motion(int32_t type, } static void sub_140553970(rob_chara* rob_chr, object_info a2, int32_t type) { - if (type == 1) - rob_chr->data.motion.field_150.head_object = a2; - else + if (type != 1 && type == 2) rob_chr->data.motion.field_3B0.head_object = a2; + else + rob_chr->data.motion.field_150.head_object = a2; } void rob_chara::set_face_mottbl_motion(int32_t type, @@ -4224,8 +4237,8 @@ static void bone_data_mult_ik(bone_data* a1, int32_t skeleton_select) { rot_cos = (v28 + ik_segment_length) / (2.0f * v10); rot_2nd_cos = (v28 - ik_segment_length) / (2.0f * ik_2nd_segment_length); - rot_cos = clamp(rot_cos, -1.0f, 1.0f); - rot_2nd_cos = clamp(rot_2nd_cos, -1.0f, 1.0f); + rot_cos = clamp_def(rot_cos, -1.0f, 1.0f); + rot_2nd_cos = clamp_def(rot_2nd_cos, -1.0f, 1.0f); rot_sin = sqrtf(1.0f - rot_cos * rot_cos); rot_2nd_sin = sqrtf(1.0f - rot_2nd_cos * rot_2nd_cos); @@ -6192,7 +6205,7 @@ static void motion_blend_mot_set_blend(motion_blend_mot* a1, case MOTION_BLEND_COMBINE: a1->blend = &a1->combine; a1->combine.Reset(); - a1->combine.blend = clamp(blend, 0.0f, 1.0f); + a1->combine.blend = clamp_def(blend, 0.0f, 1.0f); break; } } @@ -6239,11 +6252,6 @@ static PvOsageManager* pv_osage_manager_array_get(int32_t chara_id) { return &pv_osage_manager_array[chara_id]; } -static void pv_osage_manager_array_set_not_reset_true() { - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) - pv_osage_manager_array_get(i)->SetNotReset(true); -} - static int pv_data_set_motion_quicksort_compare_func(void const* src1, void const* src2) { pv_data_set_motion* pv1 = (pv_data_set_motion*)src1; pv_data_set_motion* pv2 = (pv_data_set_motion*)src2; @@ -6375,13 +6383,13 @@ void rob_chara_data_adjust_ctrl(rob_chara* rob_chr, rob_chara_data_adjust* adjus float_t blend = (adjust->transition_frame + 1.0f) / (adjust->force_duration + 1.0f); vec3_lerp_scalar(adjust_prev->curr_external_force, adjust->curr_external_force, adjust->curr_external_force, blend); - adjust->curr_force = lerp(adjust_prev->curr_force, adjust->curr_force, blend); + adjust->curr_force = lerp_def(adjust_prev->curr_force, adjust->curr_force, blend); } if (adjust->strength_transition > adjust->transition_frame && fabsf(adjust->strength_transition - adjust->transition_frame) > 0.000001f) { float_t blend = (adjust->transition_frame + 1.0f) / (adjust->strength_transition + 1.0f); - adjust->curr_strength = lerp(adjust_prev->curr_strength, adjust->curr_strength, blend); + adjust->curr_strength = lerp_def(adjust_prev->curr_strength, adjust->curr_strength, blend); } else if (!transition_frame_step) return; @@ -7831,7 +7839,6 @@ static void sub_140407280(struc_258* a1, std::vector* a2, mat4* mat, vec3_normalize(v67, v67); vec3_mult_scalar(v67, v28, v68); - float_t v39; vec2_length(*(vec2*)&v67, v39); @@ -8300,7 +8307,6 @@ static void rob_chara_set_hand_adjust(rob_chara* rob_chr, switch (adjust->type) { case ROB_CHARA_DATA_HAND_ADJUST_NORMAL: - case 15: adjust->scale = chara_size_table_get_value(1); break; case ROB_CHARA_DATA_HAND_ADJUST_SHORT: @@ -8310,10 +8316,10 @@ static void rob_chara_set_hand_adjust(rob_chara* rob_chr, adjust->scale = chara_size_table_get_value(0); break; case ROB_CHARA_DATA_HAND_ADJUST_MIN: - adjust->scale = min(opposite_chara_scale, chara_scale); + adjust->scale = min_def(opposite_chara_scale, chara_scale); break; case ROB_CHARA_DATA_HAND_ADJUST_MAX: - adjust->scale = max(opposite_chara_scale, chara_scale); + adjust->scale = max_def(opposite_chara_scale, chara_scale); break; case ROB_CHARA_DATA_HAND_ADJUST_OPPOSITE_CHARA: adjust->scale = opposite_chara_scale; @@ -8355,7 +8361,7 @@ static void rob_chara_set_hand_adjust(rob_chara* rob_chr, if (fabsf(prev_scale - scale * adjust->scale_blend) <= 0.000001f || adjust->duration <= adjust->current_time || fabsf(adjust->duration - adjust->current_time) <= 0.000001f) { - adjust->current_scale = lerp(prev_scale, scale, adjust->scale_blend); + adjust->current_scale = lerp_def(prev_scale, scale, adjust->scale_blend); if (fabsf(adjust->current_scale - chara_scale) <= 0.000001f) { adjust->current_scale = chara_scale; adjust->enable = false; @@ -8363,7 +8369,7 @@ static void rob_chara_set_hand_adjust(rob_chara* rob_chr, } else { float_t t = (adjust->current_time + 1.0f) / (adjust->duration + 1.0f); - adjust->current_scale = lerp(prev_scale, scale, t * adjust->scale_blend); + adjust->current_scale = lerp_def(prev_scale, scale, t * adjust->scale_blend); adjust->current_time += rob_chr->data.motion.step_data.frame; } } @@ -8640,7 +8646,7 @@ static bool sub_14053B580(rob_chara* rob_chr, int32_t a2) { float_t v32 = v0.field_8 - v30 + 1.0f; if (fabsf(v32) > 0.000001f) { v31 = (v0.field_8 - v29) / v32; - v31 = clamp(v31, 0.0f, 1.0f); + v31 = clamp_def(v31, 0.0f, 1.0f); } int32_t v33 = v0.field_0; @@ -8786,7 +8792,7 @@ static void sub_1403FA040(vec3* a1, float_t a2, mat4* a3, float_t ymin, if (fabsf(v16.z) > 0.000001f) { vec3_normalize(v16, v16); vec3_mult_scalar(v16, a2, v16); - v16.z = clamp(v16.z, zmin, zmax); + v16.z = clamp_def(v16.z, zmin, zmax); } goto LABEL_66; } @@ -8838,7 +8844,7 @@ static void sub_1403FA040(vec3* a1, float_t a2, mat4* a3, float_t ymin, if (fabsf(v16.y) > 0.000001f) { vec3_normalize(v16, v16); vec3_mult_scalar(v16, a2, v16); - v16.y = clamp(v16.y, ymin, ymax); + v16.y = clamp_def(v16.y, ymin, ymax); } goto LABEL_66; } @@ -9141,7 +9147,7 @@ static void sub_140406920(vec3* a1, bone_data* a2, bone_data* a3, float_t heel_h v12 = 0.0f; a2->ik_target.x = v18.x; - a2->ik_target.y = v18.y + lerp(v12, v11, a5->z); + a2->ik_target.y = v18.y + lerp_def(v12, v11, a5->z); a2->ik_target.z = v18.z; } @@ -9723,10 +9729,11 @@ static void rob_chara_bone_data_interpolate(rob_chara_bone_data* rob_bone_data) } static void rob_chara_bone_data_motion_blend_mot_free(rob_chara_bone_data* rob_bone_data) { - rob_bone_data->motion_indices.clear(); + rob_chara_bone_data_motion_blend_mot_list_free(rob_bone_data, 0); for (motion_blend_mot*& i : rob_bone_data->motions) delete i; rob_bone_data->motions.clear(); + rob_bone_data->motion_indices.clear(); } static void rob_chara_bone_data_motion_blend_mot_init(rob_chara_bone_data* rob_bone_data) { @@ -11925,7 +11932,7 @@ static void rob_chara_set_pv_data(rob_chara* rob_chr, int8_t chara_id, } static void rob_cmn_mottbl_read(void* a1, const void* data, size_t size) { - free(rob_cmn_mottbl_data); + free_def(rob_cmn_mottbl_data); farc f; f.read(data, size, true); @@ -12042,6 +12049,11 @@ bool pv_osage_manager_array_get_disp() { return disp; } +void pv_osage_manager_array_set_not_reset_true() { + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) + pv_osage_manager_array_get(i)->SetNotReset(true); +} + void pv_osage_manager_array_set_pv_id(int32_t chara_id, int32_t pv_id, bool reset) { pv_osage_manager_array_get(chara_id)->SetPvId(pv_id, chara_id, reset); } @@ -12350,11 +12362,11 @@ void MotionBlendCross::Blend(bone_data* a2, bone_data* a3) { break; case BONE_DATABASE_BONE_POSITION_ROTATION: if (field_21) { - a2->trans.x = lerp(a3->trans.x, a2->trans.x, blend); - a2->trans.z = lerp(a3->trans.z, a2->trans.z, blend); + a2->trans.x = lerp_def(a3->trans.x, a2->trans.x, blend); + a2->trans.z = lerp_def(a3->trans.z, a2->trans.z, blend); } if (field_20) - a2->trans.y = lerp(a3->trans.y, a2->trans.y, blend); + a2->trans.y = lerp_def(a3->trans.y, a2->trans.y, blend); break; case BONE_DATABASE_BONE_HEAD_IK_ROTATION: if (a2->motion_bone_index == MOTION_BONE_CL_MUNE) { @@ -12520,11 +12532,11 @@ void MotionBlendFreeze::Blend(bone_data* a2, bone_data* a3) { break; case BONE_DATABASE_BONE_POSITION_ROTATION: if (field_21) { - a2->trans.x = lerp(a2->trans_prev[field_24].x, a2->trans.x, blend); - a2->trans.z = lerp(a2->trans_prev[field_24].z, a2->trans.z, blend); + a2->trans.x = lerp_def(a2->trans_prev[field_24].x, a2->trans.x, blend); + a2->trans.z = lerp_def(a2->trans_prev[field_24].z, a2->trans.z, blend); } if (field_20) - a2->trans.y = lerp(a2->trans_prev[field_24].y, a2->trans.y, blend); + a2->trans.y = lerp_def(a2->trans_prev[field_24].y, a2->trans.y, blend); break; case BONE_DATABASE_BONE_HEAD_IK_ROTATION: if (a2->motion_bone_index == MOTION_BONE_CL_MUNE) { @@ -13248,7 +13260,7 @@ void rob_chara_item_equip_object::reset_external_force() { void rob_chara_item_equip_object::set_alpha_draw_task_flags(float_t alpha, int32_t flags) { draw_task_flags = (::draw_task_flags)flags; - this->alpha = clamp(alpha, 0.0f, 1.0f); + this->alpha = clamp_def(alpha, 0.0f, 1.0f); } bool rob_chara_item_equip_object::set_boc( @@ -14412,6 +14424,21 @@ int32_t expression_id_to_mottbl_index(int32_t expression_id) { return 6; } +/* +195 CMN_HAND_OPEN 0 +196 CMN_HAND_CLOSE 1 +194 CMN_HAND_NORMAL 2 +197 CMN_HAND_PEACE 3 +201 CMN_HAND_NEGI 4 +198 CMN_HAND_MIC 5 +199 CMN_HAND_ONE 6 +202 CMN_HAND_SIZEN 7 +203 CMN_HAND_PICK 8 +192 (null) 9 +200 CMN_HAND_THREE 10 +204 CMN_HAND_MIC 11,12,13 +193 CMN_HAND_RESET 14*/ + int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id) { static const int32_t hand_anim_id_to_mottbl_index_table[] = { 195, 196, 194, 197, 201, 198, 199, 202, @@ -15562,9 +15589,7 @@ bool OpdMaker::InitThread(rob_chara* rob_chr, std::vector* motion_ids, bool OpdMaker::IsWaiting() { std::unique_lock u_lock(waiting_mtx); - bool ret = waiting; - u_lock.unlock(); - return ret; + return waiting; } void OpdMaker::Reset() { @@ -15594,20 +15619,16 @@ bool OpdMaker::SetOsagePlayInitData(int32_t motion_id) { void OpdMaker::SetWaiting(bool value) { std::unique_lock u_lock(waiting_mtx); waiting = value; - u_lock.unlock(); } void OpdMaker::sub_140475AE0() { std::unique_lock u_lock(field_40); field_18 = true; - u_lock.unlock(); } bool OpdMaker::sub_140478330() { std::unique_lock u_lock(field_40); - bool ret = field_18; - u_lock.unlock(); - return ret; + return field_18; } void OpdMaker::ThreadMain(OpdMaker* opd_maker) { @@ -16191,15 +16212,21 @@ PvOsageManager::PvOsageManager() : state(), chara_id(), reset(), field_74(), motion_index(), pv(), thread(), disp(), not_reset(), exit(), field_D4() { Reset(); - std::unique_lock u_disp_mtx_lock(disp_mtx); - disp = false; - u_disp_mtx_lock.unlock(); - std::unique_lock u_not_reset_mtx_lock(not_reset_mtx); - not_reset = false; - u_not_reset_mtx_lock.unlock(); - std::unique_lock u_exit_mtx_lock(exit_mtx); - exit = false; - u_exit_mtx_lock.unlock(); + { + std::unique_lock u_lock(disp_mtx); + disp = false; + } + + { + std::unique_lock u_lock(not_reset_mtx); + not_reset = false; + } + + { + std::unique_lock u_lock(exit_mtx); + exit = false; + } + thread = new std::thread(PvOsageManager::ThreadMain, this); if (thread) { @@ -16210,9 +16237,11 @@ motion_index(), pv(), thread(), disp(), not_reset(), exit(), field_D4() { } PvOsageManager::~PvOsageManager() { - std::unique_lock u_lock(exit_mtx); - exit = true; - u_lock.unlock(); + { + std::unique_lock u_lock(exit_mtx); + exit = true; + } + cnd.notify_one(); thread->join(); delete thread; @@ -16275,45 +16304,38 @@ void PvOsageManager::AddMotionFrameResetData(int32_t stage_index, int32_t motion } bool PvOsageManager::CheckResetFrameNotFound(int32_t motion_id, float_t frame) { - return reset_frames_list.find(frame) == reset_frames_list.end(); + return reset_frames_list.find(frame) == reset_frames_list.end(); } bool PvOsageManager::GetDisp() { std::unique_lock u_lock(disp_mtx); - bool disp = this->disp; - u_lock.unlock(); return disp; } bool PvOsageManager::GetNotReset() { std::unique_lock u_lock(not_reset_mtx); - bool not_reset = this->not_reset; - u_lock.unlock(); return not_reset; } void PvOsageManager::SetDisp(bool value) { std::unique_lock u_lock(disp_mtx); disp = value; - u_lock.unlock(); } void PvOsageManager::SetNotReset(bool value) { std::unique_lock u_lock(not_reset_mtx); not_reset = value; - u_lock.unlock(); } void PvOsageManager::SetPvId(int32_t pv_id, int32_t chara_id, bool reset) { if (!pv_set_motion.size()) return; - HANDLE timer = timer_handle_init(); + waitable_timer timer; while (GetDisp()) { SetNotReset(true); - timer_handle_sleep(timer, 1.0); + timer.sleep(1); } - timer_handle_dispose(timer); SetDisp(true); SetNotReset(false); @@ -16329,7 +16351,7 @@ void PvOsageManager::SetPvId(int32_t pv_id, int32_t chara_id, bool reset) { } void PvOsageManager::SetPvSetMotion(std::vector& set_motion) { - pv_set_motion = set_motion; + pv_set_motion.assign(set_motion.begin(), set_motion.end()); } void PvOsageManager::sub_1404F77E0() { @@ -16343,6 +16365,7 @@ void PvOsageManager::sub_1404F77E0() { && i->frame_stage_index.first == i_next->frame_stage_index.first) { memmove(i, i_next, sizeof(pv_data_set_motion) * (i_end - i_next)); pv_set_motion.pop_back(); + i_end--; continue; } else { @@ -16406,18 +16429,21 @@ void PvOsageManager::Reset() { void PvOsageManager::sub_1404F82F0() { do { - std::unique_lock u_not_reset_lock(not_reset_mtx); - bool not_reset = this->not_reset; - u_not_reset_lock.unlock(); - if (not_reset) - break; + { + std::unique_lock u_lock(not_reset_mtx); + if (not_reset) + break; + } sub_1404F8AA0(); } while (sub_1404F7AF0()); - std::unique_lock u_not_reset_lock(not_reset_mtx); - bool not_reset = this->not_reset; - u_not_reset_lock.unlock(); + bool not_reset = false; + { + std::unique_lock u_lock(not_reset_mtx); + not_reset = this->not_reset; + } + sub_1404F7BD0(not_reset); } @@ -16618,26 +16644,29 @@ void PvOsageManager::ThreadMain(PvOsageManager* pv_osg_mgr) { std::unique_lock u_lock(pv_osg_mgr->mtx); while (true) { pv_osg_mgr->cnd.wait(u_lock); - std::unique_lock u_exit_lock(pv_osg_mgr->exit_mtx); - bool exit = pv_osg_mgr->exit; - u_exit_lock.unlock(); - if (exit) - break; + + { + std::unique_lock u_lock(pv_osg_mgr->exit_mtx); + if (pv_osg_mgr->exit) + break; + } pv_osg_mgr->sub_1404F82F0(); - std::unique_lock u_not_reset_lock(pv_osg_mgr->not_reset_mtx); - u_not_reset_lock.unlock(); + { + std::unique_lock u_lock(pv_osg_mgr->not_reset_mtx); + } - std::unique_lock u_disp_lock(pv_osg_mgr->disp_mtx); - pv_osg_mgr->disp = false; - u_disp_lock.unlock(); + { + std::unique_lock u_lock(pv_osg_mgr->disp_mtx); + pv_osg_mgr->disp = false; + } } - std::unique_lock u_disp_lock(pv_osg_mgr->disp_mtx); - pv_osg_mgr->disp = false; - u_disp_lock.unlock(); - u_lock.unlock(); + { + std::unique_lock u_lock(pv_osg_mgr->disp_mtx); + pv_osg_mgr->disp = false; + } } RobThreadParent::RobThreadParent() : exit(), thread() { @@ -16650,9 +16679,11 @@ RobThreadParent::RobThreadParent() : exit(), thread() { } RobThreadParent::~RobThreadParent() { - std::unique_lock u_lock(mtx); - exit = true; - u_lock.unlock(); + { + std::unique_lock u_lock(mtx); + exit = true; + } + cnd.notify_one(); thread->join(); delete thread; @@ -16666,7 +16697,6 @@ void RobThreadParent::AppendRobCharaFunc(rob_chara* rob_chr, void(*rob_chr_func) thrd.func = rob_chr_func; AppendRobThread(&thrd); cnd.notify_one(); - u_lock.unlock(); } void RobThreadHandler::sub_14054E3F0() { @@ -16677,26 +16707,24 @@ void RobThreadHandler::sub_14054E3F0() { void RobThreadParent::AppendRobThread(RobThread* thread) { std::unique_lock u_lock(threads_mtx); threads.push_back(*thread); - u_lock.unlock(); } bool RobThreadParent::CheckThreadsNotNull() { std::unique_lock u_lock(threads_mtx); - bool not_null = !!threads.size(); - u_lock.unlock(); - return not_null; + return !!threads.size(); } void RobThreadParent::sub_14054E0D0() { - std::unique_lock u_lock(threads_mtx); - threads.pop_front(); - bool v5 = this->threads.size() == 0; - u_lock.unlock(); + bool threads_null = false; + { + std::unique_lock u_lock(threads_mtx); + threads.pop_front(); + threads_null = threads.size() == 0; + } - if (v5) { + if (threads_null) { std::unique_lock u_lock(field_28); field_30.notify_one(); - u_lock.unlock(); } } @@ -16704,7 +16732,6 @@ void RobThreadParent::sub_14054E370() { std::unique_lock u_lock(field_28); if (CheckThreadsNotNull()) field_30.wait(u_lock); - u_lock.unlock(); } void RobThreadParent::ThreadMain(RobThreadParent* rob_thrd_parent) { @@ -16719,7 +16746,6 @@ void RobThreadParent::ThreadMain(RobThreadParent* rob_thrd_parent) { else rob_thrd_parent->cnd.wait(u_lock); } - u_lock.unlock(); } RobThreadHandler::RobThreadHandler() { @@ -18063,7 +18089,7 @@ static void sub_1404156B0(mot_play_data* a1) { switch (frame_data->field_1C) { case 0: default: - frame_data->frame = min(frame_data->frame, frame_data->frame_count); + frame_data->frame = min_def(frame_data->frame, frame_data->frame_count); break; case 1: { if (frame_data->field_24 >= 0.0f && frame_data->field_24 <= last_frame) diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 89510cb6..a5ba3d54 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -3273,6 +3273,7 @@ extern void rob_chara_array_set_alpha_draw_task_flags(int32_t chara_id, float_t extern bool rob_chara_pv_data_array_check_chara_id(int32_t chara_id); extern bool pv_osage_manager_array_get_disp(); +extern void pv_osage_manager_array_set_not_reset_true(); extern void pv_osage_manager_array_set_pv_id(int32_t chara_id, int32_t pv_id, bool reset); extern void pv_osage_manager_array_set_pv_set_motion( int32_t chara_id, std::vector& set_motion); diff --git a/src/CRE/shader.cpp b/src/CRE/shader.cpp index 4e2b62a4..5418e797 100644 --- a/src/CRE/shader.cpp +++ b/src/CRE/shader.cpp @@ -4,6 +4,7 @@ */ #include "shader.hpp" +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/io/path.hpp" #include "../KKdLib/hash.hpp" #include "../KKdLib/str_utils.hpp" @@ -100,7 +101,7 @@ env_update_data(), buffer_update_data(), state_ubo(), state_matrix_ubo(), env_ub } -int32_t shader::bind(uint32_t sub_index) { +int32_t shader::bind(shader_set_data* set, uint32_t sub_index) { int32_t sub_shader_index = 0; if (num_sub < 1) return -1; @@ -125,12 +126,12 @@ int32_t shader::bind(uint32_t sub_index) { int32_t i = 0; for (i = 0; i < num_uniform && i < 16; i++) { int32_t unival_max = use_permut[i] - ? max(vp_unival_max[i], fp_unival_max[i]) : 0; - unival += unival_curr * min(uniform_value[(int32_t)use_uniform[i]], unival_max); + ? max_def(vp_unival_max[i], fp_unival_max[i]) : 0; + unival += unival_curr * min_def(uniform_value[(int32_t)use_uniform[i]], unival_max); unival_curr *= unival_max + 1; - int32_t unival_max_glsl = max(vp_unival_max[i], fp_unival_max[i]); - uniform_val[i] = min(uniform_value[use_uniform[i]], unival_max_glsl); + int32_t unival_max_glsl = max_def(vp_unival_max[i], fp_unival_max[i]); + uniform_val[i] = min_def(uniform_value[use_uniform[i]], unival_max_glsl); } for (; i < 16; i++) @@ -260,8 +261,8 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, } if (!vert_data || !frag_data) { - free(vert_data); - free(frag_data); + free_def(vert_data); + free_def(frag_data); continue; } @@ -308,7 +309,7 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, const int32_t* fp_unival_max = sub_table->fp_unival_max; for (size_t k = 0; k < num_uniform; k++) { size_t unival_max = shader->use_permut[k] - ? max(vp_unival_max[k], fp_unival_max[k]) : 0; + ? max_def(vp_unival_max[k], fp_unival_max[k]) : 0; unival_count += unival_curr * unival_max; unival_curr *= unival_max + 1; } @@ -339,16 +340,16 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, for (size_t k = 0; k < unival_count; k++) { for (size_t l = 0, m = k; l < num_uniform; l++) { size_t unival_max = (size_t)(shader->use_permut[l] - ? max(vp_unival_max[l], fp_unival_max[l]) : 0) + 1; - vec_vert[l] = (uint32_t)(min(m % unival_max, vp_unival_max[l])); + ? max_def(vp_unival_max[l], fp_unival_max[l]) : 0) + 1; + vec_vert[l] = (uint32_t)(min_def(m % unival_max, vp_unival_max[l])); m /= unival_max; vert_buf[vert_buf_pos + l] = (char)('0' + vec_vert[l]); } for (size_t l = 0, m = k; l < num_uniform; l++) { size_t unival_max = (size_t)(shader->use_permut[l] - ? max(vp_unival_max[l], fp_unival_max[l]) : 0) + 1; - vec_frag[l] = (uint32_t)(min(m % unival_max, fp_unival_max[l])); + ? max_def(vp_unival_max[l], fp_unival_max[l]) : 0) + 1; + vec_frag[l] = (uint32_t)(min_def(m % unival_max, fp_unival_max[l])); m /= unival_max; frag_buf[frag_buf_pos + l] = (char)('0' + vec_frag[l]); } @@ -436,7 +437,7 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, shader_cache_file = &shader_cache_farc.files.back(); } else - free(shader_cache_file->data); + free_def(shader_cache_file->data); size_t bin_count = program_data_binary.size(); size_t bin_size = sizeof(uint64_t) * 2 + bin_count * sizeof(program_binary); @@ -459,14 +460,14 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, bin_data_base += sizeof(program_binary); bin_data += k.length; void* binary = (void*)k.binary; - free(binary); + free_def(binary); k.binary = 0; bin++; } } - free(vert_data); - free(frag_data); + free_def(vert_data); + free_def(frag_data); program_data_binary.clear(); } vec_vert.clear(); @@ -478,9 +479,9 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, break; } } - free(binary); - free(temp_vert); - free(temp_frag); + free_def(binary); + free_def(temp_vert); + free_def(temp_frag); if (shader_cache_changed) shader_cache_farc.write(temp_buf, FARC_COMPRESS_FArC, false); @@ -514,7 +515,7 @@ void shader_set_data::set(uint32_t index) { if (shader->bind_func) shader->bind_func(this, shader); else - shader->bind(shader->sub[0].sub_index); + shader->bind(this, shader->sub[0].sub_index); gl_state_bind_uniform_buffer_range(0, data.state_ubo, 0, sizeof(data.state)); gl_state_bind_uniform_buffer_range(1, data.state_matrix_ubo, 0, sizeof(data.state_matrix)); gl_state_bind_uniform_buffer_range(2, data.env_ubo, 0, sizeof(data.env)); @@ -544,7 +545,7 @@ void shader_set_data::unload() { const int32_t* fp_unival_max = sub->fp_unival_max; for (size_t k = 0; k < num_uniform; k++) { size_t unival_max = shader->use_permut[k] - ? max(vp_unival_max[k], fp_unival_max[k]) : 0; + ? max_def(vp_unival_max[k], fp_unival_max[k]) : 0; unival_count += unival_curr * unival_max; unival_curr *= unival_max + 1; } @@ -552,17 +553,17 @@ void shader_set_data::unload() { if (sub->program) for (size_t k = 0; k < unival_count; k++) glDeleteProgram(sub->program[k]); - free(sub->program); + free_def(sub->program); } else { if (sub->program) glDeleteProgram(sub->program[0]); - free(sub->program); + free_def(sub->program); } } - free(shader->sub); + free_def(shader->sub); } - free(shaders); + free_def(shaders); } void shader_set_data::buffer_get(size_t index, vec4& data) { @@ -1187,12 +1188,8 @@ void shader_set_data::state_light_set_ambient(size_t index, float_t x, float_t y this->data.state.light[index].ambient = data; this->data.state_update_data = true; - vec4 lightprod_front; - vec4 lightprod_back; - vec4_mult(this->data.state.light[index].ambient, - this->data.state.material[0].ambient, lightprod_front); - vec4_mult(this->data.state.light[index].ambient, - this->data.state.material[1].ambient, lightprod_back); + vec4 lightprod_front = this->data.state.light[index].ambient * this->data.state.material[0].ambient; + vec4 lightprod_back = this->data.state.light[index].ambient * this->data.state.material[1].ambient; state_lightprod_set_ambient(false, index, lightprod_front); state_lightprod_set_ambient(true, index, lightprod_back); } @@ -1207,12 +1204,8 @@ void shader_set_data::state_light_set_ambient(size_t index, const vec4& data) { this->data.state.light[index].ambient = data; this->data.state_update_data = true; - vec4 lightprod_front; - vec4 lightprod_back; - vec4_mult(this->data.state.light[index].ambient, - this->data.state.material[0].ambient, lightprod_front); - vec4_mult(this->data.state.light[index].ambient, - this->data.state.material[1].ambient, lightprod_back); + vec4 lightprod_front = this->data.state.light[index].ambient * this->data.state.material[0].ambient; + vec4 lightprod_back = this->data.state.light[index].ambient * this->data.state.material[1].ambient; state_lightprod_set_ambient(false, index, lightprod_front); state_lightprod_set_ambient(true, index, lightprod_back); } @@ -1228,12 +1221,8 @@ void shader_set_data::state_light_set_diffuse(size_t index, float_t x, float_t y this->data.state.light[index].diffuse = data; this->data.state_update_data = true; - vec4 lightprod_front; - vec4 lightprod_back; - vec4_mult(this->data.state.light[index].diffuse, - this->data.state.material[0].diffuse, lightprod_front); - vec4_mult(this->data.state.light[index].diffuse, - this->data.state.material[1].diffuse, lightprod_back); + vec4 lightprod_front = this->data.state.light[index].diffuse * this->data.state.material[0].diffuse; + vec4 lightprod_back = this->data.state.light[index].diffuse * this->data.state.material[1].diffuse; state_lightprod_set_diffuse(false, index, lightprod_front); state_lightprod_set_diffuse(true, index, lightprod_back); } @@ -1248,12 +1237,8 @@ void shader_set_data::state_light_set_diffuse(size_t index, const vec4& data) { this->data.state.light[index].diffuse = data; this->data.state_update_data = true; - vec4 lightprod_front; - vec4 lightprod_back; - vec4_mult(this->data.state.light[index].diffuse, - this->data.state.material[0].diffuse, lightprod_front); - vec4_mult(this->data.state.light[index].diffuse, - this->data.state.material[1].diffuse, lightprod_back); + vec4 lightprod_front = this->data.state.light[index].diffuse * this->data.state.material[0].diffuse; + vec4 lightprod_back = this->data.state.light[index].diffuse * this->data.state.material[1].diffuse; state_lightprod_set_diffuse(false, index, lightprod_front); state_lightprod_set_diffuse(true, index, lightprod_back); } @@ -1269,12 +1254,8 @@ void shader_set_data::state_light_set_specular(size_t index, float_t x, float_t this->data.state.light[index].specular = data; this->data.state_update_data = true; - vec4 lightprod_front; - vec4 lightprod_back; - vec4_mult(this->data.state.light[index].specular, - this->data.state.material[0].specular, lightprod_front); - vec4_mult(this->data.state.light[index].specular, - this->data.state.material[1].specular, lightprod_back); + vec4 lightprod_front = this->data.state.light[index].specular * this->data.state.material[0].diffuse; + vec4 lightprod_back = this->data.state.light[index].specular * this->data.state.material[1].diffuse; state_lightprod_set_specular(false, index, lightprod_front); state_lightprod_set_specular(true, index, lightprod_back); } @@ -1289,12 +1270,8 @@ void shader_set_data::state_light_set_specular(size_t index, const vec4& data) { this->data.state.light[index].specular = data; this->data.state_update_data = true; - vec4 lightprod_front; - vec4 lightprod_back; - vec4_mult(this->data.state.light[index].specular, - this->data.state.material[0].specular, lightprod_front); - vec4_mult(this->data.state.light[index].specular, - this->data.state.material[1].specular, lightprod_back); + vec4 lightprod_front = this->data.state.light[index].specular * this->data.state.material[0].diffuse; + vec4 lightprod_back = this->data.state.light[index].specular * this->data.state.material[1].diffuse; state_lightprod_set_specular(false, index, lightprod_front); state_lightprod_set_specular(true, index, lightprod_back); } @@ -1540,9 +1517,8 @@ void shader_set_data::state_material_set_ambient(bool back, float_t x, float_t y this->data.state_update_data = true; for (int32_t index = 0; index < SHADER_MAX_LIGHTS; index++) { - vec4 lightprod; - vec4_mult(this->data.state.light[index].ambient, - this->data.state.material[back ? 1 : 0].ambient, lightprod); + vec4 lightprod = this->data.state.light[index].ambient + * this->data.state.material[back ? 1 : 0].ambient; state_lightprod_set_ambient(back, index, lightprod); } } @@ -1558,9 +1534,8 @@ void shader_set_data::state_material_set_ambient(bool back, const vec4& data) { this->data.state_update_data = true; for (int32_t index = 0; index < SHADER_MAX_LIGHTS; index++) { - vec4 lightprod; - vec4_mult(this->data.state.light[index].ambient, - this->data.state.material[back ? 1 : 0].ambient, lightprod); + vec4 lightprod = this->data.state.light[index].ambient + * this->data.state.material[back ? 1 : 0].ambient; state_lightprod_set_ambient(back, index, lightprod); } } @@ -1575,11 +1550,10 @@ void shader_set_data::state_material_set_diffuse(bool back, float_t x, float_t y this->data.state.material[back ? 1 : 0].diffuse = data; this->data.state_update_data = true; - vec4 lightprod; for (int32_t index = 0; index < SHADER_MAX_LIGHTS; index++) { - vec4_mult(this->data.state.light[index].diffuse, - this->data.state.material[back ? 1 : 0].diffuse, lightprod); + vec4 lightprod = this->data.state.light[index].diffuse + * this->data.state.material[back ? 1 : 0].diffuse; state_lightprod_set_diffuse(back, index, lightprod); } } @@ -1595,9 +1569,8 @@ void shader_set_data::state_material_set_diffuse(bool back, const vec4& data) { this->data.state_update_data = true; for (int32_t index = 0; index < SHADER_MAX_LIGHTS; index++) { - vec4 lightprod; - vec4_mult(this->data.state.light[index].diffuse, - this->data.state.material[back ? 1 : 0].diffuse, lightprod); + vec4 lightprod = this->data.state.light[index].diffuse + * this->data.state.material[back ? 1 : 0].diffuse; state_lightprod_set_diffuse(back, index, lightprod); } } @@ -1614,9 +1587,8 @@ void shader_set_data::state_material_set_specular(bool back, float_t x, float_t this->data.state_update_data = true; for (int32_t index = 0; index < SHADER_MAX_LIGHTS; index++) { - vec4 lightprod; - vec4_mult(this->data.state.light[index].specular, - this->data.state.material[back ? 1 : 0].specular, lightprod); + vec4 lightprod = this->data.state.light[index].specular + * this->data.state.material[back ? 1 : 0].specular; state_lightprod_set_specular(back, index, lightprod); } } @@ -1632,9 +1604,8 @@ void shader_set_data::state_material_set_specular(bool back, const vec4& data) { this->data.state_update_data = true; for (int32_t index = 0; index < SHADER_MAX_LIGHTS; index++) { - vec4 lightprod; - vec4_mult(this->data.state.light[index].specular, - this->data.state.material[back ? 1 : 0].specular, lightprod); + vec4 lightprod = this->data.state.light[index].specular + * this->data.state.material[back ? 1 : 0].specular; state_lightprod_set_specular(back, index, lightprod); } } @@ -2118,7 +2089,7 @@ static GLuint shader_compile_shader(GLenum type, const char* data, const char* f printf("file: %s\n", file); printf(info_log); putchar('\n'); - free(info_log); + free_def(info_log); glDeleteShader(shader); #if defined(CRE_DEV) @@ -2138,7 +2109,7 @@ static GLuint shader_compile_shader(GLenum type, const char* data, const char* f L"%ls\\shader_error\\%hs", temp_buf, file); buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; - stream s; + file_stream s; s.open(buf, L"wb"); s.write(data, utf8_length(data)); } @@ -2173,7 +2144,7 @@ static GLuint shader_compile(const char* vert, const char* frag, const char* vp, printf("vp: %s; fp: %s\n", vp, fp); printf(info_log); putchar('\n'); - free(info_log); + free_def(info_log); glDeleteProgram(program); return 0; } @@ -2211,7 +2182,7 @@ static GLuint shader_compile_binary(const char* vert, const char* frag, const ch printf("vp: %s; fp: %s\n", vp, fp); printf(info_log); putchar('\n'); - free(info_log); + free_def(info_log); glDeleteProgram(program); return 0; } @@ -2225,7 +2196,7 @@ static GLuint shader_compile_binary(const char* vert, const char* frag, const ch if (!glGetError()) break; - free(*binary); + free_def(*binary); *buffer_size <<= 1; *binary = force_malloc(*buffer_size); } @@ -2274,7 +2245,7 @@ static bool shader_parse_define(const char* data, int32_t num_uniform, len += len_a + len_b; if (len + 1 > *temp_size) { - free(*temp); + free_def(*temp); *temp_size = len + 1; *temp = force_malloc_s(char, *temp_size); } @@ -2288,7 +2259,7 @@ static bool shader_parse_define(const char* data, int32_t num_uniform, return true; } - const int32_t s = min(0x100, num_uniform); + const int32_t s = min_def(0x100, num_uniform); size_t t_len[0x100]; char t[0x100]; @@ -2310,7 +2281,7 @@ static bool shader_parse_define(const char* data, int32_t num_uniform, len += len_a + len_b; if (len + 1 > *temp_size) { - free(*temp); + free_def(*temp); *temp_size = len + 1; *temp = force_malloc_s(char, *temp_size); } @@ -2353,10 +2324,10 @@ static char* shader_parse_include(char* data, farc* f) { char** temp_ptr0 = force_malloc_s(char*, count); char** temp_ptr1 = force_malloc_s(char*, count); if (!temp || !temp_len || !temp_ptr0 || !temp_ptr1) { - free(temp); - free(temp_len); - free(temp_ptr0); - free(temp_ptr1); + free_def(temp); + free_def(temp_len); + free_def(temp_ptr0); + free_def(temp_ptr1); return data; } @@ -2381,7 +2352,7 @@ static char* shader_parse_include(char* data, farc* f) { t[s] = 0; farc_file* ff = f->read_file(t); - free(t); + free_def(t); if (!ff) continue; @@ -2430,13 +2401,13 @@ static char* shader_parse_include(char* data, farc* f) { } temp_data[pos] = 0; - free(data); + free_def(data); for (size_t i = 0; i < count; i++) - free(temp[i]); - free(temp); - free(temp_len); - free(temp_ptr0); - free(temp_ptr1); + free_def(temp[i]); + free_def(temp); + free_def(temp_len); + free_def(temp_ptr0); + free_def(temp_ptr1); return temp_data; } diff --git a/src/CRE/shader.hpp b/src/CRE/shader.hpp index e0d632f9..f1139c7c 100644 --- a/src/CRE/shader.hpp +++ b/src/CRE/shader.hpp @@ -229,7 +229,7 @@ struct shader { const bool* use_permut; PFNSHADERBINDFUNCPROC bind_func; - int32_t bind(uint32_t sub_index); + int32_t bind(shader_set_data* set, uint32_t sub_index); static void unbind(); }; diff --git a/src/CRE/shader_ft.cpp b/src/CRE/shader_ft.cpp index fbfe9b2a..7f20f95f 100644 --- a/src/CRE/shader_ft.cpp +++ b/src/CRE/shader_ft.cpp @@ -7,75 +7,78 @@ #include "gl_state.hpp" enum shader_ft_sub_enum { - SHADER_FT_SUB_SHADER_FFP = 0x00, - SHADER_FT_SUB_BLINN_VERT = 0x01, - SHADER_FT_SUB_BLINN_FRAG = 0x02, - SHADER_FT_SUB_ITEM_BLINN = 0x03, - SHADER_FT_SUB_STAGE_BLINN = 0x04, - SHADER_FT_SUB_SKIN_DEFAULT = 0x05, - SHADER_FT_SUB_SSS_SKIN = 0x06, - SHADER_FT_SUB_SSS_FILTER = 0x07, - SHADER_FT_SUB_HAIR_DEFAULT = 0x08, - SHADER_FT_SUB_HAIR_ANISO = 0x09, - SHADER_FT_SUB_HAIR_NPR1 = 0x0A, - SHADER_FT_SUB_CLOTH_DEFAULT = 0x0B, - SHADER_FT_SUB_CLOTH_ANISO = 0x0C, - SHADER_FT_SUB_CLOTH_NPR1 = 0x0D, - SHADER_FT_SUB_TIGHTS = 0x0E, - SHADER_FT_SUB_SKY_DEFAULT = 0x0F, - SHADER_FT_SUB_EYE_BALL = 0x10, - SHADER_FT_SUB_EYE_LENS = 0x11, - SHADER_FT_SUB_GLASS_EYE = 0x12, - SHADER_FT_SUB_MEMBRANE = 0x13, - SHADER_FT_SUB_SHADOWMAP = 0x14, - SHADER_FT_SUB_ESM = 0x15, - SHADER_FT_SUB_ESM_GAUSS = 0x16, - SHADER_FT_SUB_ESM_FILTER = 0x17, - SHADER_FT_SUB_LIT_PROJ = 0x18, - SHADER_FT_SUB_SIMPLE = 0x19, - SHADER_FT_SUB_SILHOUETTE = 0x1A, - SHADER_FT_SUB_LAMBERT = 0x1B, - SHADER_FT_SUB_CONSTANT = 0x1C, - SHADER_FT_SUB_PEEL = 0x1D, - SHADER_FT_SUB_TONEMAP = 0x1E, - SHADER_FT_SUB_TONEMAP_NPR1 = 0x1F, - SHADER_FT_SUB_REDUCE_TEX = 0x20, - SHADER_FT_SUB_MAGNIFY = 0x21, - SHADER_FT_SUB_MLAA = 0x22, - SHADER_FT_SUB_CONTOUR = 0x23, - SHADER_FT_SUB_EXPOSURE = 0x24, - SHADER_FT_SUB_PP_GAUSS = 0x25, - SHADER_FT_SUB_SUN = 0x26, - SHADER_FT_SUB_FADE = 0x27, - SHADER_FT_SUB_WATER01 = 0x28, - SHADER_FT_SUB_WATER02 = 0x29, - SHADER_FT_SUB_WATER_RING = 0x2A, - SHADER_FT_SUB_WATER_PARTICLE = 0x2B, - SHADER_FT_SUB_SNOW_PARTICLE = 0x2C, - SHADER_FT_SUB_LEAF_PARTICLE = 0x2D, - SHADER_FT_SUB_STAR = 0x2E, - SHADER_FT_SUB_SNOW_RING = 0x2F, - SHADER_FT_SUB_SNOW_FOOTPRINT = 0x30, - SHADER_FT_SUB_SNOW_TEX_SPACE_LIGHT = 0x31, - SHADER_FT_SUB_SNOW_CALC_NORMAL = 0x32, - SHADER_FT_SUB_FLOOR = 0x33, - SHADER_FT_SUB_PUDDLE = 0x34, - SHADER_FT_SUB_SIMPLE_REFLECT = 0x35, - SHADER_FT_SUB_SIMPLE_REFRACT = 0x36, - SHADER_FT_SUB_RIPPLE_EMIT = 0x37, - SHADER_FT_SUB_RAIN = 0x38, - SHADER_FT_SUB_VOLUME_LIGHT = 0x39, - SHADER_FT_SUB_FENCE_ALPHA = 0x3A, - SHADER_FT_SUB_RIPPLE = 0x3B, - SHADER_FT_SUB_FOG_PTCL = 0x3C, - SHADER_FT_SUB_PARTICLE = 0x3D, - SHADER_FT_SUB_GLITTER_PARTICLE = 0x3E, - SHADER_FT_SUB_SHOW_VECTOR = 0x3F, - SHADER_FT_SUB_FONT = 0x40, - SHADER_FT_SUB_MOVIE = 0x41, - SHADER_FT_SUB_IMGFILTER = 0x42, - SHADER_FT_SUB_SPRITE = 0x43, - SHADER_FT_SUB_SHADER_END = 0x44, + SHADER_FT_SUB_SHADER_FFP = 0, + SHADER_FT_SUB_BLINN_VERT, + SHADER_FT_SUB_BLINN_FRAG, + SHADER_FT_SUB_ITEM_BLINN, + SHADER_FT_SUB_STAGE_BLINN, + SHADER_FT_SUB_SKIN_DEFAULT, + SHADER_FT_SUB_SSS_SKIN, + SHADER_FT_SUB_SSS_FILTER, + SHADER_FT_SUB_HAIR_DEFAULT, + SHADER_FT_SUB_HAIR_ANISO, + SHADER_FT_SUB_HAIR_NPR1, + SHADER_FT_SUB_CLOTH_DEFAULT, + SHADER_FT_SUB_CLOTH_ANISO, + SHADER_FT_SUB_CLOTH_NPR1, + SHADER_FT_SUB_TIGHTS, + SHADER_FT_SUB_SKY_DEFAULT, + SHADER_FT_SUB_EYE_BALL, + SHADER_FT_SUB_EYE_LENS, + SHADER_FT_SUB_GLASS_EYE, + SHADER_FT_SUB_MEMBRANE, + SHADER_FT_SUB_SHADOWMAP, + SHADER_FT_SUB_ESM, + SHADER_FT_SUB_ESM_GAUSS, + SHADER_FT_SUB_ESM_FILTER, + SHADER_FT_SUB_LIT_PROJ, + SHADER_FT_SUB_SIMPLE, + SHADER_FT_SUB_SILHOUETTE, + SHADER_FT_SUB_LAMBERT, + SHADER_FT_SUB_CONSTANT, + SHADER_FT_SUB_PEEL, + SHADER_FT_SUB_TONEMAP, + SHADER_FT_SUB_TONEMAP_NPR1, + SHADER_FT_SUB_REDUCE_TEX, + SHADER_FT_SUB_MAGNIFY, + //SHADER_FT_SUB_MLAA, + SHADER_FT_SUB_MLAA_EDGE, + SHADER_FT_SUB_MLAA_AREA, + SHADER_FT_SUB_MLAA_BLEND, + SHADER_FT_SUB_CONTOUR, + SHADER_FT_SUB_EXPOSURE, + SHADER_FT_SUB_PP_GAUSS, + SHADER_FT_SUB_SUN, + SHADER_FT_SUB_FADE, + SHADER_FT_SUB_WATER01, + SHADER_FT_SUB_WATER02, + SHADER_FT_SUB_WATER_RING, + SHADER_FT_SUB_WATER_PARTICLE, + SHADER_FT_SUB_SNOW_PARTICLE, + SHADER_FT_SUB_LEAF_PARTICLE, + SHADER_FT_SUB_STAR, + SHADER_FT_SUB_SNOW_RING, + SHADER_FT_SUB_SNOW_FOOTPRINT, + SHADER_FT_SUB_SNOW_TEX_SPACE_LIGHT, + SHADER_FT_SUB_SNOW_CALC_NORMAL, + SHADER_FT_SUB_FLOOR, + SHADER_FT_SUB_PUDDLE, + SHADER_FT_SUB_SIMPLE_REFLECT, + SHADER_FT_SUB_SIMPLE_REFRACT, + SHADER_FT_SUB_RIPPLE_EMIT, + SHADER_FT_SUB_RAIN, + SHADER_FT_SUB_VOLUME_LIGHT, + SHADER_FT_SUB_FENCE_ALPHA, + SHADER_FT_SUB_RIPPLE, + SHADER_FT_SUB_FOG_PTCL, + SHADER_FT_SUB_PARTICLE, + SHADER_FT_SUB_GLITTER_PARTICLE, + SHADER_FT_SUB_SHOW_VECTOR, + SHADER_FT_SUB_FONT, + SHADER_FT_SUB_MOVIE, + SHADER_FT_SUB_IMGFILTER, + SHADER_FT_SUB_SPRITE, + SHADER_FT_SUB_SHADER_END, }; static const int32_t blinn_vert_vpt_unival_max[] = { @@ -342,12 +345,38 @@ static const int32_t magnify_fpt_unival_max[] = { 7, }; -static const int32_t mlaa_vpt_unival_max[] = { - 0, 0, 2, 0, +/*static const int32_t mlaa_vpt_unival_max[] = { + //0, 0, 2, 0, + 0, 2, 0, // 1st removed }; static const int32_t mlaa_fpt_unival_max[] = { - 1, 1, 2, 2, + //1, 1, 2, 2, + 1, 2, 2, // 1st removed +};*/ + +static const int32_t mlaa_edge_vpt_unival_max[] = { + 0, +}; + +static const int32_t mlaa_edge_fpt_unival_max[] = { + 1, +}; + +static const int32_t mlaa_area_vpt_unival_max[] = { + 0, +}; + +static const int32_t mlaa_area_fpt_unival_max[] = { + 2, +}; + +static const int32_t mlaa_blend_vpt_unival_max[] = { + 0, +}; + +static const int32_t mlaa_blend_fpt_unival_max[] = { + 1, }; static const int32_t contour_vpt_unival_max[] = { @@ -926,7 +955,7 @@ static const shader_sub_table MAGNIFY_table[] = { }, }; -static const shader_sub_table MLAA_table[] = { +/*static const shader_sub_table MLAA_table[] = { { SHADER_FT_SUB_MLAA, mlaa_vpt_unival_max, @@ -934,6 +963,36 @@ static const shader_sub_table MLAA_table[] = { "mlaa", "mlaa", }, +};*/ + +static const shader_sub_table MLAA_EDGE_table[] = { + { + SHADER_FT_SUB_MLAA_EDGE, + mlaa_edge_vpt_unival_max, + mlaa_edge_fpt_unival_max, + "mlaa_edge", + "mlaa_edge", + }, +}; + +static const shader_sub_table MLAA_AREA_table[] = { + { + SHADER_FT_SUB_MLAA_AREA, + mlaa_area_vpt_unival_max, + mlaa_area_fpt_unival_max, + "mlaa_area", + "mlaa_area", + }, +}; + +static const shader_sub_table MLAA_BLEND_table[] = { + { + SHADER_FT_SUB_MLAA_BLEND, + mlaa_blend_vpt_unival_max, + mlaa_blend_fpt_unival_max, + "mlaa_blend", + "mlaa_blend", + }, }; static const shader_sub_table CONTOUR_table[] = { @@ -1524,18 +1583,30 @@ static const uniform_name TONEMAP_uniform[] = { static const uniform_name REDUCE_uniform[] = { U_REDUCE, - U01, + U_ALPHA_MASK, }; static const uniform_name MAGNIFY_uniform[] = { U_MAGNIFY, }; -static const uniform_name MLAA_uniform[] = { - U16, - U01, +/*static const uniform_name MLAA_uniform[] = { + //U16, // 1st removed + U_ALPHA_MASK, U_MLAA, - U20, + U_MLAA_SEARCH, +};*/ + +static const uniform_name MLAA_EDGE_uniform[] = { + U_ALPHA_MASK, +}; + +static const uniform_name MLAA_AREA_uniform[] = { + U_MLAA_SEARCH, +}; + +static const uniform_name MLAA_BLEND_uniform[] = { + U_ALPHA_MASK, }; static const uniform_name CONTOUR_uniform[] = { @@ -1786,8 +1857,8 @@ static const bool SSS_SKIN_permut[] = { static const bool SSS_FILT_permut[] = { true, - false, - false, + true, + true, }; static const bool HAIR_permut[] = { @@ -1969,32 +2040,44 @@ static const bool TONEMAP_permut[] = { }; static const bool REDUCE_permut[] = { - false, - false, + true, + true, }; static const bool MAGNIFY_permut[] = { - false, + true, }; -static const bool MLAA_permut[] = { - false, - false, +/*static const bool MLAA_permut[] = { + //true, // 1st removed true, true, + true, +};*/ + +static const bool MLAA_EDGE_permut[] = { + true, +}; + +static const bool MLAA_AREA_permut[] = { + true, +}; + +static const bool MLAA_BLEND_permut[] = { + true, }; static const bool CONTOUR_permut[] = { - false, + true, false, }; static const bool EXPOSURE_permut[] = { - false, + true, }; static const bool GAUSS_permut[] = { - false, + true, }; static const bool SUN_permut[] = { @@ -2150,7 +2233,7 @@ static const bool MOVIE_permut[] = { }; static const bool IMGFILT_permut[] = { - false, + true, }; static const bool SPRITE_permut[] = { @@ -2236,7 +2319,10 @@ static const shader_table shader_ft_table[] = { shader_table_struct(TONEMAP), shader_table_struct(REDUCE), shader_table_struct(MAGNIFY), - shader_table_struct(MLAA), + //shader_table_struct(MLAA), + shader_table_struct(MLAA_EDGE), + shader_table_struct(MLAA_AREA), + shader_table_struct(MLAA_BLEND), shader_table_struct(CONTOUR), shader_table_struct(EXPOSURE), shader_table_struct(GAUSS), @@ -2356,9 +2442,9 @@ static void glass_eye_calc(glass_eye_struct* glass_eye) { float_t v2 = glass_eye->field_28; glass_eye->field_64 = glass_eye->field_2C / v2; glass_eye->field_90 = glass_eye->field_58; - vec3_mult_scalar(glass_eye->field_30, v2, glass_eye->field_68); - vec3_mult_scalar(glass_eye->field_3C, v2, glass_eye->field_74); - vec3_mult_scalar(glass_eye->field_48, v2, glass_eye->field_80); + glass_eye->field_68 = glass_eye->field_30 * v2; + glass_eye->field_74 = glass_eye->field_3C * v2; + glass_eye->field_80 = glass_eye->field_48 * v2; glass_eye->field_8C = glass_eye->field_54 * v2; if (glass_eye->field_B0 == 0) { glass_eye->field_A0 = vec4_null; @@ -2386,9 +2472,9 @@ static void glass_eye_calc(glass_eye_struct* glass_eye) { static void glass_eye_set(glass_eye_struct* glass_eye, shader_set_data* set) { vec4 temp; - vec3_mult(glass_eye->field_68, glass_eye->field_68, *(vec3*)&temp); + *(vec3*)&temp = glass_eye->field_68 * glass_eye->field_68; temp.w = temp.z; - vec3_div(vec3_identity, *(vec3*)&temp, *(vec3*)&temp); + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); set->local_vert_set(0x0A, temp); set->local_frag_set(0x0A, temp); @@ -2402,17 +2488,17 @@ static void glass_eye_set(glass_eye_struct* glass_eye, shader_set_data* set) { temp = glass_eye->field_A0; set->local_vert_set(0x0D, temp); - vec3_mult(glass_eye->field_90, glass_eye->field_90, *(vec3*)&temp); + *(vec3*)&temp = glass_eye->field_90 * glass_eye->field_90; temp.w = temp.z; - vec3_div(vec3_identity, *(vec3*)&temp, *(vec3*)&temp); + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); set->local_vert_set(0x0E, temp); temp = glass_eye->field_10; set->local_vert_set(0x0F, temp); - vec3_mult(glass_eye->field_68, glass_eye->field_68, *(vec3*)&temp); + *(vec3*)&temp = glass_eye->field_68 * glass_eye->field_68; temp.w = temp.z; - vec3_div(vec3_identity, *(vec3*)&temp, *(vec3*)&temp); + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); set->local_vert_set(0x0E, temp); float_t v2 = (glass_eye->field_20 - glass_eye->field_24) / (glass_eye->field_20 + glass_eye->field_24); @@ -2425,46 +2511,46 @@ static void glass_eye_set(glass_eye_struct* glass_eye, shader_set_data* set) { float_t v4 = (glass_eye->field_24 * glass_eye->field_24) / (glass_eye->field_20 * glass_eye->field_20); set->local_frag_set(0x0E, v4, 1.0f - v4, glass_eye->field_24 / glass_eye->field_20, 0.0f); - vec3_mult(glass_eye->field_74, glass_eye->field_74, *(vec3*)&temp); + *(vec3*)&temp = glass_eye->field_74 * glass_eye->field_74; temp.w = -1.0f; - vec3_div(vec3_identity, *(vec3*)&temp, *(vec3*)&temp); + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); set->local_frag_set(0x0F, temp); - vec3_mult(glass_eye->field_68, glass_eye->field_68, *(vec3*)&temp); + *(vec3*)&temp = glass_eye->field_68 * glass_eye->field_68; temp.w = -1.0f; - vec3_div(vec3_identity, *(vec3*)&temp, *(vec3*)&temp); + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); set->local_frag_set(0x10, temp); - vec3_mult(glass_eye->field_80, glass_eye->field_80, *(vec3*)&temp); + *(vec3*)&temp = glass_eye->field_80 * glass_eye->field_80; temp.w = -1.0f; - vec3_div(vec3_identity, *(vec3*)&temp, *(vec3*)&temp); + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); set->local_frag_set(0x11, temp); - vec2_mult(*(vec2*)&glass_eye->field_0, *(vec2*)&glass_eye->field_74, *(vec2*)&temp); + *(vec2*)&temp = *(vec2*)&glass_eye->field_0 * *(vec2*)&glass_eye->field_74; temp.z = glass_eye->field_64 * 1.442695f; temp.w = glass_eye->field_8C; - vec2_div(vec2_identity, *(vec2*)&temp, *(vec2*)&temp); + *(vec2*)&temp = vec2::rcp(*(vec2*)&temp); set->local_frag_set(0x12, temp); } static void shader_bind_blinn(shader_set_data* set, shader* shad) { - shad->bind(uniform_value[U_NORMAL] + shad->bind(set, uniform_value[U_NORMAL] ? SHADER_FT_SUB_BLINN_FRAG : SHADER_FT_SUB_BLINN_VERT); } static void shader_bind_cloth(shader_set_data* set, shader* shad) { - shad->bind(uniform_value[U_NPR] ? SHADER_FT_SUB_CLOTH_NPR1 + shad->bind(set, uniform_value[U_NPR] ? SHADER_FT_SUB_CLOTH_NPR1 : (uniform_value[U_ANISO] ? SHADER_FT_SUB_CLOTH_ANISO : SHADER_FT_SUB_CLOTH_DEFAULT)); } static void shader_bind_hair(shader_set_data* set, shader* shad) { - shad->bind(uniform_value[U_NPR] ? SHADER_FT_SUB_HAIR_NPR1 + shad->bind(set, uniform_value[U_NPR] ? SHADER_FT_SUB_HAIR_NPR1 : (uniform_value[U_ANISO] ? SHADER_FT_SUB_HAIR_ANISO : SHADER_FT_SUB_HAIR_DEFAULT)); } static void shader_bind_membrane(shader_set_data* set, shader* shad) { uniform_value[U_MEMBRANE] = 3; - if (shad->bind(SHADER_FT_SUB_MEMBRANE) < 0) + if (shad->bind(set, SHADER_FT_SUB_MEMBRANE) < 0) return; /*uint32_t(* sub_140192E00)() = (void*)0x0000000140192E00; @@ -2481,13 +2567,13 @@ static void shader_bind_membrane(shader_set_data* set, shader* shad) { static void shader_bind_eye_ball(shader_set_data* set, shader* shad) { uniform_value[U18] = 0; - if (set->shaders[SHADER_FT_GLASEYE].bind(SHADER_FT_SUB_GLASS_EYE) >= 0) { + if (set->shaders[SHADER_FT_GLASEYE].bind(set, SHADER_FT_SUB_GLASS_EYE) >= 0) { glass_eye_calc(&glass_eye); glass_eye_set(&glass_eye, set); } } static void shader_bind_tone_map(shader_set_data* set, shader* shad) { - shad->bind(uniform_value[U_NPR] == 1 + shad->bind(set, uniform_value[U_NPR] == 1 ? SHADER_FT_SUB_TONEMAP_NPR1 : SHADER_FT_SUB_TONEMAP); } diff --git a/src/CRE/shader_ft.hpp b/src/CRE/shader_ft.hpp index e7343239..dcf2bb4d 100644 --- a/src/CRE/shader_ft.hpp +++ b/src/CRE/shader_ft.hpp @@ -9,69 +9,72 @@ #include "shader.hpp" enum shader_ft_enum { - SHADER_FT_FFP = 0x00, - SHADER_FT_BLINN = 0x01, - SHADER_FT_ITEM = 0x02, - SHADER_FT_STAGE = 0x03, - SHADER_FT_SKIN = 0x04, - SHADER_FT_SSS_SKIN = 0x05, - SHADER_FT_SSS_FILT = 0x06, - SHADER_FT_HAIR = 0x07, - SHADER_FT_CLOTH = 0x08, - SHADER_FT_TIGHTS = 0x09, - SHADER_FT_SKY = 0x0A, - SHADER_FT_EYEBALL = 0x0B, - SHADER_FT_EYELENS = 0x0C, - SHADER_FT_GLASEYE = 0x0D, - SHADER_FT_MEMBRAN = 0x0E, - SHADER_FT_SHDMAP = 0x0F, - SHADER_FT_ESM = 0x10, - SHADER_FT_ESMGAUSS = 0x11, - SHADER_FT_ESMFILT = 0x12, - SHADER_FT_LITPROJ = 0x13, - SHADER_FT_SIMPLE = 0x14, - SHADER_FT_SIL = 0x15, - SHADER_FT_LAMBERT = 0x16, - SHADER_FT_CONSTANT = 0x17, - SHADER_FT_PEEL = 0x18, - SHADER_FT_TONEMAP = 0x19, - SHADER_FT_REDUCE = 0x1A, - SHADER_FT_MAGNIFY = 0x1B, - SHADER_FT_MLAA = 0x1C, - SHADER_FT_CONTOUR = 0x1D, - SHADER_FT_EXPOSURE = 0x1E, - SHADER_FT_GAUSS = 0x1F, - SHADER_FT_SUN = 0x20, - SHADER_FT_FADE = 0x21, - SHADER_FT_WATER01 = 0x22, - SHADER_FT_WATER02 = 0x23, - SHADER_FT_WATRING = 0x24, - SHADER_FT_W_PTCL = 0x25, - SHADER_FT_SNOW_PT = 0x26, - SHADER_FT_LEAF_PT = 0x27, - SHADER_FT_STAR = 0x28, - SHADER_FT_SNORING = 0x29, - SHADER_FT_SN_FOOT = 0x2A, - SHADER_FT_SN_TSL = 0x2B, - SHADER_FT_SN_NRM = 0x2C, - SHADER_FT_FLOOR = 0x2D, - SHADER_FT_PUDDLE = 0x2E, - SHADER_FT_S_REFL = 0x2F, - SHADER_FT_S_REFR = 0x30, - SHADER_FT_RIPEMIT = 0x31, - SHADER_FT_RAIN = 0x32, - SHADER_FT_VOLLIT = 0x33, - SHADER_FT_FENCE = 0x34, - SHADER_FT_RIPPLE = 0x35, - SHADER_FT_FOGPTCL = 0x36, - SHADER_FT_PARTICL = 0x37, - SHADER_FT_GLITTER_PT = 0x38, - SHADER_FT_SHOWVEC = 0x39, - SHADER_FT_FONT = 0x3A, - SHADER_FT_MOVIE = 0x3B, - SHADER_FT_IMGFILT = 0x3C, - SHADER_FT_SPRITE = 0x3D, - SHADER_FT_END = 0x3E, + SHADER_FT_FFP = 0, + SHADER_FT_BLINN, + SHADER_FT_ITEM, + SHADER_FT_STAGE, + SHADER_FT_SKIN, + SHADER_FT_SSS_SKIN, + SHADER_FT_SSS_FILT, + SHADER_FT_HAIR, + SHADER_FT_CLOTH, + SHADER_FT_TIGHTS, + SHADER_FT_SKY, + SHADER_FT_EYEBALL, + SHADER_FT_EYELENS, + SHADER_FT_GLASEYE, + SHADER_FT_MEMBRAN, + SHADER_FT_SHDMAP, + SHADER_FT_ESM, + SHADER_FT_ESMGAUSS, + SHADER_FT_ESMFILT, + SHADER_FT_LITPROJ, + SHADER_FT_SIMPLE, + SHADER_FT_SIL, + SHADER_FT_LAMBERT, + SHADER_FT_CONSTANT, + SHADER_FT_PEEL, + SHADER_FT_TONEMAP, + SHADER_FT_REDUCE, + SHADER_FT_MAGNIFY, + //SHADER_FT_MLAA, + SHADER_FT_MLAA_EDGE, + SHADER_FT_MLAA_AREA, + SHADER_FT_MLAA_BLEND, + SHADER_FT_CONTOUR, + SHADER_FT_EXPOSURE, + SHADER_FT_GAUSS, + SHADER_FT_SUN, + SHADER_FT_FADE, + SHADER_FT_WATER01, + SHADER_FT_WATER02, + SHADER_FT_WATRING, + SHADER_FT_W_PTCL, + SHADER_FT_SNOW_PT, + SHADER_FT_LEAF_PT, + SHADER_FT_STAR, + SHADER_FT_SNORING, + SHADER_FT_SN_FOOT, + SHADER_FT_SN_TSL, + SHADER_FT_SN_NRM, + SHADER_FT_FLOOR, + SHADER_FT_PUDDLE, + SHADER_FT_S_REFL, + SHADER_FT_S_REFR, + SHADER_FT_RIPEMIT, + SHADER_FT_RAIN, + SHADER_FT_VOLLIT, + SHADER_FT_FENCE, + SHADER_FT_RIPPLE, + SHADER_FT_FOGPTCL, + SHADER_FT_PARTICL, + SHADER_FT_GLITTER_PT, + SHADER_FT_SHOWVEC, + SHADER_FT_FONT, + SHADER_FT_MOVIE, + SHADER_FT_IMGFILT, + SHADER_FT_SPRITE, + SHADER_FT_END, }; extern shader_set_data shaders_ft; diff --git a/src/CRE/shader_glsl.cpp b/src/CRE/shader_glsl.cpp index b7e913f5..3d477e68 100644 --- a/src/CRE/shader_glsl.cpp +++ b/src/CRE/shader_glsl.cpp @@ -4,6 +4,7 @@ */ #include "shader_glsl.hpp" +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/hash.hpp" #include "../KKdLib/str_utils.hpp" #include "gl_state.hpp" @@ -73,9 +74,9 @@ void shader_glsl::load(const char* vert, const char* frag, GLuint vert_shad = shader_compile(GL_VERTEX_SHADER, vert_data); GLuint geom_shad = shader_compile(GL_GEOMETRY_SHADER, geom_data); - free(frag_data); - free(vert_data); - free(geom_data); + free_def(frag_data); + free_def(vert_data); + free_def(geom_data); program = glCreateProgram(); if (frag_shad) @@ -91,10 +92,10 @@ void shader_glsl::load(const char* vert, const char* frag, if (!success) { GLchar* info_log = force_malloc_s(GLchar, 0x10000); glGetProgramInfoLog(program, 0x10000, 0, info_log); - printf("Program FBO Shader linking error: %s\n", param->name); + printf("Program linking error: %s\n", param->name); printf(info_log); putchar('\n'); - free(info_log); + free_def(info_log); } if (frag_shad) @@ -113,7 +114,7 @@ void shader_glsl::load_file(const char* vert_path, const char* frag_path, uniform.clear(); uniform_block.clear(); - stream st; + file_stream st; size_t l; char* vert = 0; @@ -121,7 +122,7 @@ void shader_glsl::load_file(const char* vert_path, const char* frag_path, char* geom = 0; st.open(vert_path, "rb"); - if (st.io.stream) { + if (st.check_not_null()) { l = st.length; vert = force_malloc_s(char, l + 1); st.read(vert, l); @@ -130,7 +131,7 @@ void shader_glsl::load_file(const char* vert_path, const char* frag_path, st.close(); st.open(frag_path, "rb"); - if (st.io.stream) { + if (st.check_not_null()) { l = st.length; frag = force_malloc_s(char, l + 1); st.read(frag, l); @@ -139,7 +140,7 @@ void shader_glsl::load_file(const char* vert_path, const char* frag_path, st.close(); st.open(geom_path, "rb"); - if (st.io.stream) { + if (st.check_not_null()) { l = st.length; geom = force_malloc_s(char, l + 1); st.read(geom, l); @@ -148,8 +149,8 @@ void shader_glsl::load_file(const char* vert_path, const char* frag_path, st.close(); load(vert, frag, geom, param); - free(vert); - free(frag); + free_def(vert); + free_def(frag); } void shader_glsl::load_file(const wchar_t* vert_path, const wchar_t* frag_path, @@ -160,7 +161,7 @@ void shader_glsl::load_file(const wchar_t* vert_path, const wchar_t* frag_path, uniform.clear(); uniform_block.clear(); - stream st; + file_stream st; size_t l; char* vert = 0; @@ -168,7 +169,7 @@ void shader_glsl::load_file(const wchar_t* vert_path, const wchar_t* frag_path, char* geom = 0; st.open(vert_path, L"rb"); - if (st.io.stream) { + if (st.check_not_null()) { l = st.length; vert = force_malloc_s(char, l + 1); st.read(vert, l); @@ -177,7 +178,7 @@ void shader_glsl::load_file(const wchar_t* vert_path, const wchar_t* frag_path, st.close(); st.open(frag_path, L"rb"); - if (st.io.stream) { + if (st.check_not_null()) { l = st.length; frag = force_malloc_s(char, l + 1); st.read(frag, l); @@ -186,7 +187,7 @@ void shader_glsl::load_file(const wchar_t* vert_path, const wchar_t* frag_path, st.close(); st.open(geom_path, L"rb"); - if (st.io.stream) { + if (st.check_not_null()) { l = st.length; geom = force_malloc_s(char, l + 1); st.read(geom, l); @@ -195,8 +196,8 @@ void shader_glsl::load_file(const wchar_t* vert_path, const wchar_t* frag_path, st.close(); load(vert, frag, geom, param); - free(vert); - free(frag); + free_def(vert); + free_def(frag); } void shader_glsl::set(const char* name, bool value) { @@ -448,7 +449,7 @@ static GLuint shader_compile(GLenum type, const char* data) { printf("Shader compile error: "); printf(info_log); putchar('\n'); - free(info_log); + free_def(info_log); } return shader; } @@ -513,7 +514,7 @@ static char* shader_parse(char* data, const char* parse_string, const char* repl memcpy(temp_data + pos, replace_string, len_b); pos += len_b; memcpy(temp_data + pos, def, len_c); - free(data); + free_def(data); return temp_data; } @@ -561,6 +562,6 @@ static char* shader_parse_define(char* data, shader_glsl_param* param) { pos += temp_len[i]; } memcpy(temp_data + pos, def, len_b); - free(data); + free_def(data); return temp_data; } diff --git a/src/CRE/sound.cpp b/src/CRE/sound.cpp new file mode 100644 index 00000000..4f863892 --- /dev/null +++ b/src/CRE/sound.cpp @@ -0,0 +1,1775 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "sound.hpp" +#include "../KKdLib/io/file_stream.hpp" +#include "../KKdLib/key_val.hpp" +#include "../KKdLib/str_utils.hpp" +#include "../KKdLib/vec.hpp" +#include "data.hpp" +#include "timer.hpp" +#include +#include + +struct ima_storage { + int32_t step_index; + int32_t current; + + inline ima_storage() : step_index(), current() { + + } +}; + +struct SoundCueQueueVolume { + float_t min; + float_t max; +}; + +SoundWork* sound_work; +sound::wasapi::System* sound_wasapi_system_data; +std::map wave_audio_storage; + +static int32_t sound_cue_counter = 0; +static int32_t sound_wasapi_system_counter = 0; + +static const int8_t ima_index_table[] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +static const int16_t ima_step_table[] = { + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 +}; + +static const SoundCueQueueVolume sound_cue_queue_volume_array[SOUND_WORK_SE_QUEUE_COUNT] = { + { 0.0f, 1.0f, }, + { 0.0f, 1.0f, }, + { 0.0f, 1.0f, }, + { 0.3f, 1.0f, }, + { 0.3f, 1.0f, }, +}; + +static size_t ima_decode(int16_t* dst, size_t dst_size, uint8_t* data, size_t samples_count, + size_t channels, ima_storage* storage, size_t storage_size); + +namespace sound { + namespace wasapi { + System::System() : wave_format(), pEnumerator(), pDevice(), pAudioClient(), + samples_count(), pRenderClient(), pClockAdjustment(), hEvent(), + channels(), sample_rate(), bit_depth(), mixer(), thread(), format() { + + } + + System::~System() { + Reset(); + } + + void System::Init(size_t se_channels_count, size_t streaming_channels_count, + bool separate_speakers_headphones) { + if (FAILED(CoCreateInstance(__uuidof(MMDeviceEnumerator), + 0, 1, __uuidof(IMMDeviceEnumerator), (LPVOID*)&pEnumerator)) + || FAILED(pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice))) + return; + + if (FAILED(pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient))) + return; + + WAVEFORMATEXTENSIBLE* mix_format; + if (FAILED(pAudioClient->GetMixFormat((WAVEFORMATEX**)&mix_format))) + return; + + int32_t channels = separate_speakers_headphones ? 4 : 2; + int32_t sample_rate; + int32_t bit_depth; + if (mix_format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) { + wave_format = *mix_format; + sample_rate = mix_format->Format.nSamplesPerSec; + bit_depth = mix_format->Samples.wValidBitsPerSample; + } + else { + wave_format.Format = mix_format->Format; + sample_rate = mix_format->Format.nSamplesPerSec; + bit_depth = 16; + } + + if (mix_format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE + && !memcmp(&wave_format.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID))) { + bit_depth = 32; + format = AUDIO_FORMAT_F32; + wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; + } + else { + switch (bit_depth) { + default: + bit_depth = 16; + case 16: + format = AUDIO_FORMAT_I16; + break; + case 24: + format = AUDIO_FORMAT_I24; + break; + case 32: + format = AUDIO_FORMAT_I32; + break; + } + + wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + } + + wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + wave_format.Format.nChannels = (WORD)channels; + wave_format.Format.nSamplesPerSec = (DWORD)sample_rate; + wave_format.Format.nAvgBytesPerSec = (DWORD)(sample_rate * (bit_depth / 8) * channels); + wave_format.Format.nBlockAlign = (WORD)((bit_depth / 8) * channels); + wave_format.Format.wBitsPerSample = (WORD)bit_depth; + wave_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + wave_format.Samples.wValidBitsPerSample = (WORD)bit_depth; + wave_format.dwChannelMask = channels == 4 ? KSAUDIO_SPEAKER_QUAD : KSAUDIO_SPEAKER_STEREO; + + WAVEFORMATEXTENSIBLE* closest_format; + if (FAILED(pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, + &wave_format.Format, (WAVEFORMATEX**)&closest_format))) { + wave_format = {}; + return; + } + + this->channels = channels; + this->sample_rate = sample_rate; + this->bit_depth = bit_depth; + + mixer = new Mixer(this); + if (!mixer) + return; + + REFERENCE_TIME hnsPeriod; + if (FAILED(pAudioClient->GetDevicePeriod(&hnsPeriod, 0))) + return; + + if (pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, + AUDCLNT_STREAMFLAGS_RATEADJUST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + hnsPeriod, 0, &wave_format.Format, 0) == AUDCLNT_ERR(0x019)) { + if (FAILED(pAudioClient->GetBufferSize(&samples_count))) + return; + + pAudioClient->Release(); + + if (FAILED(pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient))) + return; + + hnsPeriod = (REFERENCE_TIME)((double_t)(int32_t)samples_count + * 10000000.0 / (double_t)sample_rate + 0.5); + + if (FAILED(pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, + AUDCLNT_STREAMFLAGS_RATEADJUST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + hnsPeriod, 0, &wave_format.Format, 0))) + return; + } + + if (FAILED(pAudioClient->GetBufferSize(&samples_count))) + return; + + // Rounding to prev base 2 + while (true) { + uint32_t _samples_count = samples_count; + _samples_count--; + _samples_count |= _samples_count >> 1; + _samples_count |= _samples_count >> 2; + _samples_count |= _samples_count >> 4; + _samples_count |= _samples_count >> 8; + _samples_count |= _samples_count >> 16; + _samples_count++; + _samples_count >>= 1; + if (_samples_count + (_samples_count >> 1) < samples_count) { + samples_count = _samples_count; + break; + } + samples_count = _samples_count; + } + + if (!mixer->Init(se_channels_count, streaming_channels_count, samples_count)) + return; + + hEvent = CreateEventW(0, 0, 0, 0); + if (!hEvent) + return; + + thread = new std::thread(System::ThreadMain, this); + if (thread) { + wchar_t buf[0x80]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), L"sound::wasapi::System #%d", sound_wasapi_system_counter++); + SetThreadDescription((HANDLE)thread->native_handle(), buf); + } + + if (!thread || !SetThreadPriority((HANDLE)thread->native_handle(), THREAD_PRIORITY_HIGHEST)) + return; + + if (FAILED(pAudioClient->SetEventHandle(hEvent))) + return; + + if (SUCCEEDED(pAudioClient->GetService(__uuidof(IAudioRenderClient), (void**)&pRenderClient))) { + void* data = 0; + if (SUCCEEDED(pRenderClient->GetBuffer(samples_count, (BYTE**)&data)) + && SUCCEEDED(pRenderClient->ReleaseBuffer(samples_count, AUDCLNT_BUFFERFLAGS_SILENT))) + pAudioClient->Start(); + } + + if (SUCCEEDED(pAudioClient->GetService(__uuidof(IAudioClockAdjustment), (void**)&pClockAdjustment))) + pClockAdjustment->SetSampleRate((float_t)44100); + } + + void System::Reset() { + if (thread) { + thread_state.set(1); + thread->join(); + delete thread; + thread = 0; + } + + if (pAudioClient) + pAudioClient->Stop(); + + if (pClockAdjustment) { + pClockAdjustment->Release(); + pClockAdjustment = 0; + } + + if (pRenderClient) { + pRenderClient->Release(); + pRenderClient = 0; + } + + if (pAudioClient) { + pAudioClient->Release(); + pAudioClient = 0; + } + + if (pDevice) { + pDevice->Release(); + pDevice = 0; + } + + if (pEnumerator) { + pEnumerator->Release(); + pEnumerator = 0; + } + + if (hEvent) { + CloseHandle(hEvent); + hEvent = 0; + } + + if (mixer) { + delete mixer; + mixer = 0; + } + } + + void System::ThreadMain(System* system) { + if (!system) + return; + + while (!system->thread_state.get()) { + WaitForSingleObject(system->hEvent, -1); + void* data = 0; + if (SUCCEEDED(system->pRenderClient->GetBuffer(system->samples_count, (BYTE**)&data))) { + if (system->mixer && data) + system->mixer->FillBuffer(data, + system->samples_count, false, false, system->format); + + if (FAILED(system->pRenderClient->ReleaseBuffer(system->samples_count, 0))) + break; + } + } + system->thread_state.set(0); + } + + Mixer::Mixer(System* system) : se_channels(), se_channels_count(), + streaming_channels(), streaming_channels_count(), mix_buffer(), mix_buffer_size() { + this->system = system; + master_volume = 1.0f; + channels_volume[0] = 1.0f; + channels_volume[1] = 1.0f; + channels_volume[2] = 1.0f; + channels_volume[3] = 1.0f; + } + + Mixer::~Mixer() { + Reset(); + } + + void Mixer::FillBuffer(void* buffer, size_t samples_count, + bool disable_headphones_volume, bool invert_phase, AudioFormat format) { + if (!system) + return; + + float_t spk_l_volume = 0.0f; + float_t spk_r_volume = 0.0f; + float_t hph_l_volume = 0.0f; + float_t hph_r_volume = 0.0f; + + { + std::unique_lock u_lock(volume_mtx); + float_t master_volume = this->master_volume; + spk_l_volume = master_volume * channels_volume[0]; + spk_r_volume = master_volume * channels_volume[1]; + hph_l_volume = master_volume * channels_volume[2]; + hph_r_volume = master_volume * channels_volume[3]; + } + + if (disable_headphones_volume) { + hph_l_volume = spk_l_volume; + hph_r_volume = spk_r_volume; + } + else if (invert_phase) { + spk_l_volume = -spk_l_volume; + spk_l_volume = -spk_l_volume; + hph_l_volume = -hph_l_volume; + hph_r_volume = -hph_r_volume; + } + + memset(mix_buffer, 0, mix_buffer_size); + if (streaming_channels) + for (size_t i = 0; i < streaming_channels_count; i++) + streaming_channels[i].FillBuffer(mix_buffer, samples_count, 1.0f); + + if (se_channels) + for (size_t i = 0; i < se_channels_count; i++) + se_channels[i].FillBuffer(mix_buffer, samples_count, 1.0f); + + sound_buffer_data* _mix_buffer = mix_buffer; + switch (format) { + case AUDIO_FORMAT_I16: { + int16_t* _buffer = (int16_t*)buffer; + switch (system->channels) { + case 2: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + int32_t hph_l = (int32_t)(_mix_buffer->hph_l * hph_l_volume * (float_t)0x7FFF); + int32_t hph_r = (int32_t)(_mix_buffer->hph_r * hph_r_volume * (float_t)0x7FFF); + *_buffer++ = (int16_t)clamp_def(hph_l, -0x8000, 0x7FFF); + *_buffer++ = (int16_t)clamp_def(hph_r, -0x8000, 0x7FFF); + } + break; + case 4: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + int32_t spk_l = (int32_t)(_mix_buffer->spk_l * spk_l_volume * (float_t)0x7FFF); + int32_t spk_r = (int32_t)(_mix_buffer->spk_r * spk_r_volume * (float_t)0x7FFF); + int32_t hph_l = (int32_t)(_mix_buffer->hph_l * hph_l_volume * (float_t)0x7FFF); + int32_t hph_r = (int32_t)(_mix_buffer->hph_r * hph_r_volume * (float_t)0x7FFF); + *_buffer++ = (int16_t)clamp_def(spk_l, -0x8000, 0x7FFF); + *_buffer++ = (int16_t)clamp_def(spk_r, -0x8000, 0x7FFF); + *_buffer++ = (int16_t)clamp_def(hph_l, -0x8000, 0x7FFF); + *_buffer++ = (int16_t)clamp_def(hph_r, -0x8000, 0x7FFF); + } + break; + } + } break; + case AUDIO_FORMAT_I24: { + int8_t* _buffer = (int8_t*)buffer; + switch (system->channels) { + case 2: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + int32_t hph_l = (int32_t)(_mix_buffer->hph_l * hph_l_volume * (float_t)0x7FFFFF); + int32_t hph_r = (int32_t)(_mix_buffer->hph_r * hph_r_volume * (float_t)0x7FFFFF); + hph_l = clamp_def(hph_l, -0x800000, 0x7FFFFF); + hph_r = clamp_def(hph_r, -0x800000, 0x7FFFFF); + *(uint16_t*)&_buffer[0] = (uint16_t)hph_l; + *(uint8_t*)&_buffer[2] = (uint8_t)(hph_l >> 16); + *(uint16_t*)&_buffer[3] = (uint16_t)hph_r; + *(uint8_t*)&_buffer[5] = (uint8_t)(hph_r >> 16); + _buffer += 6; + } + break; + case 4: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + int32_t spk_l = (int32_t)(_mix_buffer->spk_l * spk_l_volume * (float_t)0x7FFFFF); + int32_t spk_r = (int32_t)(_mix_buffer->spk_r * spk_r_volume * (float_t)0x7FFFFF); + int32_t hph_l = (int32_t)(_mix_buffer->hph_l * hph_l_volume * (float_t)0x7FFFFF); + int32_t hph_r = (int32_t)(_mix_buffer->hph_r * hph_r_volume * (float_t)0x7FFFFF); + spk_l = clamp_def(spk_l, -0x800000, 0x7FFFFF); + spk_r = clamp_def(spk_r, -0x800000, 0x7FFFFF); + hph_l = clamp_def(hph_l, -0x800000, 0x7FFFFF); + hph_r = clamp_def(hph_r, -0x800000, 0x7FFFFF); + *(uint16_t*)&_buffer[0] = (uint16_t)spk_l; + *(uint8_t*)&_buffer[2] = (uint8_t)(spk_l >> 16); + *(uint16_t*)&_buffer[3] = (uint16_t)spk_r; + *(uint8_t*)&_buffer[5] = (uint8_t)(spk_r >> 16); + *(uint16_t*)&_buffer[6] = (uint16_t)hph_l; + *(uint8_t*)&_buffer[8] = (uint8_t)(hph_l >> 16); + *(uint16_t*)&_buffer[9] = (uint16_t)hph_r; + *(uint8_t*)&_buffer[11] = (uint8_t)(hph_r >> 16); + _buffer += 12; + } + break; + } + } break; + case AUDIO_FORMAT_I32: { + int32_t* _buffer = (int32_t*)buffer; + switch (system->channels) { + case 2: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + int64_t hph_l = (int64_t)((double_t)_mix_buffer->hph_l * hph_l_volume * (double_t)0x7FFFFFFF); + int64_t hph_r = (int64_t)((double_t)_mix_buffer->hph_r * hph_r_volume * (double_t)0x7FFFFFFF); + *_buffer++ = (int32_t)clamp_def(hph_l, -0x80000000LL, 0x7FFFFFFFLL); + *_buffer++ = (int32_t)clamp_def(hph_r, -0x80000000LL, 0x7FFFFFFFLL); + } + break; + case 4: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + int64_t spk_l = (int64_t)((double_t)_mix_buffer->spk_l * spk_l_volume * (double_t)0x7FFFFFFF); + int64_t spk_r = (int64_t)((double_t)_mix_buffer->spk_r * spk_r_volume * (double_t)0x7FFFFFFF); + int64_t hph_l = (int64_t)((double_t)_mix_buffer->hph_l * hph_l_volume * (double_t)0x7FFFFFFF); + int64_t hph_r = (int64_t)((double_t)_mix_buffer->hph_r * hph_r_volume * (double_t)0x7FFFFFFF); + *_buffer++ = (int32_t)clamp_def(spk_l, -0x80000000LL, 0x7FFFFFFFLL); + *_buffer++ = (int32_t)clamp_def(spk_r, -0x80000000LL, 0x7FFFFFFFLL); + *_buffer++ = (int32_t)clamp_def(hph_l, -0x80000000LL, 0x7FFFFFFFLL); + *_buffer++ = (int32_t)clamp_def(hph_r, -0x80000000LL, 0x7FFFFFFFLL); + } + break; + } + } break; + case AUDIO_FORMAT_F32: { + float_t* _buffer = (float_t*)buffer; + switch (system->channels) { + case 2: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + *_buffer++ = _mix_buffer->hph_l * hph_l_volume; + *_buffer++ = _mix_buffer->hph_r * hph_r_volume; + } + break; + case 4: + for (size_t i = samples_count; i; i--, _mix_buffer++) { + *_buffer++ = _mix_buffer->spk_l * spk_l_volume; + *_buffer++ = _mix_buffer->spk_r * spk_r_volume; + *_buffer++ = _mix_buffer->hph_l * hph_l_volume; + *_buffer++ = _mix_buffer->hph_r * hph_r_volume; + } + break; + } + } break; + } + } + + SEChannel* Mixer::GetSEChannel(size_t channel) { + if (channel < se_channels_count && se_channels) + return &se_channels[channel]; + return 0; + } + + StreamingChannel* Mixer::GetStreamingChannel(size_t channel) { + if (channel < streaming_channels_count && streaming_channels) + return &streaming_channels[channel]; + return 0; + } + + bool Mixer::Init(size_t se_channels_count, size_t streaming_channels_count, size_t samples_count) { + if (this->se_channels_count || this->streaming_channels_count) { + Reset(); + return false; + } + + mix_buffer_size = sizeof(sound_buffer_data) * samples_count; + mix_buffer = (sound_buffer_data*)malloc(mix_buffer_size); + if (!mix_buffer) { + Reset(); + return false; + } + memset(mix_buffer, 0, mix_buffer_size); + + if (se_channels_count) { + se_channels = new SEChannel[se_channels_count]; + if (!se_channels) { + Reset(); + return false; + } + + for (size_t i = 0; i < se_channels_count; i++) + se_channels[i].Init(this); + } + this->se_channels_count = se_channels_count; + + if (streaming_channels_count) { + streaming_channels = new StreamingChannel[streaming_channels_count]; + if (!streaming_channels) { + Reset(); + return false; + } + + for (size_t i = 0; i < streaming_channels_count; i++) + streaming_channels[i].Init(this, samples_count); + } + this->streaming_channels_count = streaming_channels_count; + return true; + } + + void Mixer::Reset() { + if (streaming_channels) { + for (size_t i = 0; i < streaming_channels_count; i++) + streaming_channels[i].Reset(); + + delete[] streaming_channels; + streaming_channels = 0; + } + streaming_channels_count = 0; + + if (se_channels) { + for (size_t i = 0; i < se_channels_count; i++) + se_channels[i].Reset(); + + delete[] se_channels; + se_channels = 0; + } + se_channels_count = 0; + + if (mix_buffer) { + free(mix_buffer); + mix_buffer = 0; + } + mix_buffer_size = 0; + } + + void Mixer::SetChannelsVolume(int32_t mask, float_t value) { + std::unique_lock u_lock(volume_mtx); + for (int32_t i = 0; i < 4; i++) + if (mask & (1 << i)) + channels_volume[i] = value; + } + + void Mixer::SetMasterVolume(float_t value) { + std::unique_lock u_lock(volume_mtx); + master_volume = value; + } + + SEChannel::SEChannel() : mixer(), buffer(), buffer_size(), channels(), + samples_count(), sample_rate(), loop_start(), loop_end(), current_sample() { + master_volume = 1.0f; + channels_volume[0] = 1.0f; + channels_volume[1] = 1.0f; + channels_volume[2] = 1.0f; + channels_volume[3] = 1.0f; + } + + SEChannel::~SEChannel() { + Reset(); + } + + void SEChannel::FillBuffer(sound_buffer_data* buffer, size_t samples_count, float_t volume) { + std::unique_lock u_lock(mtx); + if (!play_state.get() || !buffer) + return; + + float_t master_volume = this->master_volume; + float_t spk_l_volume = master_volume * channels_volume[0]; + float_t spk_r_volume = master_volume * channels_volume[1]; + float_t hph_l_volume = master_volume * channels_volume[2]; + float_t hph_r_volume = master_volume * channels_volume[3]; + + vec4 channels_volume(spk_l_volume, spk_r_volume, hph_l_volume, hph_r_volume); + + size_t _samples_count = this->samples_count; + if (channels == 1) + for (size_t i = samples_count; i && current_sample < _samples_count; i--, buffer++) { + float_t* _buffer = this->buffer + current_sample; + *(vec4*)buffer = channels_volume * _buffer[0] + *(vec4*)buffer; + + current_sample++; + if ((loop_start || loop_end) && current_sample > loop_end) + current_sample = loop_start; + } + if (channels == 2) + for (size_t i = samples_count; i && current_sample < _samples_count; i--, buffer++) { + float_t* _buffer = this->buffer + current_sample * 2; + *(vec4*)buffer = channels_volume * vec4(_buffer[0], _buffer[1], + _buffer[0], _buffer[1]) + *(vec4*)buffer; + + current_sample++; + if ((loop_start || loop_end) && current_sample > loop_end) + current_sample = loop_start; + } + else if (channels == 4) + for (size_t i = samples_count; i && current_sample < _samples_count; i--, buffer++) { + float_t* _buffer = this->buffer + current_sample * 4; + *(vec4*)buffer = channels_volume * *(vec4*)_buffer + *(vec4*)buffer; + + current_sample++; + if ((loop_start || loop_end) && current_sample > loop_end) + current_sample = loop_start; + } + + if (current_sample >= _samples_count) + ResetData(); + } + + bool SEChannel::Init(Mixer* mixer) { + bool ret = false; + { + std::unique_lock u_lock(mtx); + if (!this->mixer) { + this->mixer = mixer; + buffer = 0; + buffer_size = 0; + ret = true; + } + } + + if (!ret) + Reset(); + return ret; + } + + float_t* SEChannel::InitBuffer(size_t channels, size_t samples_count, size_t sample_rate) { + std::unique_lock u_lock(mtx); + ResetData(); + buffer = (float_t*)malloc(sizeof(float_t) * samples_count * channels); + if (!buffer) + return 0; + + buffer_size = sizeof(float_t) * samples_count * channels; + memset(buffer, 0, buffer_size); + this->channels = channels; + this->sample_rate = sample_rate; + this->samples_count = samples_count; + loop_start = 0; + loop_end = 0; + return buffer; + } + + bool SEChannel::Play(size_t loop_start, size_t loop_end) { + std::unique_lock u_lock(mtx); + if (!buffer) + return false; + + this->loop_start = loop_start; + this->loop_end = loop_end; + current_sample = 0; + play_state.set(1); + return true; + } + + void SEChannel::Reset() { + std::unique_lock u_lock(mtx); + ResetData(); + } + + void SEChannel::ResetData() { + play_state.set(0); + if (buffer) { + free(buffer); + buffer = 0; + } + buffer_size = 0; + channels = 0; + samples_count = 0; + sample_rate = 0; + loop_start = 0; + loop_end = 0; + current_sample = 0; + } + + void SEChannel::ResetDataProt() { + if (!play_state.get()) + return; + + std::unique_lock u_lock(mtx); + ResetData(); + } + + void SEChannel::SetChannelsVolume(int32_t mask, float_t value) { + std::unique_lock u_lock(mtx); + for (int32_t i = 0; i < 4; i++) + if (mask & (1 << i)) + channels_volume[i] = value; + } + + void SEChannel::SetMasterVolume(float_t value) { + std::unique_lock u_lock(mtx); + master_volume = value; + } + + StreamingChannel::StreamingChannel() : mixer(), buffer(), + buffer_size(), callback_func(), callback_data() { + master_volume = 1.0f; + channels_volume[0] = 1.0f; + channels_volume[1] = 1.0f; + channels_volume[2] = 1.0f; + channels_volume[3] = 1.0f; + } + + StreamingChannel::~StreamingChannel() { + Reset(); + } + + void StreamingChannel::FillBuffer(sound_buffer_data* buffer, size_t samples_count, float_t volume) { + if (playing_state.get() && reset_state.get()) { + std::unique_lock u_lock(mtx); + ResetData(); + } + + if (!playing_state.get() || !this->buffer || !buffer) + return; + + float_t spk_l_volume = 0.0f; + float_t spk_r_volume = 0.0f; + float_t hph_l_volume = 0.0f; + float_t hph_r_volume = 0.0f; + { + std::unique_lock u_lock(mtx); + if (!callback_func) + return; + + memset(this->buffer, 0, buffer_size); + + callback_func(this->buffer, samples_count, callback_data); + + float_t master_volume = this->master_volume; + spk_l_volume = master_volume * channels_volume[0]; + spk_r_volume = master_volume * channels_volume[1]; + hph_l_volume = master_volume * channels_volume[2]; + hph_r_volume = master_volume * channels_volume[3]; + } + + vec4 channels_volume(spk_l_volume, spk_r_volume, hph_l_volume, hph_r_volume); + + sound_buffer_data* _buffer = this->buffer; + for (size_t i = samples_count; i; i--, buffer++, _buffer++) + *(vec4*)buffer = channels_volume * *(vec4*)_buffer + *(vec4*)buffer; + } + + bool StreamingChannel::Init(Mixer* mixer, size_t samples_count) { + if (this->mixer) { + Reset(); + return false; + } + + this->mixer = mixer; + buffer_size = sizeof(sound_buffer_data) * samples_count; + buffer = (sound_buffer_data*)malloc(buffer_size); + if (!buffer) { + Reset(); + return false; + } + + memset(buffer, 0, buffer_size); + return true; + } + + void StreamingChannel::Reset() { + reset_state.set(1); + FillBuffer(0, 0, 0.0f); + if (buffer) { + free(buffer); + buffer = 0; + } + mixer = 0; + buffer_size = 0; + } + + void StreamingChannel::ResetData() { + playing_state.set(0); + reset_state.set(0); + callback_func = 0; + callback_data = 0; + } + + bool StreamingChannel::SetCallback(void(*func)(sound_buffer_data* buffer, + size_t samples_count, void* data), void* data) { + std::unique_lock u_lock(mtx); + ResetData(); + callback_func = func; + callback_data = data; + playing_state.set(1); + return true; + } + + void StreamingChannel::SetChannelsVolume(int32_t mask, float_t value) { + std::unique_lock u_lock(mtx); + for (int32_t i = 0; i < 4; i++) + if (mask & (1 << i)) + channels_volume[i] = value; + } + + void StreamingChannel::SetMasterVolume(float_t value) { + std::unique_lock u_lock(mtx); + master_volume = value; + } + } +} + +sound_db_farc::sound_db_farc() : loaded() { + +} + +sound_db_farc::~sound_db_farc() { + +} + +bool sound_db_farc::load() { + if (loaded) + return false; + else if (file_handler.check_not_ready()) + return true; + + + farc.read(file_handler.get_data(), file_handler.get_size()); + if (farc.files.size() && sound_work->ParseProperty(this)) + loaded = true; + return false; +} + +bool sound_db_farc::read(const char* file_path) { + if (loaded) + unload(); + + this->file_path.assign(file_path); + return file_handler.read_file(&data_list[DATA_AFT], file_path); +} + +bool sound_db_farc::unload() { + sound_work_release_farc_se(file_path.c_str()); + if (!sound_work->UnloadProperty(file_path.c_str())) + return false; + + file_path.clear(); + loaded = false; + file_handler.free_data(); + return true; +} + +sound_db_property::sound_db_property() : farc(), +volume(), loop_start(), loop_end(), release_time()/*, field_48()*/ { + +} + +sound_db_property::~sound_db_property() { + +} + +SoundCue::SoundCue() : thread(), property(), counter(), release_time(), se_channel() { + queue_index = SOUND_WORK_SE_QUEUE_COUNT; + volume = new SoundCueVolume(this); +} + +SoundCue::~SoundCue() { + if (thread) { + thread_state.set(1); + cnd.notify_one(); + thread->join(); + delete thread; + thread = 0; + } + + if (volume) { + delete volume; + volume = 0; + } +} + +bool SoundCue::CanPlay() { + if (se_channel && se_channel->play_state.get()) + return true; + return !!load_state.get(); +} + +void SoundCue::Ctrl() { + std::unique_lock u_lock(mtx); + while (!thread_state.get()) { + if (!data_state.get()) + cnd.wait(u_lock); + + int32_t _data_state = data_state.get(); + data_state.set(SOUND_CUE_DATA_STATE_NONE); + switch (_data_state) { + case SOUND_CUE_DATA_STATE_LOAD: + LoadData(); + break; + case SOUND_CUE_DATA_STATE_RESET: + ResetData(); + break; + } + } + thread_state.set(0); +} + +int32_t SoundCue::Load(int32_t queue_index, const char* name, float_t volume) { + ReleaseProt(true); + std::unique_lock u_lock(mtx); + if (!se_channel) + return 0; + + sound_db_property* property = sound_work->FindProperty(name); + if (!property) + return 0; + + this->name.assign(name); + this->property = property; + this->queue_index = queue_index; + this->volume->SetValue(volume); + + Play(); + load_state.set(1); + data_state.set(SOUND_CUE_DATA_STATE_LOAD); + cnd.notify_one(); + counter = sound_work->counter; + if (++sound_work->counter <= -1) + sound_work->counter = 1; + return counter; +} + +void SoundCue::LoadData() { + WaveAudio* _wave_audio = 0; + if (!property || !property->farc) { + load_state.set(0); + return; + } + + WaveAudio* wave_audio = wave_audio_storage_get_wave_audio(name); + if (!wave_audio) { + _wave_audio = new WaveAudio; + if (_wave_audio && _wave_audio->Read(property->farc, property->file_name.c_str())) + wave_audio = _wave_audio; + } + + if (wave_audio) { + float_t* buffer = se_channel->InitBuffer(wave_audio->data.channels, + wave_audio->data.samples_count, wave_audio->data.sample_rate); + if (buffer) { + memmove(buffer, wave_audio->buffer, wave_audio->buffer_size); + se_channel->Play(property->loop_start, property->loop_end); + } + } + + if (_wave_audio) { + _wave_audio->Reset(); + delete _wave_audio; + } + load_state.set(0); +} + +void SoundCue::Play() { + if (se_channel && !property) + return; + + bool master_volume_set = false; + float_t master_volume = property->volume * volume->value; + + if (volume->set) { + volume->set = false; + master_volume_set = true; + } + + if (release_time > 0.0f) { + double_t release_time = this->release_time * 1000.0; + double_t current_time = time.calc_time(); + double_t remain_time; + if (current_time >= release_time) { + remain_time = 0.0; + Release(true); + } + else + remain_time = release_time - current_time; + + master_volume_set = true; + master_volume = (float_t)(remain_time / release_time) * master_volume; + } + + if (se_channel) { + if (master_volume_set) + se_channel->SetMasterVolume(master_volume); + + if (!queue_index) + se_channel->SetChannelsVolume(0x03, get_max_speakers_volume()); + } + return; +} + +void SoundCue::PlayProt() { + std::unique_lock u_lock(mtx); + Play(); +} + +void SoundCue::Release(bool force_release) { + if (!property || fabsf(property->release_time) <= 0.000001f || force_release) { + data_state.set(SOUND_CUE_DATA_STATE_RESET); + cnd.notify_one(); + queue_index = SOUND_WORK_SE_QUEUE_COUNT; + name.clear(); + property = 0; + counter = 0; + release_time = 0.0f; + } + else + release_time = property->release_time; + + time.get_timestamp(); +} + +void SoundCue::ReleaseProt(bool force_release) { + std::unique_lock u_lock(mtx); + Release(force_release); +} + +void SoundCue::Reset() { + ReleaseProt(true); + + if (thread) { + thread_state.set(1); + cnd.notify_one(); + thread->join(); + delete thread; + thread = 0; + } +} + +void SoundCue::ResetData() { + if (se_channel) + se_channel->ResetDataProt(); +} + +void SoundCue::SetSEChannel(sound::wasapi::SEChannel* se_channel) { + this->se_channel = se_channel; + if (se_channel) + se_channel->SetMasterVolume(1.0f); + + thread = new std::thread(SoundCue::ThreadMain, this); + if (thread) { + wchar_t buf[0x80]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), L"SoundCue #%d", sound_cue_counter++); + SetThreadDescription((HANDLE)thread->native_handle(), buf); + } +} + +void SoundCue::ThreadMain(SoundCue* cue) { + if (cue) + cue->Ctrl(); +} + +WaveAudioData::WaveAudioData() : format(), channels(), sample_rate(), bit_depth(), +samples_count(), position(), data_size(), has_loop(), loop_start(), loop_end() { + +} + +WaveAudioData::~WaveAudioData() { + +} + +bool WaveAudioData::Read(WaveAudioDataFileMemoryStream* fms) { + Reset(); + return ReadDiva(fms)/* || ReadRiff(fms)*/; +} + +bool WaveAudioData::ReadData(const void* data, size_t size) { + if (!this || !data || !size) + return false; + + WaveAudioDataFileMemoryStream fms(data, size); + return Read(&fms); +} + +bool WaveAudioData::ReadDiva(WaveAudioDataFileMemoryStream* fms) { + struct DivaAudioHeader { + uint32_t signature; + uint8_t pad_4[4]; + uint32_t size; + uint32_t sample_rate; + uint32_t samples_count; + uint32_t loop_start; + uint32_t loop_end; + uint8_t channels; + uint8_t pad_1D[3]; + uint8_t reserved1[32]; + } header; + + if (fms->file) { + if (fseek(fms->file, 0, SEEK_SET)) + return false; + } + else { + if (!fms->data || !fms->size) + return false; + fms->position = 0; + } + + size_t read_bytes = 0; + if (fms->file) + read_bytes = fread(&header, sizeof(DivaAudioHeader), 1, fms->file); + else if (fms->data && fms->size && fms->position + sizeof(DivaAudioHeader) <= fms->size) { + memmove(&header, (uint8_t*)fms->data + fms->position, sizeof(DivaAudioHeader)); + read_bytes = sizeof(DivaAudioHeader); + } + + if (!read_bytes || header.signature != reverse_endianness_uint32_t('DIVA')) + return false; + + format = WAVE_AUDIO_DATA_FORMAT_DIVA; + channels = header.channels; + sample_rate = header.sample_rate; + bit_depth = 0; + samples_count = header.samples_count; + position = 0; + data_size = 0; + has_loop = header.loop_start < header.loop_end; + loop_start = header.loop_start; + loop_end = header.loop_end; + return true; +} + +void WaveAudioData::Reset() { + format = WAVE_AUDIO_DATA_FORMAT_NONE; + channels = 0; + sample_rate = 0; + bit_depth = 0; + samples_count = 0; + position = 0; + data_size = 0; + has_loop = false; + loop_start = 0; + loop_end = 0; +} + +WaveAudio::WaveAudio() : buffer(), buffer_size() { + +} + +bool WaveAudio::Read(sound_db_farc* farc, const char* file_name) { + if (!this) + return false; + + if (!farc) { + Reset(); + return false; + } + + ::farc* f = &farc->farc; + farc_file* ff = f->read_file(file_name); + if (!ff || !ff->data || !ff->size) { + Reset(); + return false; + } + + data.ReadData(ff->data, ff->size); + + size_t buffer_size = sizeof(float_t) * data.samples_count * data.channels; + float_t* buffer = (float_t*)malloc(buffer_size); + this->buffer_size = buffer_size; + this->buffer = buffer; + + if (!buffer) { + Reset(); + return false; + } + + bool ret = false; + memset(buffer, 0, buffer_size); + if (data.format == WAVE_AUDIO_DATA_FORMAT_DIVA) { + size_t buf_size = sizeof(int16_t) * data.samples_count * data.channels; + int16_t* buf = (int16_t*)malloc(buf_size); + if (!buf) { + Reset(); + return false; + } + + memset(buf, 0, buf_size); + + { + std::vector storage(data.channels); + data.samples_count = ima_decode(buf, buf_size, (uint8_t*)ff->data + data.position, + data.samples_count, data.channels, storage.data(), storage.size()); + } + + int16_t* _buf = buf; + float_t* buffer = this->buffer; + size_t channels = data.channels; + size_t samples_count = data.samples_count; + for (size_t i = samples_count; i; i--) + for (size_t j = channels; j; j--) + *buffer++ = (float_t)*_buf++ * (float_t)(1.0 / (double_t)0x7FFF); + + free(buf); + ret = true; + } + + if (!ret) { + Reset(); + return false; + } + return true; +} + +void WaveAudio::Reset() { + if (buffer) { + free(buffer); + buffer = 0; + } + buffer_size = 0; + data.Reset(); +} + +SoundWork::SoundWork() : se_queue_enable(), streaming_enable(), se_queue_volume() { + counter = 1; + speakers_volume = get_max_speakers_volume(); + speakers_volume_changed = true; + headphones_volume = get_min_headphones_volume(); + headphones_volume_changed = true; + se_volume = 1.0f; + + for (bool& i : se_queue_enable) + i = true; + + for (bool& i : streaming_enable) + i = true; + + for (int32_t i = 0; i < SOUND_WORK_SE_QUEUE_COUNT; i++) + se_queue_volume[i] = sound_cue_queue_volume_array_get_max(i); +} + +SoundWork::~SoundWork() { + +} + +sound_db_property* SoundWork::FindProperty(const char* name) { + auto elem = properties.find(name); + if (elem != properties.end()) + return &elem->second; + return 0; +} + +bool SoundWork::ParseProperty(sound_db_farc* snd_db_farc) { + if (!snd_db_farc) + return false; + + farc& f = snd_db_farc->farc; + farc_file* property_ff = f.read_file("property.txt"); + if (!property_ff || !property_ff->data || !property_ff->size) + return false; + + key_val kv; + kv.parse(property_ff->data, property_ff->size); + + int32_t max; + float_t volume_bias; + if (!kv.read("max", max) || !kv.read("volume_bias", volume_bias)) + return false; + + for (int32_t i = 0, j = 1; i < max; i++, j++) { + if (!kv.open_scope_fmt("%zu", j)) + continue; + + std::string name; + std::string file_name; + if (!kv.read("name", name) || !kv.read("file_name", file_name) + || !kv.has_key("volume") || !f.has_file(file_name.c_str())) { + kv.close_scope(); + continue; + } + + uint32_t loop_start = 0; + if (kv.open_scope("loop_start")) { + kv.read(loop_start); + kv.close_scope(); + } + + uint32_t loop_end = 0; + if (kv.open_scope("loop_end")) { + kv.read(loop_end); + kv.close_scope(); + } + + float_t release_time = 0.0f; + if (kv.open_scope("release_time")) { + kv.read(release_time); + release_time *= 0.001f; + kv.close_scope(); + } + + float_t volume = 0.0f; + kv.read("volume", volume); + + sound_db_property property; + property.farc = snd_db_farc; + property.file_name.assign(file_name); + property.volume = volume * volume_bias; + property.loop_start = loop_start; + property.loop_end = loop_end; + property.release_time = release_time; + properties.insert_or_assign(name, property); + kv.close_scope(); + } + return true; +} + +bool SoundWork::UnloadProperty(const char* file_path) { + for (std::map::iterator i + = properties.begin(); i != properties.end(); i++) + if (!i->second.farc->file_path.compare(file_path)) { + properties.erase(i); + break; + } + return true; +} + +extern float_t get_min_headphones_volume() { + return 1.0f;//0.02f; +} + +extern float_t get_max_headphones_volume() { + return 0.45f; +} + +extern float_t get_min_speakers_volume() { + return 0.0f; +} + +extern float_t get_max_speakers_volume() { + return 0.8f; +} + +float_t db_to_ratio(int32_t value) { + if (value <= -10000) + return 0.0f; + else if (value >= 0) + return 1.0f; + else + return powf(10.0, (float_t)value * 0.0005f); +} + +int32_t ratio_to_db(float_t value) { + if (value <= 0.0f) + return -10000; + else if (value >= 1.0f) + return 0; + else + return (int32_t)(log10f(value) * 20.0f * 100.0f); +} + +void sound_init() { + IMMDeviceEnumerator* mmEnumerator; + if (SUCCEEDED(CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, + CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&mmEnumerator))) { + IMMDeviceCollection* collection; + if (SUCCEEDED(mmEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &collection))) { + UINT count; + if (SUCCEEDED(collection->GetCount(&count))) { + for (UINT i = 0; i < count; i++) { + IMMDevice* device; + if (FAILED(collection->Item(i, &device))) + continue; + + wchar_t* wstrID; + if (SUCCEEDED(device->GetId((LPWSTR*)&wstrID))) { + IPropertyStore* store; + if (SUCCEEDED(device->OpenPropertyStore(STGM_READ, &store))) { + PROPVARIANT pv; + + PropVariantInit(&pv); + if (SUCCEEDED(store->GetValue(PKEY_Device_FriendlyName, &pv))) + printf("%ls\n", pv.pwszVal); + PropVariantClear(&pv); + + store->Release(); + } + CoTaskMemFree((LPVOID)wstrID); + } + device->Release(); + } + } + collection->Release(); + } + mmEnumerator->Release(); + } + + if (!sound_work) + sound_work = new SoundWork; + + if (!sound_wasapi_system_data) + sound_wasapi_system_data = new sound::wasapi::System; + + sound_wasapi_system_data->Init(32, 4); + + sound::wasapi::Mixer* mixer = sound_wasapi_system_data->mixer; + if (mixer) { + mixer->SetMasterVolume(1.0f); + mixer->SetChannelsVolume(0x03, 1.0f); + mixer->SetChannelsVolume(0x0C, get_min_headphones_volume()); + + size_t se_channels_count = mixer->se_channels_count; + for (size_t i = 0; i < se_channels_count; i++) { + sound::wasapi::SEChannel* se_channel = mixer->GetSEChannel(i); + se_channel->SetChannelsVolume(0x03, get_max_speakers_volume()); + se_channel->SetChannelsVolume(0x0C, 1.0f); + } + + size_t streaming_channels_count = mixer->streaming_channels_count; + for (size_t i = 0; i < streaming_channels_count; i++) { + sound::wasapi::StreamingChannel* streaming_channel = mixer->GetStreamingChannel(i); + streaming_channel->SetChannelsVolume(0x03, get_max_speakers_volume()); + streaming_channel->SetChannelsVolume(0x0C, 1.0f); + } + + SoundCue* sound_cue = sound_work->cues; + for (size_t i = 0; i < se_channels_count + && i < sizeof(sound_work->cues) / sizeof(SoundCue); i++, sound_cue++) { + sound::wasapi::SEChannel* se_channel = mixer->GetSEChannel(i); + if (se_channel) + sound_cue->SetSEChannel(se_channel); + } + } + + //sub_140622E00(); +} + +void sound_ctrl() { + sound::wasapi::System* sound_wasapi_system = sound_wasapi_system_data_get(); + if (sound_wasapi_system) { + sound::wasapi::Mixer* mixer = sound_wasapi_system->mixer; + if (mixer) { + if (sound_work->headphones_volume_changed) + mixer->SetChannelsVolume(0x0C, sound_work_get_headphones_volume()); + + if (sound_work->speakers_volume_changed) { + size_t se_channels_count = mixer->se_channels_count; + for (size_t i = 0; i < se_channels_count; i++) { + sound::wasapi::SEChannel* se_channel = mixer->GetSEChannel(i); + se_channel->SetChannelsVolume(0x03, sound_work_get_speakers_volume()); + } + + size_t streaming_channels_count = mixer->streaming_channels_count; + for (size_t i = 0; i < streaming_channels_count; i++) { + sound::wasapi::StreamingChannel* streaming_channel = mixer->GetStreamingChannel(i); + streaming_channel->SetChannelsVolume(0x03, sound_work_get_speakers_volume()); + } + } + } + } + sound_work->speakers_volume_changed = false; + sound_work->headphones_volume_changed = false; + + for (SoundCue& i : sound_work->cues) { + if (i.CanPlay()) + i.PlayProt(); + else + i.ReleaseProt(true); + } + + //sub_140622AD0(); + + sound_work->names_list.clear(); +} + +void sound_free() { + if (sound_work) { + delete sound_work; + sound_work = 0; + } + + if (sound_wasapi_system_data) { + delete sound_wasapi_system_data; + sound_wasapi_system_data = 0; + } +} + +bool sound_work_cue_can_play(int32_t queue_index, const char* name) { + if (!name) + return false; + + SoundCue* cue = sound_work_get_cue(queue_index, name); + if (cue) + return cue->CanPlay(); + return false; +} + +SoundCue* sound_work_get_cue(int32_t queue_index, const char* name) { + for (SoundCue& i : sound_work->cues) + if ((!i.se_channel || i.property) && i.queue_index == queue_index + && !i.name.compare(name)) + return &i; + return 0; +} + +bool sound_work_get_cue_release(int32_t queue_index, const char* name, bool force_release) { + if (!name) + return false; + + SoundCue* cue = sound_work_get_cue(queue_index, name); + if (cue) { + cue->ReleaseProt(force_release); + return true; + } + return false; +} + +sound_db_farc* sound_work_get_farc(const char* file_path) { + for (sound_db_farc& i : sound_work->farcs) + if (!i.file_path.compare(file_path)) + return &i; + return 0; +} + +float_t sound_work_get_headphones_volume() { + return sound_work->headphones_volume; +} + +float_t sound_work_get_speakers_volume() { + return sound_work->speakers_volume; +} + +bool sound_work_has_property(const char* name) { + return !!sound_work->FindProperty(name); +} + +bool sound_work_load_farc(const char* file_path) { + if (!file_path) + return false; + + sound_db_farc* snd_db_farc = sound_work_get_farc(file_path); + if (snd_db_farc) + return snd_db_farc->load(); + return false; +} + +int32_t sound_work_play_se(int32_t queue_index, const char* name, float_t volume) { + if (!str_utils_compare(name, "sys_kettei_aif")) + name = "sys_kettei.aif"; + + bool found = false; + for (std::string& i : sound_work->names_list) + if (!i.compare(name)) { + found = true; + break; + } + + if (found || queue_index < 0 || queue_index >= SOUND_WORK_SE_QUEUE_COUNT || !sound_work->se_queue_enable[queue_index]) + return 0; + + SoundCue* cue = 0; + for (SoundCue& i : sound_work->cues) + if (i.se_channel && !i.property) { + cue = &i; + break; + } + + if (!cue) { + int32_t min_counter = sound_work->counter; + for (SoundCue& i : sound_work->cues) + if (!i.name.compare(name) && min_counter > i.counter) { + cue = &i; + min_counter = i.counter; + } + + if (!cue) { + int32_t min_counter = sound_work->counter; + for (SoundCue& i : sound_work->cues) + if (min_counter > i.counter) { + cue = &i; + min_counter = i.counter; + } + + if (!cue) + return 0; + } + + cue->ReleaseProt(true); + } + + float_t cue_volume = volume * sound_work->se_queue_volume[queue_index]; + if (queue_index < 3 || queue_index > 4) + cue_volume *= sound_work->se_volume; + + int32_t counter = cue->Load(queue_index, name, cue_volume); + if (counter) + sound_work->names_list.push_back(name); + return counter; +} + +bool sound_work_read_farc(const char* file_path) { + if (!file_path || sound_work_get_farc(file_path)) + return false; + + sound_db_farc* snd_db_farc = 0; + for (sound_db_farc& i : sound_work->farcs) + if (!i.file_path.size()) { + snd_db_farc = &i; + break; + } + + if (snd_db_farc) + return snd_db_farc->read(file_path); + return false; +} + +void sound_work_release_farc_se(const char* file_path) { + if (!file_path) + return; + + for (SoundCue& i : sound_work->cues) { + if (i.se_channel && !i.property || i.property->farc) + continue; + + sound_db_farc* snd_db_farc = i.property->farc; + if (!snd_db_farc) + continue; + + if (!snd_db_farc->farc.file_path.compare(file_path)) + i.ReleaseProt(true); + } +} + +bool sound_work_release_se(const char* name, bool release) { + if (!name) + return false; + + bool found = false; + for (SoundCue& i : sound_work->cues) + if ((!i.se_channel || i.property) && !i.name.compare(name)) { + i.ReleaseProt(release); + found = true; + } + return found; +} + +float_t sound_cue_queue_volume_array_get_max(int32_t queue_index) { + if (queue_index >= 0 && queue_index < SOUND_WORK_SE_QUEUE_COUNT) + return sound_cue_queue_volume_array[queue_index].max; + return 1.0f; +} + +float_t sound_cue_queue_volume_array_get_min(int32_t queue_index) { + if (queue_index >= 0 && queue_index < SOUND_WORK_SE_QUEUE_COUNT) + return sound_cue_queue_volume_array[queue_index].min; + return 0.0f; +} + +sound::wasapi::System* sound_wasapi_system_data_get() { + return sound_wasapi_system_data; +} + +void sound_work_set_headphones_volume(float_t value) { + float_t min = get_min_headphones_volume(); + float_t max = get_max_headphones_volume(); + value = clamp_def(value, min, max); + if (fabsf(sound_work->headphones_volume - value) > 0.000001f) { + sound_work->headphones_volume = value; + sound_work->headphones_volume_changed = true; + } +} + +void sound_work_set_se_queue_volume(int32_t queue_index, float_t value) { + if (queue_index < 0 || queue_index >= SOUND_WORK_SE_QUEUE_COUNT) + return; + + const SoundCueQueueVolume& vol = sound_cue_queue_volume_array[queue_index]; + sound_work->se_queue_volume[queue_index] = clamp_def(value, vol.min, vol.max); +} + +void sound_work_set_speakers_volume(float_t value) { + float_t min = get_min_speakers_volume(); + float_t max = get_max_speakers_volume(); + value = clamp_def(value, min, max); + if (fabsf(sound_work->speakers_volume - value) > 0.000001f) { + sound_work->speakers_volume = value; + sound_work->speakers_volume_changed = true; + } +} + +bool sound_work_unload_farc(const char* file_path) { + if (!file_path) + return false; + + sound_db_farc* snd_db_farc = sound_work_get_farc(file_path); + if (snd_db_farc) + return snd_db_farc->unload(); + return false; +} + +void wave_audio_storage_init() { + wave_audio_storage = {}; +} + +void wave_audio_storage_clear() { + wave_audio_storage.clear(); +} + +WaveAudio* wave_audio_storage_get_wave_audio(std::string& name) { + auto elem = wave_audio_storage.find(name); + if (elem != wave_audio_storage.end()) + return &elem->second; + return 0; +} + +bool wave_audio_storage_load_wave_audio(std::string& name) { + wave_audio_storage_unload_wave_audio(name); + + sound_db_property* property = sound_work->FindProperty(name.c_str()); + if (!property) + return false; + + WaveAudio wave_audio; + if (wave_audio.Read(property->farc, property->file_name.c_str())) { + wave_audio_storage.insert({ name, wave_audio }); + return true; + } + return false; +} + +void wave_audio_storage_unload_wave_audio(std::string& name) { + auto elem = wave_audio_storage.find(name); + if (elem != wave_audio_storage.end()) { + elem->second.Reset(); + wave_audio_storage.erase(elem); + } +} + +void wave_audio_storage_free() { + wave_audio_storage.clear(); +} + +static size_t ima_decode(int16_t* dst, size_t dst_size, uint8_t* data, size_t samples_count, + size_t channels, ima_storage* storage, size_t storage_size) { + if (!dst || !dst_size || !data || !samples_count || !storage || channels > storage_size) + return 0; + + bool odd_sample = false; + size_t act_samp_count = 0; + for (size_t i = min_def(samples_count, dst_size / sizeof(int16_t)); i; i--, act_samp_count++) { + for (size_t j = channels, k = 0; j; j--, k++, odd_sample ^= true) { + ima_storage& _storage = storage[k]; + int16_t step = ima_step_table[_storage.step_index]; + + uint8_t nibble = (odd_sample ? *data : (*data >> 4)) & 0x0F; + + int32_t diff = step >> 3; + if (nibble & 0x01) + diff += step >> 2; + if (nibble & 0x02) + diff += step >> 1; + if (nibble & 0x04) + diff += step; + if (nibble & 0x08) + diff = -diff; + + int32_t current = _storage.current + diff; + current = clamp_def(current, -0x8000, 0x7FFF); + _storage.current = current; + + int32_t step_index = _storage.step_index + ima_index_table[nibble]; + _storage.step_index = clamp_def(step_index, 0, 88); + + *dst++ = current; + + if (odd_sample) + data++; + } + } + return act_samp_count; +} \ No newline at end of file diff --git a/src/CRE/sound.hpp b/src/CRE/sound.hpp new file mode 100644 index 00000000..d46d4e30 --- /dev/null +++ b/src/CRE/sound.hpp @@ -0,0 +1,352 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/farc.hpp" +#include "file_handler.hpp" +#include "lock.hpp" +#include "time.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct sound_buffer_data { + float_t spk_l; + float_t spk_r; + float_t hph_l; + float_t hph_r; +}; + +namespace sound { + namespace wasapi { + enum AudioFormat { + AUDIO_FORMAT_I16 = 0, + AUDIO_FORMAT_I24, + AUDIO_FORMAT_I32, + AUDIO_FORMAT_F32, + }; + + struct Mixer; + struct SEChannel; + struct StreamingChannel; + + struct System { + WAVEFORMATEXTENSIBLE wave_format; + IMMDeviceEnumerator* pEnumerator; + IMMDevice* pDevice; + IAudioClient* pAudioClient; + uint32_t samples_count; + IAudioRenderClient* pRenderClient; + IAudioClockAdjustment* pClockAdjustment; + HANDLE hEvent; + int32_t channels; + int32_t sample_rate; + int32_t bit_depth; + Mixer* mixer; + std::thread* thread; + lock_uint32_t thread_state; + AudioFormat format; + + System(); + virtual ~System(); + + void Init(size_t se_channels_count, size_t streaming_channels_count, + bool separate_speakers_headphones = false); + void Reset(); + + static void ThreadMain(System* system); + }; + + struct Mixer { + System* system; + SEChannel* se_channels; + size_t se_channels_count; + StreamingChannel* streaming_channels; + size_t streaming_channels_count; + sound_buffer_data* mix_buffer; + size_t mix_buffer_size; + std::mutex volume_mtx; + float_t master_volume; + float_t channels_volume[4]; + + Mixer(System* system); + virtual ~Mixer(); + + void FillBuffer(void* buffer, size_t samples_count, + bool disable_headphones_volume, bool invert_phase, AudioFormat format); + SEChannel* GetSEChannel(size_t channel); + StreamingChannel* GetStreamingChannel(size_t channel); + bool Init(size_t se_channels_count, size_t streaming_channels_count, size_t samples_count); + void Reset(); + void SetChannelsVolume(int32_t mask, float_t value); + void SetMasterVolume(float_t value); + }; + + struct SEChannel { + Mixer* mixer; + lock_uint32_t play_state; + std::mutex mtx; + float_t master_volume; + float_t channels_volume[4]; + float_t* buffer; + size_t buffer_size; + size_t channels; + size_t samples_count; + size_t sample_rate; + size_t loop_start; + size_t loop_end; + size_t current_sample; + + SEChannel(); + virtual ~SEChannel(); + + void FillBuffer(sound_buffer_data* buffer, size_t samples_count, float_t volume); + bool Init(Mixer* mixer); + float_t* InitBuffer(size_t channels, size_t samples_count, size_t sample_rate); + bool Play(size_t loop_start = 0, size_t loop_end = 0); + void Reset(); + void ResetData(); + void ResetDataProt(); + void SetChannelsVolume(int32_t mask, float_t value); + void SetMasterVolume(float_t value); + }; + + struct StreamingChannel { + Mixer* mixer; + sound_buffer_data* buffer; + size_t buffer_size; + lock_uint32_t playing_state; + lock_uint32_t reset_state; + std::mutex mtx; + float_t master_volume; + float_t channels_volume[4]; + void(*callback_func)(sound_buffer_data* buffer, size_t samples_count, void* data); + void* callback_data; + + StreamingChannel(); + virtual ~StreamingChannel(); + + void FillBuffer(sound_buffer_data* buffer, size_t samples_count, float_t volume); + bool Init(Mixer* mixer, size_t samples_count); + void Reset(); + void ResetData(); + bool SetCallback(void(*func)(sound_buffer_data* buffer, + size_t samples_count, void* data), void* data); + void SetChannelsVolume(int32_t mask, float_t value); + void SetMasterVolume(float_t value); + }; + } +} + +enum SoundCueDataState { + SOUND_CUE_DATA_STATE_NONE = 0, + SOUND_CUE_DATA_STATE_LOAD, + SOUND_CUE_DATA_STATE_RESET, + SOUND_CUE_DATA_STATE_MAX, +}; + +enum WaveAudioDataFormat { + WAVE_AUDIO_DATA_FORMAT_NONE = 0, + WAVE_AUDIO_DATA_FORMAT_RIFF = 1, + WAVE_AUDIO_DATA_FORMAT_DIVA = 3, +}; + +struct sound_db_farc { + std::string file_path; + bool loaded; + p_file_handler file_handler; + farc farc; + + sound_db_farc(); + ~sound_db_farc(); + + bool load(); + bool read(const char* file_path); + bool unload(); +}; + +struct sound_db_property { + sound_db_farc* farc; + std::string file_name; + float_t volume; + size_t loop_start; + size_t loop_end; + float_t release_time; + //std::string field_28; + //int32_t field_48; + + sound_db_property(); + ~sound_db_property(); +}; + +struct SoundCue; + +struct SoundCueVolume { + SoundCue* cue; + float_t value; + bool set; + + inline SoundCueVolume(SoundCue* cue) : cue(cue), value(), set() { + + } + + inline void SetValue(float_t value) { + this->value = value; + set = true; + } +}; + +struct SoundCue { + lock_uint32_t thread_state; + lock_uint32_t data_state; + std::thread* thread; + std::mutex mtx; + std::condition_variable cnd; + SoundCueVolume* volume; + int32_t queue_index; + std::string name; + sound_db_property* property; + int32_t counter; + float_t release_time; + time_struct time; + lock_uint32_t load_state; + sound::wasapi::SEChannel* se_channel; + + SoundCue(); + ~SoundCue(); + + bool CanPlay(); + void Ctrl(); + int32_t Load(int32_t queue_index, const char* name, float_t volume); + void LoadData(); + void Play(); + void PlayProt(); + void Release(bool force_release); + void ReleaseProt(bool force_release); + void Reset(); + void ResetData(); + void SetSEChannel(sound::wasapi::SEChannel* se_channel); + + static void ThreadMain(SoundCue* cue); +}; + +struct WaveAudioDataFileMemoryStream { + FILE* file; + const void* data; + size_t size; + size_t position; + + inline WaveAudioDataFileMemoryStream(const void* data, size_t size) : file(), + data(data), size(size), position() { + + } +}; + +struct WaveAudioData { + WaveAudioDataFormat format; + size_t channels; + size_t sample_rate; + size_t bit_depth; + size_t samples_count; + size_t position; + size_t data_size; + bool has_loop; + size_t loop_start; + size_t loop_end; + + WaveAudioData(); + ~WaveAudioData(); + + bool Read(WaveAudioDataFileMemoryStream* fms); + bool ReadData(const void* data, size_t size); + bool ReadDiva(WaveAudioDataFileMemoryStream* fms); + void Reset(); +}; + +struct WaveAudio { + float_t* buffer; + size_t buffer_size; + WaveAudioData data; + + WaveAudio(); + + bool Read(sound_db_farc* farc, const char* file_name); + void Reset(); +}; + +#define SOUND_WORK_SE_QUEUE_COUNT 5 +#define SOUND_WORK_STREAMING_COUNT 3 + +struct SoundWork { + std::map properties; + sound_db_farc farcs[16]; + SoundCue cues[32]; + int32_t counter; + std::vector names_list; + bool se_queue_enable[SOUND_WORK_SE_QUEUE_COUNT]; + bool streaming_enable[SOUND_WORK_STREAMING_COUNT]; + float_t speakers_volume; + bool speakers_volume_changed; + float_t headphones_volume; + bool headphones_volume_changed; + float_t se_queue_volume[5]; + float_t se_volume; + + SoundWork(); + virtual ~SoundWork(); + + sound_db_property* FindProperty(const char* name); + bool ParseProperty(sound_db_farc* snd_db_farc); + bool UnloadProperty(const char* file_path); +}; + +extern float_t get_min_headphones_volume(); +extern float_t get_max_headphones_volume(); +extern float_t get_max_speakers_volume(); + +extern float_t db_to_ratio(int32_t value); +extern int32_t ratio_to_db(float_t value); + +extern void sound_init(); +extern void sound_ctrl(); +extern void sound_free(); + +extern float_t sound_cue_queue_volume_array_get_max(int32_t queue_index); +extern float_t sound_cue_queue_volume_array_get_min(int32_t queue_index); + +extern bool sound_work_cue_release(int32_t queue_index, const char* name, bool force_release = true); +extern SoundCue* sound_work_get_cue(int32_t queue_index, const char* name); +extern bool sound_work_get_cue_can_play(int32_t queue_index, const char* name); +extern sound_db_farc* sound_work_get_farc(const char* file_path); +extern float_t sound_work_get_headphones_volume(); +extern float_t sound_work_get_speakers_volume(); +extern bool sound_work_has_property(const char* name); +extern bool sound_work_load_farc(const char* file_path); +extern int32_t sound_work_play_se(int32_t queue_index, const char* name, float_t volume); +extern bool sound_work_read_farc(const char* file_path); +extern void sound_work_release_farc_se(const char* file_path); +extern bool sound_work_release_se(const char* name, bool force_release = true); +extern float_t sound_cue_queue_volume_array_get_max(int32_t queue_index); +extern float_t sound_cue_queue_volume_array_get_min(int32_t queue_index); +extern sound::wasapi::System* sound_wasapi_system_data_get(); +extern void sound_work_set_headphones_volume(float_t value); +extern void sound_work_set_se_queue_volume(int32_t queue_index, float_t value); +extern void sound_work_set_speakers_volume(float_t value); +extern bool sound_work_unload_farc(const char* file_path); + +extern void wave_audio_storage_init(); +extern void wave_audio_storage_clear(); +extern WaveAudio* wave_audio_storage_get_wave_audio(std::string& name); +extern bool wave_audio_storage_load_wave_audio(std::string& name); +extern void wave_audio_storage_unload_wave_audio(std::string& name); +extern void wave_audio_storage_free(); diff --git a/src/CRE/stage.cpp b/src/CRE/stage.cpp index a211e1e9..ef1a3023 100644 --- a/src/CRE/stage.cpp +++ b/src/CRE/stage.cpp @@ -237,7 +237,7 @@ static void stage_detail::TaskStage_CtrlInner(stage_detail::TaskStage* a1) { if (!a1->state) { a1->state = 3; int32_t stage_count = (int32_t)a1->load_stage_indices.size(); - stage_count = min(stage_count, TASK_STAGE_STAGE_COUNT); + stage_count = min_def(stage_count, TASK_STAGE_STAGE_COUNT); for (int32_t i = 0; i < stage_count; i++) if (a1->stages[i].index == -1) stage_set_by_stage_index(&a1->stages[i], a1->load_stage_indices[i], stage_counter++); diff --git a/src/CRE/stage_modern.cpp b/src/CRE/stage_modern.cpp index d5510ac1..1a6680fb 100644 --- a/src/CRE/stage_modern.cpp +++ b/src/CRE/stage_modern.cpp @@ -208,7 +208,7 @@ static void stage_detail::TaskStageModern_CtrlInner(stage_detail::TaskStageModer if (!a1->state) { a1->state = 3; int32_t stage_count = (int32_t)a1->load_stage_hashes.size(); - stage_count = min(stage_count, TASK_STAGE_STAGE_COUNT); + stage_count = min_def(stage_count, TASK_STAGE_STAGE_COUNT); for (int32_t i = 0; i < stage_count; i++) if (a1->stages[i].hash == -1 || a1->stages[i].hash == hash_murmurhash_empty) stage_modern_set_by_stage_hash(&a1->stages[i], @@ -687,11 +687,11 @@ static void stage_modern_set_by_stage_hash(stage_modern* s, int32_t stage_hash, char set_name[11]; set_name[0] = 0; - if (!strncmp(name, "STGPV", min(name_len, 5))) { + if (!strncmp(name, "STGPV", min_def(name_len, 5))) { memcpy(set_name, name, 8); set_name[8] = 0; } - else if (!strncmp(name, "STGD2PV", min(name_len, 7))) { + else if (!strncmp(name, "STGD2PV", min_def(name_len, 7))) { memcpy(set_name, name, 10); set_name[10] = 0; } diff --git a/src/CRE/static_var.cpp b/src/CRE/static_var.cpp index 0209577c..e90ef439 100644 --- a/src/CRE/static_var.cpp +++ b/src/CRE/static_var.cpp @@ -43,7 +43,7 @@ const mat3 sv_ypbpr_to_rgb = { }; void sv_anisotropy_set(int32_t value) { - sv_anisotropy = 1 << (int32_t)roundf(log2f((float_t)clamp(value, 1, sv_max_texture_max_anisotropy))); + sv_anisotropy = 1 << (int32_t)roundf(log2f((float_t)clamp_def(value, 1, sv_max_texture_max_anisotropy))); if (sv_anisotropy != sv_old_anisotropy) sv_anisotropy_changed = true; sv_old_anisotropy = sv_anisotropy; diff --git a/src/CRE/static_var.hpp b/src/CRE/static_var.hpp index 6a0fdf2b..96479da6 100644 --- a/src/CRE/static_var.hpp +++ b/src/CRE/static_var.hpp @@ -22,7 +22,7 @@ enum draw_pass_3d_type { enum uniform_name { U_NONE = 0x00, - U01 = 0x01, + U_ALPHA_MASK = 0x01, U_ALPHA_TEST = 0x02, U_ANISO = 0x03, U_AET_BACK = 0x04, @@ -53,7 +53,7 @@ enum uniform_name { U_MAGNIFY = 0x1D, U_MEMBRANE = 0x1E, U_MLAA = 0x1F, - U20 = 0x20, + U_MLAA_SEARCH = 0x20, U_MORPH_COLOR = 0x21, U_MORPH = 0x22, U_MOVIE = 0x23, @@ -102,7 +102,7 @@ extern int32_t sv_max_texture_max_anisotropy; extern bool sv_anisotropy_changed; extern int32_t sv_anisotropy; -extern int32_t uniform_value[]; +extern int32_t uniform_value[U_MAX]; extern const vec3 sv_rgb_to_luma; extern const mat3 sv_rgb_to_ypbpr; diff --git a/src/CRE/task.cpp b/src/CRE/task.cpp index 8a545f2b..33e74331 100644 --- a/src/CRE/task.cpp +++ b/src/CRE/task.cpp @@ -116,7 +116,7 @@ namespace app { } size_t len = utf8_length(name); - len = min(len, sizeof(this->name) - 1); + len = min_def(len, sizeof(this->name) - 1); memmove(&this->name, name, len); this->name[len] = 0; } @@ -231,7 +231,7 @@ namespace app { for (Task*& i : task_work->tasks) i->SetDest(); } - + void TaskWork::Disp() { task_work->disp = true; for (int32_t i = 0; i < 3; i++) @@ -369,7 +369,7 @@ namespace app { uint32_t frame_counter = get_frame_counter(); if (frame_counter == (frame_counter / 300) * 300) t->calc_time_max = 0; - t->calc_time = max(t->calc_time, t->calc_time_max); + t->calc_time = max_def(t->calc_time, t->calc_time_max); } static void Task_set_disp_time(Task* t, uint32_t disp_time) { @@ -377,7 +377,7 @@ namespace app { uint32_t frame_counter = get_frame_counter(); if (frame_counter == (frame_counter / 300) * 300) t->disp_time_max = 0; - t->disp_time = max(t->disp_time, t->disp_time_max); + t->disp_time = max_def(t->disp_time, t->disp_time_max); } static bool Task_sub_14019B810(Task* t, int32_t a2) { diff --git a/src/CRE/task_effect.cpp b/src/CRE/task_effect.cpp index 1e9b29a4..bcb9da8d 100644 --- a/src/CRE/task_effect.cpp +++ b/src/CRE/task_effect.cpp @@ -300,7 +300,7 @@ void TaskEffectFogAnim::Data::Ctrl() { float_t v4 = field_C[0] * DEG_TO_RAD_FLOAT; float_t v7 = (sinf(v4 - 1.5f) + 1.0f) * 0.5f + field_34.x; - v7 = min(v7, 1.0f) * field_24; + v7 = min_def(v7, 1.0f) * field_24; float_t v8 = sinf(v4) * v7; float_t v9 = cosf(v4); @@ -309,7 +309,7 @@ void TaskEffectFogAnim::Data::Ctrl() { color.y = (float_t)(1.0 - v8 * 0.345686 - ((double_t)v9 * v7) * 0.714486); color.z = (float_t)(v8 * 1.771 + 1.0); color.w = 1.0f; - vec3_max(*(vec3*)&color, vec3_null, *(vec3*)&color); + *(vec3*)&color = vec3::max(*(vec3*)&color, vec3_null); for (int32_t i = 0; i < 3; i++) { float_t v20 = (field_18[i] * 10.0f) + field_C[i]; @@ -321,8 +321,7 @@ void TaskEffectFogAnim::Data::Ctrl() { fog& fog = rctx_ptr->fog[FOG_DEPTH]; fog.set_color(color); - vec3_add_scalar(*(vec3*)&color, 1.0f, *(vec3*)&color); - vec3_mult_scalar(*(vec3*)&color, 0.8f, *(vec3*)&color); + *(vec3*)&color = (*(vec3*)&color + 1.0f) * 0.8f; light_set& light_set = rctx_ptr->light_set[LIGHT_SET_MAIN]; light_set.lights[LIGHT_CHARA].set_diffuse(color); @@ -415,7 +414,7 @@ bool TaskEffectFogRing::Init() { bool TaskEffectFogRing::Ctrl() { data.delta_frame = data.frame_rate_control->GetDeltaFrame(); - data.Ctrl();; + data.Ctrl(); return 0; } diff --git a/src/CRE/task_effect.hpp b/src/CRE/task_effect.hpp index f02a22c3..e0a6827f 100644 --- a/src/CRE/task_effect.hpp +++ b/src/CRE/task_effect.hpp @@ -63,8 +63,6 @@ public: virtual void Field_A8(int32_t a2, int8_t* a3); }; -; - struct struc_621 { int32_t stage_index; std::vector auth_3d_ids; diff --git a/src/CRE/texture.cpp b/src/CRE/texture.cpp index ab1293b9..e7ade2d7 100644 --- a/src/CRE/texture.cpp +++ b/src/CRE/texture.cpp @@ -8,6 +8,15 @@ #include "../KKdLib/txp.hpp" #include "gl_state.hpp" #include "static_var.hpp" +#include +#include + +struct texture_params { + GLenum target; + GLint wrap_s; + GLint wrap_t; + GLint wrap_r; +}; static void texture_get_format_type_by_internal_format(GLenum internal_format, GLenum* format, GLenum* type); static uint32_t texture_get_height_align_mip_level(texture* tex, int32_t mip_level); @@ -21,10 +30,11 @@ static int32_t texture_load(GLenum target, GLenum internal_format, static texture* texture_load_tex(texture_id id, GLenum target, GLenum internal_format, int32_t width, int32_t height, int32_t max_mipmap_level, void** data_ptr, bool use_high_anisotropy); -static void texture_set_params(GLenum target, int32_t max_mipmap_level, bool use_high_anisotropy); +static void texture_set_params(GLuint texture, GLenum target, int32_t max_mipmap_level, bool use_high_anisotropy); static GLenum texture_txp_get_internal_format(txp* t); std::vector texture_storage; +std::map texture_params_storage; texture_id::texture_id() : id(0), index(0) { @@ -86,7 +96,7 @@ void texture_apply_color_tone(texture* chg_tex, } glBindTexture(org_tex->target, 0); glGetError(); - free(data); + free_def(data); } } @@ -119,7 +129,7 @@ texture* texture_copy(texture_id id, texture* org_tex) { org_tex->width, org_tex->height, org_tex->max_mipmap_level, vec_data.data(), true); for (void*& i : vec_data) - free(i); + free_def(i); return tex; } @@ -156,7 +166,7 @@ texture* texture_txp_load(txp* t, texture_id id) { tex = texture_load_tex_cube_map(id, internal_format, width, height, max_mipmap_level, data_ptr); else tex = texture_load_tex_2d(id, internal_format, width, height, max_mipmap_level, data_ptr, true); - free(data_ptr); + free_def(data_ptr); return tex; } @@ -192,6 +202,7 @@ bool texture_txp_set_load(txp_set* t, texture*** texs, texture_id* ids) { inline void texture_storage_init() { texture_storage = {}; + texture_params_storage = {}; } inline texture* texture_storage_create_texture(texture_id id) { @@ -241,6 +252,7 @@ inline void texture_storage_delete_texture(texture_id id) { break; } + texture_params_storage.erase(tex->tex); glDeleteTextures(1, &tex->tex); delete tex; i = texture_storage.erase(i); @@ -248,12 +260,90 @@ inline void texture_storage_delete_texture(texture_id id) { } } +inline void texture_storage_set_texture_wrap(GLuint texture, GLint wrap_s, GLint wrap_t) { + auto elem = texture_params_storage.find(texture); + if (elem == texture_params_storage.end()) + return; + + texture_params& params = elem->second; + if (params.wrap_s != wrap_s) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_S, wrap_s); + params.wrap_s = wrap_s; + } + + if (params.wrap_t != wrap_t) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_T, wrap_t); + params.wrap_t = wrap_t; + } +} + +inline void texture_storage_set_texture_wrap(GLuint texture, GLint wrap_s, GLint wrap_t, GLint wrap_r) { + auto elem = texture_params_storage.find(texture); + if (elem == texture_params_storage.end()) + return; + + texture_params& params = elem->second; + if (params.wrap_s != wrap_s) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_S, wrap_s); + params.wrap_s = wrap_s; + } + + if (params.wrap_t != wrap_t) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_T, wrap_t); + params.wrap_t = wrap_t; + } + + if (params.wrap_r != wrap_r) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_R, wrap_r); + params.wrap_r = wrap_r; + } +} + +inline void texture_storage_set_texture_wrap_s(GLuint texture, GLint wrap) { + auto elem = texture_params_storage.find(texture); + if (elem == texture_params_storage.end()) + return; + + texture_params& params = elem->second; + if (params.wrap_s != wrap) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_S, wrap); + params.wrap_s = wrap; + } +} + +inline void texture_storage_set_texture_wrap_t(GLuint texture, GLint wrap) { + auto elem = texture_params_storage.find(texture); + if (elem == texture_params_storage.end()) + return; + + texture_params& params = elem->second; + if (params.wrap_t != wrap) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_T, wrap); + params.wrap_t = wrap; + } +} + +inline void texture_storage_set_texture_wrap_r(GLuint texture, GLint wrap) { + auto elem = texture_params_storage.find(texture); + if (elem == texture_params_storage.end()) + return; + + texture_params& params = elem->second; + if (params.wrap_r != wrap) { + glTexParameteri(params.target, GL_TEXTURE_WRAP_R, wrap); + params.wrap_r = wrap; + } +} + inline void texture_storage_free() { for (texture*& i : texture_storage) { - if (i) + if (i) { + texture_params_storage.erase(i->tex); glDeleteTextures(1, &i->tex); + } delete i; } + texture_params_storage.clear(); texture_storage.clear(); texture_storage.shrink_to_fit(); } @@ -372,13 +462,13 @@ static void texture_get_format_type_by_internal_format(GLenum internal_format, G inline static uint32_t texture_get_height_align_mip_level(texture* tex, int32_t mip_level) { uint32_t height = tex->height >> mip_level; if (tex->flags & TEXTURE_BLOCK_COMPRESSION) - return max(height, 4); - return max(height, 1); + return max_def(height, 4); + return max_def(height, 1); } inline static uint32_t texture_get_height_mip_level(texture* tex, int32_t mip_level) { uint32_t height = tex->height >> mip_level; - return max(height, 1); + return max_def(height, 1); } static int32_t texture_get_size(GLenum internal_format, int32_t width, int32_t height) { @@ -431,19 +521,19 @@ static int32_t texture_get_size(GLenum internal_format, int32_t width, int32_t h inline static int32_t texture_get_size_mip_level(texture* tex, int32_t mip_level) { int32_t width = tex->width >> mip_level; int32_t height = tex->height >> mip_level; - return texture_get_size(tex->internal_format, max(width, 1), max(height, 1)); + return texture_get_size(tex->internal_format, max_def(width, 1), max_def(height, 1)); } inline static uint32_t texture_get_width_align_mip_level(texture* tex, int32_t mip_level) { uint32_t width = tex->width >> mip_level; if (tex->flags & TEXTURE_BLOCK_COMPRESSION) - return max(width, 4); - return max(width, 1); + return max_def(width, 4); + return max_def(width, 1); } inline static uint32_t texture_get_width_mip_level(texture* tex, int32_t mip_level) { uint32_t width = tex->width >> mip_level; - return max(width, 1); + return max_def(width, 1); } static int32_t texture_load(GLenum target, GLenum internal_format, @@ -478,6 +568,7 @@ static texture* texture_load_tex(texture_id id, GLenum target, return tex; glGenTextures(1, &tex->tex); + texture_params_storage.insert({ tex->tex, { target } }); switch (target) { case GL_TEXTURE_2D: gl_state_bind_texture_2d(tex->tex); @@ -486,7 +577,7 @@ static texture* texture_load_tex(texture_id id, GLenum target, gl_state_bind_texture_cube_map(tex->tex); break; } - texture_set_params(target, max_mipmap_level, use_high_anisotropy); + texture_set_params(tex->tex, target, max_mipmap_level, use_high_anisotropy); GLint swizzle[4]; switch (internal_format) { @@ -534,8 +625,8 @@ static texture* texture_load_tex(texture_id id, GLenum target, if (target == GL_TEXTURE_CUBE_MAP) for (int32_t i = 0; i < 6; i++) for (int32_t j = 0; j <= max_mipmap_level; j++) { - int32_t mip_width = max(width >> j, 1); - int32_t mip_height = max(height >> j, 1); + int32_t mip_width = max_def(width >> j, 1); + int32_t mip_height = max_def(height >> j, 1); void* data; if (data_ptr) data = data_ptr[i * (max_mipmap_level + 1) + j]; @@ -555,8 +646,8 @@ static texture* texture_load_tex(texture_id id, GLenum target, } else for (int32_t i = 0; i <= max_mipmap_level; i++) { - int32_t mip_width = max(width >> i, 1); - int32_t mip_height = max(height >> i, 1); + int32_t mip_width = max_def(width >> i, 1); + int32_t mip_height = max_def(height >> i, 1); void* data; if (data_ptr) data = data_ptr[i]; @@ -611,24 +702,20 @@ fail: return 0; } -static void texture_set_params(GLenum target, int32_t max_mipmap_level, bool use_high_anisotropy) { - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); +static void texture_set_params(GLuint texture, GLenum target, int32_t max_mipmap_level, bool use_high_anisotropy) { + texture_storage_set_texture_wrap(target, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, (float_t*)&vec4_null); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - GLenum min_filter = GL_LINEAR; - if (max_mipmap_level > 0) - min_filter = GL_LINEAR_MIPMAP_LINEAR; - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filter); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, + max_mipmap_level > 0 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, max_mipmap_level); float_t max_anisotropy; if (use_high_anisotropy) - max_anisotropy = 16.0; + max_anisotropy = 16.0f; else - max_anisotropy = 1.0; + max_anisotropy = 1.0f; glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy); } diff --git a/src/CRE/texture.hpp b/src/CRE/texture.hpp index cd1444ea..3d022c81 100644 --- a/src/CRE/texture.hpp +++ b/src/CRE/texture.hpp @@ -5,7 +5,6 @@ #pragma once -#include #include "../KKdLib/default.hpp" #include "../KKdLib/image.hpp" #include "../KKdLib/txp.hpp" @@ -83,4 +82,9 @@ extern texture* texture_storage_get_texture(texture_id id); extern size_t texture_storage_get_texture_count(); extern texture* texture_storage_get_texture_by_index(size_t index); extern void texture_storage_delete_texture(texture_id id); +extern void texture_storage_set_texture_wrap(GLuint texture, GLint wrap_s, GLint wrap_t); +extern void texture_storage_set_texture_wrap(GLuint texture, GLint wrap_s, GLint wrap_t, GLint wrap_r); +extern void texture_storage_set_texture_wrap_s(GLuint texture, GLint wrap); +extern void texture_storage_set_texture_wrap_t(GLuint texture, GLint wrap); +extern void texture_storage_set_texture_wrap_r(GLuint texture, GLint wrap); extern void texture_storage_free(); diff --git a/src/CRE/timer.cpp b/src/CRE/timer.cpp index b3eab31b..bd8bb9c7 100644 --- a/src/CRE/timer.cpp +++ b/src/CRE/timer.cpp @@ -5,109 +5,106 @@ #include "timer.hpp" -timer::timer(double_t freq) : history() { +timer::timer(double_t freq) : history(), curr_time(), prev_time(), inv_freq() { for (double_t& i : history) i = freq; history_counter = 0; this->freq = freq; this->freq_hist = freq; - lock_init(&freq_lock); - lock_init(&freq_hist_lock); - timer_handle = timer_handle_init(); + + LARGE_INTEGER frequency; + if (QueryPerformanceFrequency(&frequency)) + inv_freq = 1000.0 / (double_t)frequency.LowPart; + else + inv_freq = 0.0; + + if (!QueryPerformanceCounter(&curr_time)) + curr_time.QuadPart = 0; + if (!QueryPerformanceCounter(&prev_time)) + prev_time.QuadPart = 0; } timer::~timer() { - lock_free(&freq_lock); - lock_free(&freq_hist_lock); - timer_handle_dispose(timer_handle); + } void timer::start_of_cycle() { - double_t time = prev_time.calc_time(); - prev_time.get_timestamp(); - double_t freq = 0; + LARGE_INTEGER timestamp; + if (!QueryPerformanceCounter(×tamp)) + timestamp.QuadPart = 0; + + double_t time = (timestamp.QuadPart - curr_time.QuadPart) * inv_freq; + + if (!QueryPerformanceCounter(&curr_time)) + curr_time.QuadPart = 0; + + history[history_counter] = time; + + double_t freq = 0.0; for (uint8_t i = 0; i < history_counter; i++) freq += history[i]; - freq += history[history_counter] = 1000.0 / time; + freq += time; for (uint8_t i = history_counter + 1; i < HISTORY_COUNT; i++) freq += history[i]; + history_counter++; if (history_counter >= HISTORY_COUNT) history_counter = 0; - lock_lock(&freq_hist_lock); - freq_hist = freq / HISTORY_COUNT; - lock_unlock(&freq_hist_lock); + + std::unique_lock u_lock(freq_mtx); + freq_hist = 1000.0 / (freq / HISTORY_COUNT); } void timer::end_of_cycle() { - double_t msec = 1000.0 / get_freq() - prev_time.calc_time(); - timer_handle_sleep(timer_handle, msec); + LONGLONG& curr_timestamp = curr_time.QuadPart; + LONGLONG& prev_timestamp = prev_time.QuadPart; + + double_t msec = 1000.0 / get_freq() - (curr_timestamp - prev_timestamp) * inv_freq; + if (floor(msec) > 0) + wait_timer.sleep_float(msec); + + if (msec < -get_freq() / 4.0) + prev_timestamp = curr_timestamp - (LONGLONG)(get_freq() / 4.0 / inv_freq); + else + prev_timestamp = curr_timestamp + (LONGLONG)(msec / inv_freq); } double_t timer::get_freq() { - double_t freq = 0.0; - lock_lock(&freq_lock); - freq = this->freq; - lock_unlock(&freq_lock); + std::unique_lock u_lock(freq_mtx); return freq; } void timer::set_freq(double_t freq) { - lock_lock(&freq_lock); + std::unique_lock u_lock(freq_mtx); this->freq = freq; - lock_unlock(&freq_lock); } double_t timer::get_freq_hist() { - double_t freq = 0.0; - lock_lock(&freq_hist_lock); - freq = freq_hist; - lock_unlock(&freq_hist_lock); - return freq; + std::unique_lock u_lock(freq_hist_mtx); + return freq_hist; } double_t timer::get_freq_ratio() { - double_t freq = 0.0; - lock_lock(&freq_lock); - freq = this->freq; - lock_unlock(&freq_lock); - lock_lock(&freq_hist_lock); - freq /= freq_hist; - lock_unlock(&freq_hist_lock); - return freq; + double_t freq_ratio = 0.0; + { + std::unique_lock u_lock(freq_mtx); + freq_ratio = freq; + } + + { + std::unique_lock u_lock(freq_hist_mtx); + freq_ratio /= freq_hist; + } + return freq_ratio; } void timer::reset() { - curr_time.get_timestamp(); - prev_time.get_timestamp(); + if (!QueryPerformanceCounter(&curr_time)) + curr_time.QuadPart = 0; + if (!QueryPerformanceCounter(&prev_time)) + prev_time.QuadPart = 0; } void timer::sleep(double_t msec) { - timer_handle_sleep(timer_handle, msec); -} - -inline HANDLE timer_handle_init() { - return CreateWaitableTimerW(0, 0, 0); -} - -inline void timer_handle_sleep(HANDLE timer, double_t msec) { - if (msec <= 0.0) - return; - - if (timer) { - LARGE_INTEGER t; - t.QuadPart = (LONGLONG)round(msec * -10000.0); - SetWaitableTimer(timer, &t, 0, 0, 0, 0); - WaitForSingleObject(timer, INFINITE); - } - else { - DWORD msec_dw = (DWORD)round(msec); - if (msec_dw) - Sleep(msec_dw); - } -} - -inline void timer_handle_dispose(HANDLE timer) { - if (timer) - CloseHandle(timer); + wait_timer.sleep_float(msec); } diff --git a/src/CRE/timer.hpp b/src/CRE/timer.hpp index 5255a248..3663f3da 100644 --- a/src/CRE/timer.hpp +++ b/src/CRE/timer.hpp @@ -6,21 +6,22 @@ #pragma once #include "../KKdLib/default.hpp" -#include "lock.hpp" -#include "time.hpp" +#include "waitable_timer.hpp" +#include #define HISTORY_COUNT 0x08 struct timer { double_t history[HISTORY_COUNT]; uint8_t history_counter; - time_struct curr_time; - time_struct prev_time; + LARGE_INTEGER curr_time; + LARGE_INTEGER prev_time; + double_t inv_freq; double_t freq; double_t freq_hist; - lock freq_lock; - lock freq_hist_lock; - HANDLE timer_handle; + std::mutex freq_mtx; + std::mutex freq_hist_mtx; + waitable_timer wait_timer; timer(double_t freq); virtual ~timer(); @@ -34,9 +35,3 @@ struct timer { void reset(); void sleep(double_t msec); }; - -extern LARGE_INTEGER performance_frequency; - -extern HANDLE timer_handle_init(); -extern void timer_handle_sleep(HANDLE timer, double_t msec); -extern void timer_handle_dispose(HANDLE timer); diff --git a/src/CRE/waitable_timer.hpp b/src/CRE/waitable_timer.hpp new file mode 100644 index 00000000..be394cf4 --- /dev/null +++ b/src/CRE/waitable_timer.hpp @@ -0,0 +1,57 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" + +struct waitable_timer { + HANDLE handle; + + inline waitable_timer() { + handle = CreateWaitableTimerW(0, 0, 0); + } + + inline ~waitable_timer() { + if (handle) { + CloseHandle(handle); + handle = 0; + } + } + + inline void sleep(int64_t msec) { + if (msec <= 0.0) + return; + + if (handle) { + LARGE_INTEGER t; + t.QuadPart = (LONGLONG)(msec * -10000); + SetWaitableTimer(handle, &t, 0, 0, 0, 0); + WaitForSingleObject(handle, INFINITE); + } + else { + DWORD msec_dw = (DWORD)msec; + if (msec_dw) + Sleep(msec_dw); + } + } + + inline void sleep_float(double_t msec) { + if (msec <= 0.0) + return; + + if (handle) { + LARGE_INTEGER t; + t.QuadPart = (LONGLONG)round(msec * -10000.0); + SetWaitableTimer(handle, &t, 0, 0, 0, 0); + WaitForSingleObject(handle, INFINITE); + } + else { + DWORD msec_dw = (DWORD)round(msec); + if (msec_dw) + Sleep(msec_dw); + } + } +}; diff --git a/src/DivaGL/DivaGL.vcxproj b/src/DivaGL/DivaGL.vcxproj index 7e8ac966..63847aa7 100644 --- a/src/DivaGL/DivaGL.vcxproj +++ b/src/DivaGL/DivaGL.vcxproj @@ -248,7 +248,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" NotUsing Level3 - MaxSpeed + Full WIN32;DEBUG;%(PreprocessorDefinitions) $(SolutionDir)extern\src true @@ -286,7 +286,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" NotUsing Level3 - MaxSpeed + Full WIN32;DEBUG;DIVAGL_DEV;%(PreprocessorDefinitions) $(SolutionDir)extern\src true @@ -417,7 +417,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" NotSet false ProgramDatabase - OnlyExplicitInline + AnySuitable true FastCall CompileAsCpp @@ -459,7 +459,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" NotSet false ProgramDatabase - OnlyExplicitInline + AnySuitable true FastCall CompileAsCpp diff --git a/src/DivaGL/bone_data.cpp b/src/DivaGL/bone_data.cpp index da50b265..0e7544bc 100644 --- a/src/DivaGL/bone_data.cpp +++ b/src/DivaGL/bone_data.cpp @@ -1193,8 +1193,8 @@ void bone_data_mult_ik(bone_data* a1, int32_t skeleton_select) { v23 = (v28 + v21) / (2.0f * v10); v22 = (v28 - v21) / (2.0f * v20); - v23 = clamp(v23, -1.0f, 1.0f); - v22 = clamp(v22, -1.0f, 1.0f); + v23 = clamp_def(v23, -1.0f, 1.0f); + v22 = clamp_def(v22, -1.0f, 1.0f); v24 = sqrtf(1.0f - v23 * v23); v25 = sqrtf(1.0f - v22 * v22); @@ -2982,7 +2982,7 @@ static void sub_140412BB0(motion_blend_mot* a1, vector_old_bone_data* a2) { } static void sub_1403FBF10(MotionBlend* a1, float_t a2) { - a1->blend = clamp(a2, 0.0f, 1.0f); + a1->blend = clamp_def(a2, 0.0f, 1.0f); a1->field_8 = 1; a1->rot_y = true; } @@ -3690,10 +3690,10 @@ void rob_chara_reset_data(rob_chara* a1, rob_chara_pv_data* a2) { } static void skin_param_hinge_limit(skin_param_hinge* hinge) { - hinge->ymin = max(hinge->ymin, -179.0f) * DEG_TO_RAD_FLOAT; - hinge->ymax = min(hinge->ymax, 179.0f) * DEG_TO_RAD_FLOAT; - hinge->zmin = max(hinge->zmin, -179.0f) * DEG_TO_RAD_FLOAT; - hinge->zmax = min(hinge->zmax, 179.0f) * DEG_TO_RAD_FLOAT; + hinge->ymin = max_def(hinge->ymin, -179.0f) * DEG_TO_RAD_FLOAT; + hinge->ymax = min_def(hinge->ymax, 179.0f) * DEG_TO_RAD_FLOAT; + hinge->zmin = max_def(hinge->zmin, -179.0f) * DEG_TO_RAD_FLOAT; + hinge->zmax = min_def(hinge->zmax, 179.0f) * DEG_TO_RAD_FLOAT; } static void rob_osage_node_data_init(rob_osage_node_data *node_data) { @@ -4505,7 +4505,7 @@ static int32_t sub_140483EA0(vec3* a1, vec3* a2, osage_coli* a3, float_t radius) vec3_dot(v63, a3->bone_pos_diff, v36); v36 *= v25; float_t v37 = v36 * v36; - v37 = min(v37, 1.0f); + v37 = min_def(v37, 1.0f); v22 *= 0.5f; float_t v38 = v22 * v22 - v61; if (v38 < 0.0f) @@ -5075,7 +5075,7 @@ void ExOsageBlock__Field_20(ExOsageBlock* osg) { } void sub_140482DF0(struc_477* dst, struc_477* src0, struc_477* src1, float_t blend) { - dst->length = lerp(src0->length, src1->length, blend); + dst->length = lerp_def(src0->length, src1->length, blend); vec3_lerp_scalar(src0->angle, src1->angle, dst->angle, blend); } @@ -5188,8 +5188,8 @@ void sub_14047E240(rob_osage* rob_osg, mat4* a2, vec3* a3, vector_old_opd_blend_ for (rob_osage_node* i = rob_osg->nodes.begin + 1; i != rob_osg->nodes.end; i++) { float_t v54 = i->field_1B0.field_0.angle.y; float_t v55 = i->field_1B0.field_0.angle.z; - v54 = clamp(v54, (float_t)-M_PI, (float_t)M_PI); - v55 = clamp(v55, (float_t)-M_PI, (float_t)M_PI); + v54 = clamp_def(v54, (float_t)-M_PI, (float_t)M_PI); + v55 = clamp_def(v55, (float_t)-M_PI, (float_t)M_PI); mat4_rotate_z_mult(&v85, v55, &v85); mat4_rotate_y_mult(&v85, v54, &v85); mat4_transpose(&v85, &v85); @@ -5273,7 +5273,7 @@ void ExOsageBlock__Field_50(ExOsageBlock* osg) { rob_osage_coli_set(&osg->rob, osg->mat); sub_14047C770(&osg->rob, parent_node->ex_data_mat, &parent_scale, osg->step, 1); float_t step = 0.5f * osg->step; - osg->step = max(step, 1.0f); + osg->step = max_def(step, 1.0f); } bool sub_14053D1B0(vec3* l_trans, vec3* r_trans, diff --git a/src/DivaGL/inject.cpp b/src/DivaGL/inject.cpp index dca1aa2d..2a8131ce 100644 --- a/src/DivaGL/inject.cpp +++ b/src/DivaGL/inject.cpp @@ -100,7 +100,7 @@ void inject_patches() { for (int32_t i = 0; i < sizeof(patch_data) / sizeof(patch_struct); i++) if (patch_data[i].func_ptr) { - free(patch_data[i].orig_data); + free_def(patch_data[i].orig_data); memcpy(&buf[2], &patch_data[i].func_ptr, sizeof(uint64_t)); patch_data[i].orig_data = inject_data(patch_data[i].address, buf, 12); } @@ -125,7 +125,7 @@ void inject_restore() { for (int32_t i = 0; i < sizeof(patch_data) / sizeof(patch_struct); i++) if (patch_data[i].func_ptr) { void* data = inject_data(patch_data[i].address, patch_data[i].orig_data, 12); - free(data); + free_def(data); } inject_uint64_t((void*)0x0000000140966008, (uint64_t)glutMainLoop); diff --git a/src/DivaGL/shader_table.cpp b/src/DivaGL/shader_table.cpp index b6fc8908..fc8dc64e 100644 --- a/src/DivaGL/shader_table.cpp +++ b/src/DivaGL/shader_table.cpp @@ -197,8 +197,8 @@ int32_t FASTCALL shader_bind(shader* shader, shader_sub_enum name) { int32_t* fp_unival_max = subshader->fp_unival_max; for (size_t i = 0; i < use_unis_count; i++) { int32_t unival = uniform->array[shader->use_uniform[i]]; - unival_vp += unival_vp_curr * min(unival, vp_unival_max[i]); - unival_fp += unival_fp_curr * min(unival, fp_unival_max[i]); + unival_vp += unival_vp_curr * min_def(unival, vp_unival_max[i]); + unival_fp += unival_fp_curr * min_def(unival, fp_unival_max[i]); unival_vp_curr *= vp_unival_max[i] + 1; unival_fp_curr *= fp_unival_max[i] + 1; } diff --git a/src/DivaGL/string.cpp b/src/DivaGL/string.cpp index ab58161f..a5426289 100644 --- a/src/DivaGL/string.cpp +++ b/src/DivaGL/string.cpp @@ -111,7 +111,7 @@ inline void string_copy(string* src, string* dst) { inline void string_copy_wstring(wstring* src, string* dst) { char* temp = utf16_to_utf8(wstring_data(src)); string_init(dst, temp); - free(temp); + free_def(temp); } inline void string_replace(string* src, string* dst) { @@ -123,7 +123,7 @@ inline void string_replace_wstring(wstring* src, string* dst) { char* temp = utf16_to_utf8(wstring_data(src)); string_free(dst); string_init(dst, temp); - free(temp); + free_def(temp); } inline bool string_compare(string* str0, string* str1) { @@ -135,7 +135,7 @@ inline bool string_compare(string* str0, string* str1) { inline void string_free(string* s) { if (s->capacity > STRING_NULL_LENGTH) - free(s->ptr); + free_def(s->ptr); *s = string_empty; } @@ -220,7 +220,7 @@ inline void wstring_copy(wstring* src, wstring* dst) { inline void wstring_copy_string(string* src, wstring* dst) { wchar_t* temp = utf8_to_utf16(string_data(src)); wstring_init(dst, temp); - free(temp); + free_def(temp); } inline void wstring_replace(wstring* src, wstring* dst) { @@ -232,7 +232,7 @@ inline void wstring_replace_string(string* src, wstring* dst) { wchar_t* temp = utf8_to_utf16(string_data(src)); wstring_free(dst); wstring_init(dst, temp); - free(temp); + free_def(temp); } inline bool wstring_compare(wstring* str0, wstring* str1) { @@ -244,7 +244,7 @@ inline bool wstring_compare(wstring* str0, wstring* str1) { inline void wstring_free(wstring* s) { if (s->capacity > WSTRING_NULL_LENGTH) - free(s->ptr); + free_def(s->ptr); *s = wstring_empty; } @@ -257,7 +257,7 @@ static void string_reserve(string* s, ssize_t size) { capacity = (capacity >> 1) + capacity; else capacity = 0; - capacity = max(capacity, s->length + size); + capacity = max_def(capacity, s->length + size); capacity |= STRING_NULL_LENGTH; char* src = string_data(s); @@ -274,7 +274,7 @@ static void string_reserve(string* s, ssize_t size) { s->ptr = dst; if (s->capacity > STRING_NULL_LENGTH) - free(src); + free_def(src); s->capacity = capacity; } @@ -288,7 +288,7 @@ static void wstring_reserve(wstring* s, ssize_t size) { capacity = (capacity >> 1) + capacity; else capacity = 0; - capacity = max(capacity, s->length + size); + capacity = max_def(capacity, s->length + size); capacity |= WSTRING_NULL_LENGTH; wchar_t* src = wstring_data(s); @@ -305,7 +305,7 @@ static void wstring_reserve(wstring* s, ssize_t size) { s->ptr = dst; if (s->capacity > STRING_NULL_LENGTH) - free(src); + free_def(src); s->capacity = capacity; } diff --git a/src/DivaGL/vector.hpp b/src/DivaGL/vector.hpp index f9933c4b..dc980bd3 100644 --- a/src/DivaGL/vector.hpp +++ b/src/DivaGL/vector.hpp @@ -65,7 +65,7 @@ void vector_old_##t##_reserve(vector_old_##t* vec, ssize_t size) { \ capacity = (capacity >> 1) + capacity; \ else \ capacity = 0; \ - capacity = max(capacity, vec->end - vec->begin + size); \ + capacity = max_def(capacity, vec->end - vec->begin + size); \ \ t* temp = 0; \ if (capacity) \ @@ -76,7 +76,7 @@ void vector_old_##t##_reserve(vector_old_##t* vec, ssize_t size) { \ \ memmove(temp, vec->begin, sizeof(t) * (vec->end - vec->begin)); \ ssize_t length = vec->end - vec->begin; \ - free(vec->begin); \ + free_def(vec->begin); \ vec->capacity_end = &temp[capacity]; \ vec->end = &temp[length]; \ vec->begin = temp; \ @@ -182,7 +182,7 @@ void vector_old_##t##_erase_range(vector_old_##t* vec, \ if (!vec || !last || last - first < 1) \ return; \ \ - ssize_t s = min(last - first, (ssize_t)(vec->end - vec->begin)); \ + ssize_t s = min_def(last - first, (ssize_t)(vec->end - vec->begin)); \ if (s < 1) \ return; \ \ @@ -214,7 +214,7 @@ void vector_old_##t##_free(vector_old_##t* vec, vector_old_dispose_func(t)) { \ for (t* i = vec->begin; i != vec->end; i++) \ dispose_func(i); \ \ - free(vec->begin); \ + free_def(vec->begin); \ vec->begin = 0; \ vec->end = 0; \ vec->capacity_end = 0; \ @@ -230,7 +230,7 @@ void vector_old_ptr_##t##_reserve(vector_old_ptr_##t* vec, ssize_t size) { \ capacity = (capacity >> 1) + capacity; \ else \ capacity = 0; \ - capacity = max(capacity, vec->end - vec->begin + size); \ + capacity = max_def(capacity, vec->end - vec->begin + size); \ \ t** temp = 0; \ if (capacity) \ @@ -241,7 +241,7 @@ void vector_old_ptr_##t##_reserve(vector_old_ptr_##t* vec, ssize_t size) { \ \ memmove(temp, vec->begin, sizeof(t*) * (vec->end - vec->begin)); \ ssize_t length = vec->end - vec->begin; \ - free(vec->begin); \ + free_def(vec->begin); \ vec->capacity_end = &temp[capacity]; \ vec->end = &temp[length]; \ vec->begin = temp; \ @@ -290,7 +290,7 @@ void vector_old_ptr_##t##_pop_back(vector_old_ptr_##t* vec, vector_old_dispose_f if (dispose_func) \ dispose_func(vec->end[-1]); \ else \ - free(vec->end[-1]); \ + free_def(vec->end[-1]); \ vec->end--; \ } \ } \ @@ -340,7 +340,7 @@ void vector_old_ptr_##t##_erase(vector_old_ptr_##t* vec, \ if (dispose_func) \ dispose_func(*t0); \ else \ - free(*t0); \ + free_def(*t0); \ \ memmove(t0, t1, sizeof(t*) * (vec->end - t1)); \ vec->end--; \ @@ -351,7 +351,7 @@ void vector_old_ptr_##t##_erase_range(vector_old_ptr_##t* vec, \ if (!vec || !last || last - first < 1) \ return; \ \ - ssize_t s = min(last - first, (ssize_t)(vec->end - vec->begin)); \ + ssize_t s = min_def(last - first, (ssize_t)(vec->end - vec->begin)); \ if (s < 1) \ return; \ \ @@ -366,7 +366,7 @@ void vector_old_ptr_##t##_erase_range(vector_old_ptr_##t* vec, \ } \ else \ for (ssize_t i = 0; i < s; i++) \ - free(t0[i]); \ + free_def(t0[i]); \ \ memmove(t0, t1, sizeof(t*) * (vec->end - t1)); \ vec->end -= s; \ @@ -385,7 +385,7 @@ void vector_old_ptr_##t##_clear(vector_old_ptr_##t* vec, vector_old_dispose_func } \ else \ for (t** i = vec->begin; i != vec->end; i++) \ - free(*i); \ + free_def(*i); \ vec->end = vec->begin; \ } \ \ @@ -402,9 +402,9 @@ void vector_old_ptr_##t##_free(vector_old_ptr_##t* vec, vector_old_dispose_func( } \ else \ for (t** i = vec->begin; i != vec->end; i++) \ - free(*i); \ + free_def(*i); \ \ - free(vec->begin); \ + free_def(vec->begin); \ vec->begin = 0; \ vec->end = 0; \ vec->capacity_end = 0; \ diff --git a/src/KKdLib/a3da.cpp b/src/KKdLib/a3da.cpp index 4b0f4a42..f47fddae 100644 --- a/src/KKdLib/a3da.cpp +++ b/src/KKdLib/a3da.cpp @@ -5,8 +5,9 @@ #include "a3da.hpp" #include "f2/struct.hpp" +#include "io/file_stream.hpp" +#include "io/memory_stream.hpp" #include "io/path.hpp" -#include "io/stream.hpp" #include "half_t.hpp" #include "hash.hpp" #include "key_val.hpp" @@ -104,12 +105,12 @@ void a3da::read(const char* path) { char* path_a3da = str_utils_add(path, (char*)".a3da"); if (path_check_file_exists(path_a3da)) { - stream s; + file_stream s; s.open(path_a3da, "rb"); - if (s.io.stream) + if (s.check_not_null()) a3da_read_inner(this, s); } - free(path_a3da); + free_def(path_a3da); } void a3da::read(const wchar_t* path) { @@ -118,19 +119,19 @@ void a3da::read(const wchar_t* path) { wchar_t* path_a3da = str_utils_add(path, (wchar_t*)L".a3da"); if (path_check_file_exists(path_a3da)) { - stream s; + file_stream s; s.open(path_a3da, L"rb"); - if (s.io.stream) + if (s.check_not_null()) a3da_read_inner(this, s); } - free(path_a3da); + free_def(path_a3da); } void a3da::read(const void* data, size_t size) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); a3da_read_inner(this, s); } @@ -140,11 +141,11 @@ void a3da::write(const char* path) { return; char* path_a3da = str_utils_add(path, ".a3da"); - stream s; + file_stream s; s.open(path_a3da, "wb"); - if (s.io.stream) + if (s.check_not_null()) a3da_write_inner(this, s); - free(path_a3da); + free_def(path_a3da); } void a3da::write(const wchar_t* path) { @@ -152,19 +153,18 @@ void a3da::write(const wchar_t* path) { return; wchar_t* path_a3da = str_utils_add(path, L".a3da"); - stream s; + file_stream s; s.open(path_a3da, L"wb"); - if (s.io.stream) + if (s.check_not_null()) a3da_write_inner(this, s); - free(path_a3da); + free_def(path_a3da); } void a3da::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; - s.open(); + memory_stream s; a3da_write_inner(this, s); s.copy(data, size); } @@ -394,7 +394,7 @@ static void a3da_read_inner(a3da* a, stream& s) { uint32_t signature = s.read_uint32_t(); s.set_position(0x00, SEEK_SET); - stream _s; + memory_stream _s; if (signature == reverse_endianness_int32_t('A3DA')) { f2_struct st; st.read(s); @@ -406,7 +406,7 @@ static void a3da_read_inner(a3da* a, stream& s) { void* data = force_malloc(length); s.read(data, length); _s.open(data, length); - free(data); + free_def(data); } void* a3da_data; @@ -451,7 +451,7 @@ static void a3da_read_inner(a3da* a, stream& s) { _s.read(a3da_data, header.string_length); ((uint8_t*)a3da_data)[header.string_length] = 0; a3da_read_text(a, a3da_data, header.string_length); - free(a3da_data); + free_def(a3da_data); if (signature == reverse_endianness_int32_t('C___')) { a->compressed = true; @@ -459,7 +459,7 @@ static void a3da_read_inner(a3da* a, stream& s) { void* a3dc_data = force_malloc(header.binary_length); _s.read(a3dc_data, header.binary_length); a3da_read_data(a, a3dc_data, header.binary_length); - free(a3dc_data); + free_def(a3dc_data); } a->ready = true; } @@ -479,7 +479,7 @@ static void a3da_write_inner(a3da* a, stream& s) { size_t a3da_data_length = 0; a3da_write_text(a, &a3da_data, &a3da_data_length, a3dc); - stream s_a3da; + memory_stream s_a3da; stream& _s = s; if (a->format > A3DA_FORMAT_AFT) { s_a3da.open(); @@ -515,11 +515,11 @@ static void a3da_write_inner(a3da* a, stream& s) { _s.write(a3da_data, a3da_data_length); _s.align_write(0x20); _s.write(a3dc_data, a3dc_data_length); - free(a3dc_data); + free_def(a3dc_data); } else _s.write(a3da_data, a3da_data_length); - free(a3da_data); + free_def(a3da_data); if (a->format > A3DA_FORMAT_AFT) { f2_struct st; @@ -1115,7 +1115,7 @@ static void a3da_write_text(a3da* a, void** data, size_t* size, bool a3dc) { char a3da_timestamp[0x100]; a3da_get_time_stamp(a3da_timestamp, 0x100); - stream s; + memory_stream s; s.open(); if (a3dc) { @@ -1985,7 +1985,7 @@ static void a3da_read_data(a3da* a, void* data, size_t size) { static void a3da_write_data(a3da* a, void** data, size_t* size) { a3da_compress_f16& _compress_f16 = a->_compress_f16; - stream s; + memory_stream s; s.open(); for (a3da_camera_root& i : a->camera_root) { @@ -2539,10 +2539,10 @@ static bool key_val_read_raw_data(key_val* kv, fs -= c * 4; } break; default: - free(fs); + free_def(fs); return false; } - free(fs); + free_def(fs); value.raw_data = true; return true; diff --git a/src/KKdLib/aes.cpp b/src/KKdLib/aes.cpp index 2096f793..ceec68e6 100644 --- a/src/KKdLib/aes.cpp +++ b/src/KKdLib/aes.cpp @@ -306,12 +306,12 @@ static void key_expansion_aes256(uint8_t* RoundKey, const uint8_t* Key) { inline static __m128i key_expansion_aes128_ni_assist(__m128i temp1, __m128i temp2) { __m128i temp3; - temp2 = _mm_shuffle_epi32(temp2, 0xff); - temp3 = _mm_slli_si128(temp1, 0x4); + temp2 = _mm_shuffle_epi32(temp2, 0xFF); + temp3 = _mm_slli_si128(temp1, 0x04); temp1 = _mm_xor_si128(temp1, temp3); - temp3 = _mm_slli_si128(temp3, 0x4); + temp3 = _mm_slli_si128(temp3, 0x04); temp1 = _mm_xor_si128(temp1, temp3); - temp3 = _mm_slli_si128(temp3, 0x4); + temp3 = _mm_slli_si128(temp3, 0x04); temp1 = _mm_xor_si128(temp1, temp3); temp1 = _mm_xor_si128(temp1, temp2); return temp1; @@ -321,16 +321,16 @@ static void key_expansion_aes128_ni(__m128i* RoundKey, const uint8_t* Key) { __m128i temp1, temp2; temp1 = _mm_loadu_si128((__m128i*)&Key[0]); RoundKey[0] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x1); + temp2 = _mm_aeskeygenassist_si128(temp1, 0x01); temp1 = key_expansion_aes128_ni_assist(temp1, temp2); RoundKey[1] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x2); + temp2 = _mm_aeskeygenassist_si128(temp1, 0x02); temp1 = key_expansion_aes128_ni_assist(temp1, temp2); RoundKey[2] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x4); + temp2 = _mm_aeskeygenassist_si128(temp1, 0x04); temp1 = key_expansion_aes128_ni_assist(temp1, temp2); RoundKey[3] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x8); + temp2 = _mm_aeskeygenassist_si128(temp1, 0x08); temp1 = key_expansion_aes128_ni_assist(temp1, temp2); RoundKey[4] = temp1; temp2 = _mm_aeskeygenassist_si128(temp1, 0x10); @@ -345,7 +345,7 @@ static void key_expansion_aes128_ni(__m128i* RoundKey, const uint8_t* Key) { temp2 = _mm_aeskeygenassist_si128(temp1, 0x80); temp1 = key_expansion_aes128_ni_assist(temp1, temp2); RoundKey[8] = temp1; - temp2 = _mm_aeskeygenassist_si128(temp1, 0x1b); + temp2 = _mm_aeskeygenassist_si128(temp1, 0x1B); temp1 = key_expansion_aes128_ni_assist(temp1, temp2); RoundKey[9] = temp1; temp2 = _mm_aeskeygenassist_si128(temp1, 0x36); @@ -365,15 +365,15 @@ static void key_expansion_aes128_ni(__m128i* RoundKey, const uint8_t* Key) { inline static void key_expansion_aes192_ni_assist(__m128i* temp1, __m128i* temp2, __m128i* temp3) { __m128i temp4; *temp2 = _mm_shuffle_epi32(*temp2, 0x55); - temp4 = _mm_slli_si128(*temp1, 0x4); + temp4 = _mm_slli_si128(*temp1, 0x04); *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x4); + temp4 = _mm_slli_si128(temp4, 0x04); *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x4); + temp4 = _mm_slli_si128(temp4, 0x04); *temp1 = _mm_xor_si128(*temp1, temp4); *temp1 = _mm_xor_si128(*temp1, *temp2); - *temp2 = _mm_shuffle_epi32(*temp1, 0xff); - temp4 = _mm_slli_si128(*temp3, 0x4); + *temp2 = _mm_shuffle_epi32(*temp1, 0xFF); + temp4 = _mm_slli_si128(*temp3, 0x04); *temp3 = _mm_xor_si128(*temp3, temp4); *temp3 = _mm_xor_si128(*temp3, *temp2); } @@ -384,19 +384,19 @@ static void key_expansion_aes192_ni(__m128i* RoundKey, const uint8_t* Key) { temp3 = _mm_loadu_si128((__m128i*)&Key[16]); RoundKey[0] = temp1; RoundKey[1] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x1); + temp2 = _mm_aeskeygenassist_si128(temp3, 0x01); key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); *(__m128d*)& RoundKey[1] = _mm_shuffle_pd(*(__m128d*)&RoundKey[1], *(__m128d*)&temp1, 0); *(__m128d*)& RoundKey[2] = _mm_shuffle_pd(*(__m128d*)&temp1, *(__m128d*)&temp3, 1); - temp2 = _mm_aeskeygenassist_si128(temp3, 0x2); + temp2 = _mm_aeskeygenassist_si128(temp3, 0x02); key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); RoundKey[3] = temp1; RoundKey[4] = temp3; - temp2 = _mm_aeskeygenassist_si128(temp3, 0x4); + temp2 = _mm_aeskeygenassist_si128(temp3, 0x04); key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); *(__m128d*)& RoundKey[4] = _mm_shuffle_pd(*(__m128d*)&RoundKey[4], *(__m128d*)&temp1, 0); *(__m128d*)& RoundKey[5] = _mm_shuffle_pd(*(__m128d*)&temp1, *(__m128d*)&temp3, 1); - temp2 = _mm_aeskeygenassist_si128(temp3, 0x8); + temp2 = _mm_aeskeygenassist_si128(temp3, 0x08); key_expansion_aes192_ni_assist(&temp1, &temp2, &temp3); RoundKey[6] = temp1; RoundKey[7] = temp3; @@ -430,25 +430,25 @@ static void key_expansion_aes192_ni(__m128i* RoundKey, const uint8_t* Key) { inline static void key_expansion_aes256_ni_assist_1(__m128i* temp1, __m128i* temp2) { __m128i temp4; - *temp2 = _mm_shuffle_epi32(*temp2, 0xff); - temp4 = _mm_slli_si128(*temp1, 0x4); + *temp2 = _mm_shuffle_epi32(*temp2, 0xFF); + temp4 = _mm_slli_si128(*temp1, 0x04); *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x4); + temp4 = _mm_slli_si128(temp4, 0x04); *temp1 = _mm_xor_si128(*temp1, temp4); - temp4 = _mm_slli_si128(temp4, 0x4); + temp4 = _mm_slli_si128(temp4, 0x04); *temp1 = _mm_xor_si128(*temp1, temp4); *temp1 = _mm_xor_si128(*temp1, *temp2); } inline static void key_expansion_aes256_ni_assist_2(__m128i* temp1, __m128i* temp3) { __m128i temp2, temp4; - temp4 = _mm_aeskeygenassist_si128(*temp1, 0x0); - temp2 = _mm_shuffle_epi32(temp4, 0xaa); - temp4 = _mm_slli_si128(*temp3, 0x4); + temp4 = _mm_aeskeygenassist_si128(*temp1, 0x00); + temp2 = _mm_shuffle_epi32(temp4, 0xAA); + temp4 = _mm_slli_si128(*temp3, 0x04); *temp3 = _mm_xor_si128(*temp3, temp4); - temp4 = _mm_slli_si128(temp4, 0x4); + temp4 = _mm_slli_si128(temp4, 0x04); *temp3 = _mm_xor_si128(*temp3, temp4); - temp4 = _mm_slli_si128(temp4, 0x4); + temp4 = _mm_slli_si128(temp4, 0x04); *temp3 = _mm_xor_si128(*temp3, temp4); *temp3 = _mm_xor_si128(*temp3, temp2); } @@ -508,42 +508,47 @@ static void key_expansion_aes256_ni(__m128i* RoundKey, const uint8_t* Key) { } void aes128_init_ctx(aes128_ctx* ctx, const uint8_t* key) { - key_expansion_aes128(ctx->RoundKey, key); if (aes_ni) key_expansion_aes128_ni(ctx->RoundKeyNI, key); + else + key_expansion_aes128(ctx->RoundKey, key); } void aes192_init_ctx(aes192_ctx* ctx, const uint8_t* key) { - key_expansion_aes192(ctx->RoundKey, key); if (aes_ni) key_expansion_aes192_ni(ctx->RoundKeyNI, key); + else + key_expansion_aes192(ctx->RoundKey, key); } void aes256_init_ctx(aes256_ctx* ctx, const uint8_t* key) { - key_expansion_aes256(ctx->RoundKey, key); if (aes_ni) key_expansion_aes256_ni(ctx->RoundKeyNI, key); + else + key_expansion_aes256(ctx->RoundKey, key); } -#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) void aes128_init_ctx_iv(aes128_ctx* ctx, const uint8_t* key, const uint8_t* iv) { - key_expansion_aes128(ctx->RoundKey, key); if (aes_ni) key_expansion_aes128_ni(ctx->RoundKeyNI, key); + else + key_expansion_aes128(ctx->RoundKey, key); memcpy(ctx->Iv, iv, AES_BLOCKLEN); } void aes192_init_ctx_iv(aes192_ctx* ctx, const uint8_t* key, const uint8_t* iv) { - key_expansion_aes192(ctx->RoundKey, key); if (aes_ni) key_expansion_aes192_ni(ctx->RoundKeyNI, key); + else + key_expansion_aes192(ctx->RoundKey, key); memcpy(ctx->Iv, iv, AES_BLOCKLEN); } void aes256_init_ctx_iv(aes256_ctx* ctx, const uint8_t* key, const uint8_t* iv) { - key_expansion_aes256(ctx->RoundKey, key); if (aes_ni) key_expansion_aes256_ni(ctx->RoundKeyNI, key); + else + key_expansion_aes256(ctx->RoundKey, key); memcpy(ctx->Iv, iv, AES_BLOCKLEN); } @@ -558,7 +563,6 @@ void aes192_ctx_set_iv(aes192_ctx* ctx, const uint8_t* iv) { void aes256_ctx_set_iv(aes256_ctx* ctx, const uint8_t* iv) { memcpy(ctx->Iv, iv, AES_BLOCKLEN); } -#endif // This function adds the round key to state. // The round key is added to the state by an XOR function. @@ -633,7 +637,6 @@ inline static uint8_t Multiply(uint8_t x, uint8_t y) { (((y >> 3) & 0x01) * xtime(xtime(xtime(x)))); } -#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) // MixColumns function mixes the columns of the state matrix. // The method used to multiply may be difficult to understand for the inexperienced. // Please use the references to gain more information. @@ -688,7 +691,6 @@ inline static void inv_shift_rows(state_t* state) { (*state)[2][3] = (*state)[3][3]; (*state)[3][3] = temp; } -#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) // Cipher is the main function that encrypts the PlainText. inline static void cipher_aes128(state_t* state, const uint8_t* RoundKey) { @@ -814,7 +816,6 @@ inline static void cipher_aes256_ni(void* state, __m128i* round_key) { _mm_storeu_si128((__m128i*)state, m); } -#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) inline static void inv_cipher_aes128(state_t* state, const uint8_t* RoundKey) { uint8_t round = 0; @@ -935,12 +936,9 @@ inline static void inv_cipher_aes256_ni(void* state, __m128i* round_key) { _mm_storeu_si128((__m128i*)state, m); } -#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) - /*****************************************************************************/ /* Public functions: */ /*****************************************************************************/ -#if defined(ECB) && (ECB == 1) void aes128_ecb_encrypt(aes128_ctx* ctx, uint8_t* buf) { // The next function call encrypts the PlainText with the Key using AES algorithm. if (aes_ni) @@ -1042,9 +1040,7 @@ void aes256_ecb_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length) { for (size_t i = 0; i < length; i += AES_BLOCKLEN, buf += AES_BLOCKLEN) inv_cipher_aes256((state_t*)buf, ctx->RoundKey); } -#endif // #if defined(ECB) && (ECB == 1) -#if defined(CBC) && (CBC == 1) inline static void XorWithIv(uint8_t* buf, const uint8_t* Iv) { _mm_storeu_si128((__m128i*)buf, _mm_xor_si128( @@ -1258,9 +1254,6 @@ void aes256_cbc_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length) { } } -#endif // #if defined(CBC) && (CBC == 1) - -#if defined(CTR) && (CTR == 1) /* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */ void aes128_ctr_xcrypt_buffer(aes128_ctx* ctx, uint8_t* buf, uint32_t length) { uint8_t buffer[AES_BLOCKLEN]; @@ -1351,6 +1344,3 @@ void aes256_ctr_xcrypt_buffer(aes256_ctx* ctx, uint8_t* buf, uint32_t length) { buf[i] ^= buffer[bi]; } } - -#endif // #if defined(CTR) && (CTR == 1) - diff --git a/src/KKdLib/aes.hpp b/src/KKdLib/aes.hpp index 3525c01f..1c3e0c85 100644 --- a/src/KKdLib/aes.hpp +++ b/src/KKdLib/aes.hpp @@ -8,26 +8,6 @@ #include "default.hpp" #include -// #define the macros below to 1/0 to enable/disable the mode of operation. -// -// CBC enables AES encryption in CBC-mode of operation. -// CTR enables encryption in counter-mode. -// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously. - -// The #ifndef-guard allows it to be configured before #include'ing or at compile time. -#ifndef CBC - #define CBC 1 -#endif - -#ifndef ECB - #define ECB 1 -#endif - -#ifndef CTR - #define CTR 1 -#endif - - //#define AES128 1 //#define AES192 1 //#define AES256 1 @@ -42,45 +22,41 @@ #define AES256_keyExpSize 240 struct aes128_ctx { - uint8_t RoundKey[AES128_keyExpSize]; - __m128i RoundKeyNI[AES128_keyExpSize / sizeof(__m128i) + 9]; -#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) + union { + uint8_t RoundKey[AES128_keyExpSize]; + __m128i RoundKeyNI[AES128_keyExpSize / sizeof(__m128i) + 9]; + }; uint8_t Iv[AES_BLOCKLEN]; -#endif }; struct aes192_ctx { - uint8_t RoundKey[AES192_keyExpSize]; - __m128i RoundKeyNI[AES192_keyExpSize / sizeof(__m128i) + 11]; -#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) + union { + uint8_t RoundKey[AES192_keyExpSize]; + __m128i RoundKeyNI[AES192_keyExpSize / sizeof(__m128i) + 11]; + }; uint8_t Iv[AES_BLOCKLEN]; -#endif }; struct aes256_ctx { - uint8_t RoundKey[AES256_keyExpSize]; - __m128i RoundKeyNI[AES256_keyExpSize / sizeof(__m128i) + 13]; -#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) + union { + uint8_t RoundKey[AES256_keyExpSize]; + __m128i RoundKeyNI[AES256_keyExpSize / sizeof(__m128i) + 13]; + }; uint8_t Iv[AES_BLOCKLEN]; -#endif }; void aes128_init_ctx(aes128_ctx* ctx, const uint8_t* key); void aes192_init_ctx(aes192_ctx* ctx, const uint8_t* key); void aes256_init_ctx(aes256_ctx* ctx, const uint8_t* key); -#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1)) void aes128_init_ctx_iv(aes128_ctx* ctx, const uint8_t* key, const uint8_t* iv); void aes192_init_ctx_iv(aes192_ctx* ctx, const uint8_t* key, const uint8_t* iv); void aes256_init_ctx_iv(aes256_ctx* ctx, const uint8_t* key, const uint8_t* iv); void aes128_ctx_set_iv(aes128_ctx* ctx, const uint8_t* iv); void aes192_ctx_set_iv(aes192_ctx* ctx, const uint8_t* iv); void aes256_ctx_set_iv(aes256_ctx* ctx, const uint8_t* iv); -#endif -#if defined(ECB) && (ECB == 1) // buffer size is exactly AES_BLOCKLEN bytes; // you need only AES_init_ctx as IV is not used in ECB -// NB: ECB is considered insecure for most uses void aes128_ecb_encrypt(aes128_ctx* ctx, uint8_t* buf); void aes192_ecb_encrypt(aes192_ctx* ctx, uint8_t* buf); void aes256_ecb_encrypt(aes256_ctx* ctx, uint8_t* buf); @@ -94,14 +70,7 @@ void aes128_ecb_decrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length); void aes192_ecb_decrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length); void aes256_ecb_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length); -#endif // #if defined(ECB) && (ECB == !) - -#if defined(CBC) && (CBC == 1) -// buffer size MUST be mutile of AES_BLOCKLEN; -// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme -// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv() -// no IV should ever be reused with the same key void aes128_cbc_encrypt(aes128_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); void aes192_cbc_encrypt(aes192_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); void aes256_cbc_encrypt(aes256_ctx* ctx, uint8_t buf[AES_BLOCKLEN]); @@ -115,20 +84,9 @@ void aes128_cbc_decrypt_buffer(aes128_ctx* ctx, uint8_t* buf, size_t length); void aes192_cbc_decrypt_buffer(aes192_ctx* ctx, uint8_t* buf, size_t length); void aes256_cbc_decrypt_buffer(aes256_ctx* ctx, uint8_t* buf, size_t length); -#endif // #if defined(CBC) && (CBC == 1) - -#if defined(CTR) && (CTR == 1) - -// Same function for encrypting as for decrypting. -// IV is incremented for every block, and used after encryption as XOR-compliment for output -// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme -// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv() -// no IV should ever be reused with the same key void aes128_ctr_xcrypt_buffer(aes128_ctx* ctx, uint8_t* buf, uint32_t length); void aes192_ctr_xcrypt_buffer(aes192_ctx* ctx, uint8_t* buf, uint32_t length); void aes256_ctr_xcrypt_buffer(aes256_ctx* ctx, uint8_t* buf, uint32_t length); -#endif // #if defined(CTR) && (CTR == 1) - #endif // _AES_H_ diff --git a/src/KKdLib/aet.cpp b/src/KKdLib/aet.cpp index 0ea03f9f..e7e599a5 100644 --- a/src/KKdLib/aet.cpp +++ b/src/KKdLib/aet.cpp @@ -4,3 +4,192 @@ */ #include "aet.hpp" +#include "f2/struct.hpp" +#include "io/path.hpp" +#include "io/memory_stream.hpp" + +static void aet_set_classic_read_inner(aet_set* as, stream& s); +static void aet_set_classic_write_inner(aet_set* as, stream& s); +static void aet_set_modern_read_inner(aet_set* as, stream& s); +static void aet_set_modern_write_inner(aet_set* as, stream& s); + +aet_marker::aet_marker() : time() { + +} + +aet_marker::~aet_marker() { + +} + +aet_layer_video_3d::aet_layer_video_3d() { + +} + +aet_layer_video_3d::~aet_layer_video_3d() { + +} + +aet_transfer_mode::aet_transfer_mode() : mode(), flag(), matte() { + +} + +aet_layer_video::aet_layer_video() : _3d_init() { + +} + +aet_layer_video::~aet_layer_video() { + +} + +aet_layer_audio::aet_layer_audio() { + +} + +aet_layer_audio::~aet_layer_audio() { + +} + +aet_color::aet_color() : r(), g(), b() { + +} + +aet_video_src::aet_video_src() : sprite_index() { + +} + +aet_video_src::~aet_video_src() { + +} + +aet_video::aet_video() : width(), height(), fpf() { + +} + +aet_video::~aet_video() { + +} + +aet_audio::aet_audio() : sound_index() { + +} + +aet_layer::aet_layer() : start_time(), end_time(), offset_time(), time_scale(), flags(), +quality(), item_type(), item(), parent(), video(), video_init(), audio(), audio_init() { + +} + +aet_layer::~aet_layer() { + +} + +aet_camera::aet_camera() { + +} + +aet_camera::~aet_camera() { + +} + +aet_scene::aet_scene() : start_time(), end_time(), fps(), width(), height(), camera_init() { + +} + +aet_scene::~aet_scene() { + +} + +aet_set::aet_set() : ready(), modern(), big_endian(), is_x() { + +} + +aet_set::~aet_set() { + +} + +void aet_set::pack_file(void** data, size_t* size) { + if (!data || !ready) + return; + + memory_stream s; + s.open(); + if (!modern) + aet_set_classic_write_inner(this, s); + else + aet_set_modern_write_inner(this, s); + s.align_write(0x10); + s.copy(data, size); +} + +void aet_set::unpack_file(const void* data, size_t size, bool modern) { + if (!data || !size) + return; + + memory_stream s; + s.open(data, size); + if (!modern) + aet_set_classic_read_inner(this, s); + else + aet_set_modern_read_inner(this, s); +} + +static void aet_set_classic_read_inner(aet_set* as, stream& s) { + as->ready = true; + as->modern = false; + as->big_endian = false; + as->is_x = false; +} + +static void aet_set_classic_write_inner(aet_set* as, stream& s) { + +} + +static void aet_set_modern_read_inner(aet_set* as, stream& s) { + f2_struct st; + st.read(s); + if (st.header.signature != reverse_endianness_uint32_t('AETC') || !st.data.size()) + return; + + bool big_endian = st.header.use_big_endian; + + memory_stream s_aetc; + s_aetc.open(st.data); + s_aetc.big_endian = big_endian; + + bool is_x = false; + + as->ready = true; + as->modern = true; + as->big_endian = big_endian; + as->is_x = is_x; +} + +static void aet_set_modern_write_inner(aet_set* as, stream& s) { + bool big_endian = as->big_endian; + bool is_x = as->is_x; + + memory_stream s_aetc; + s_aetc.open(); + s_aetc.big_endian = big_endian; + + uint32_t off; + enrs e; + enrs_entry ee; + pof pof; + + off = align_val(0, 0x10); + + f2_struct st; + s_aetc.align_write(0x10); + s_aetc.copy(st.data); + s_aetc.close(); + + st.enrs = e; + st.pof = pof; + + st.header.signature = reverse_endianness_uint32_t('AETC'); + st.header.length = 0x20; + st.header.use_big_endian = big_endian; + st.header.use_section_size = true; + + st.write(s, true, is_x); +} diff --git a/src/KKdLib/aet.hpp b/src/KKdLib/aet.hpp index 29d6b60a..cb7c3beb 100644 --- a/src/KKdLib/aet.hpp +++ b/src/KKdLib/aet.hpp @@ -11,66 +11,91 @@ #include #include "default.hpp" #include "kf.hpp" -#include "vec.hpp" -enum aet_blend_mode { - AET_BLEND_MODE_NONE = 0, - AET_BLEND_MODE_COPY = 1, - AET_BLEND_MODE_BEHIND = 2, - AET_BLEND_MODE_NORMAL = 3, - AET_BLEND_MODE_DISSOLVE = 4, - AET_BLEND_MODE_ADD = 5, - AET_BLEND_MODE_MULTIPLY = 6, - AET_BLEND_MODE_SCREEN = 7, - AET_BLEND_MODE_OVERLAY = 8, - AET_BLEND_MODE_SOFT_LIGHT = 9, - AET_BLEND_MODE_HARD_LIGHT = 10, - AET_BLEND_MODE_DARKER = 11, - AET_BLEND_MODE_LIGHTEN = 12, - AET_BLEND_MODE_CLASSIC_DIFFERENCE = 13, - AET_BLEND_MODE_HUE = 14, - AET_BLEND_MODE_SATURATION = 15, - AET_BLEND_MODE_COLOR = 16, - AET_BLEND_MODE_LUMINOSITY = 17, - AET_BLEND_MODE_STENCIL_ALPHA = 18, - AET_BLEND_MODE_STENCIL_LUMA = 19, - AET_BLEND_MODE_SILHOUETTE_ALPHA = 20, - AET_BLEND_MODE_SILHOUETTE_LUMA = 21, - AET_BLEND_MODE_LUMINESCENT_PREMULTYPLY = 22, - AET_BLEND_MODE_ALPHA_ADD = 23, - AET_BLEND_MODE_CLASSIC_COLOR_DODGE = 24, - AET_BLEND_MODE_CLASSIC_COLOR_BURN = 25, - AET_BLEND_MODE_EXCLUSION = 26, - AET_BLEND_MODE_DIFFERENCE = 27, - AET_BLEND_MODE_COLOR_DODGE = 28, - AET_BLEND_MODE_COLOR_BURN = 29, - AET_BLEND_MODE_LINEAR_DODGE = 30, - AET_BLEND_MODE_LINEAR_BURN = 31, - AET_BLEND_MODE_LINEAR_LIGHT = 32, - AET_BLEND_MODE_VIVID_LIGHT = 33, - AET_BLEND_MODE_PIN_LIGHT = 34, - AET_BLEND_MODE_HARD_MIX = 35, - AET_BLEND_MODE_LIGHTER_COLOR = 36, - AET_BLEND_MODE_DARKER_COLOR = 37, - AET_BLEND_MODE_SUBTRACT = 38, - AET_BLEND_MODE_DIVIDE = 39, +enum aet_blend_mode : uint8_t { + AET_BLEND_MODE_NONE = 0, // Unsupported + AET_BLEND_MODE_COPY = 1, // Unsupported + AET_BLEND_MODE_BEHIND = 2, // Unsupported + AET_BLEND_MODE_NORMAL = 3, + AET_BLEND_MODE_DISSOLVE = 4, // Unsupported + AET_BLEND_MODE_ADD = 5, + AET_BLEND_MODE_MULTIPLY = 6, + AET_BLEND_MODE_SCREEN = 7, + AET_BLEND_MODE_OVERLAY = 8, // Unsupported + AET_BLEND_MODE_SOFT_LIGHT = 9, // Unsupported + AET_BLEND_MODE_HARD_LIGHT = 10, // Unsupported + AET_BLEND_MODE_DARKER = 11, // Unsupported + AET_BLEND_MODE_LIGHTEN = 12, // Unsupported + AET_BLEND_MODE_CLASSIC_DIFFERENCE = 13, // Unsupported + AET_BLEND_MODE_HUE = 14, // Unsupported + AET_BLEND_MODE_SATURATION = 15, // Unsupported + AET_BLEND_MODE_COLOR = 16, // Unsupported + AET_BLEND_MODE_LUMINOSITY = 17, // Unsupported + AET_BLEND_MODE_STENCIL_ALPHA = 18, // Unsupported + AET_BLEND_MODE_STENCIL_LUMA = 19, // Unsupported + AET_BLEND_MODE_SILHOUETTE_ALPHA = 20, // Unsupported + AET_BLEND_MODE_SILHOUETTE_LUMA = 21, // Unsupported + AET_BLEND_MODE_LUMINESCENT_PREMULTYPLY = 22, // Unsupported + AET_BLEND_MODE_ALPHA_ADD = 23, // Unsupported + AET_BLEND_MODE_CLASSIC_COLOR_DODGE = 24, // Unsupported + AET_BLEND_MODE_CLASSIC_COLOR_BURN = 25, // Unsupported + AET_BLEND_MODE_EXCLUSION = 26, // Unsupported + AET_BLEND_MODE_DIFFERENCE = 27, // Unsupported + AET_BLEND_MODE_COLOR_DODGE = 28, // Unsupported + AET_BLEND_MODE_COLOR_BURN = 29, // Unsupported + AET_BLEND_MODE_LINEAR_DODGE = 30, // Unsupported + AET_BLEND_MODE_LINEAR_BURN = 31, // Unsupported + AET_BLEND_MODE_LINEAR_LIGHT = 32, // Unsupported + AET_BLEND_MODE_VIVID_LIGHT = 33, // Unsupported + AET_BLEND_MODE_PIN_LIGHT = 34, // Unsupported + AET_BLEND_MODE_HARD_MIX = 35, // Unsupported + AET_BLEND_MODE_LIGHTER_COLOR = 36, // Unsupported + AET_BLEND_MODE_DARKER_COLOR = 37, // Unsupported + AET_BLEND_MODE_SUBTRACT = 38, // Unsupported + AET_BLEND_MODE_DIVIDE = 39, // Unsupported }; -enum aet_item_type { +enum aet_item_type : uint8_t { AET_ITEM_TYPE_NONE = 0, AET_ITEM_TYPE_VIDEO = 1, AET_ITEM_TYPE_AUDIO = 2, AET_ITEM_TYPE_COMPOSITION = 3, }; -enum aet_layer_quality { +enum aet_layer_flags : uint16_t { + AET_LAYER_FLAGS_VIDEO_ACTIVE = 0x000001, + AET_LAYER_FLAGS_AUDIO_ACTIVE = 0x000002, + AET_LAYER_FLAGS_EFFECTS_ACTIVE = 0x000004, + AET_LAYER_FLAGS_MOTION_BLUR = 0x000008, + AET_LAYER_FLAGS_FRAME_BLENDING = 0x000010, + AET_LAYER_FLAGS_LOCKED = 0x000020, + AET_LAYER_FLAGS_SHY = 0x000040, + AET_LAYER_FLAGS_COLLAPSE = 0x000080, + AET_LAYER_FLAGS_AUTO_ORIENT_ROTATION = 0x000100, + AET_LAYER_FLAGS_ADJUSTMENT_LAYER = 0x000200, + AET_LAYER_FLAGS_TIME_REMAPPING = 0x000400, + AET_LAYER_FLAGS_LAYER_IS_3D = 0x000800, + AET_LAYER_FLAGS_LOOK_AT_CAMERA = 0x001000, + AET_LAYER_FLAGS_LOOK_AT_POINT_OF_INTEREST = 0x002000, + AET_LAYER_FLAGS_SOLO = 0x004000, + AET_LAYER_FLAGS_MARKERS_LOCKED = 0x008000, + // Should be there but they don't fit in 16 bits + //AET_LAYER_FLAGS_NULL_LAYER = 0x010000, + //AET_LAYER_FLAGS_HIDE_LOCKED_MASKS = 0x020000, + //AET_LAYER_FLAGS_GUIDE_LAYER = 0x040000, + //AET_LAYER_FLAGS_ADVANCED_FRAME_BLENDING = 0x080000, + //AET_LAYER_FLAGS_SUB_LAYERS_RENDER_SEPARATELY = 0x100000, + //AET_LAYER_FLAGS_ENVIRONMENT_LAYER = 0x200000, +}; + +enum aet_layer_quality : uint8_t { AET_LAYER_QUALITY_NONE = 0, AET_LAYER_QUALITY_WIREFRAME = 1, AET_LAYER_QUALITY_DRAFT = 2, AET_LAYER_QUALITY_BEST = 3, }; -enum aet_track_matte { +enum aet_track_matte : uint8_t { AET_TRACK_MATTE_NONE = 0, AET_TRACK_MATTE_ALPHA = 1, AET_TRACK_MATTE_NOT_ALPHA = 2, @@ -78,157 +103,174 @@ enum aet_track_matte { AET_TRACK_MATTE_NOT_LUMA = 4, }; -struct aet_layer_flags { - // Toggles layer visuals on or off - uint16_t video_active : 1; - // Toggles layer sounds on or off - uint16_t audio_active : 1; - uint16_t effects_active : 1; - // Toggles motion blur on or off for the layer - uint16_t motion_blur : 1; - uint16_t frame_blending : 1; - // Locks layer contents, preventing all changes - uint16_t locked : 1; - // Hides the current layer when the "Hide Shy Layers" composition switch is selected - uint16_t shy : 1; - uint16_t collapse : 1; - uint16_t auto_orient_rotation : 1; - // Identifies the layer as an adjustment layer - uint16_t adjustment_layer : 1; - uint16_t time_remapping : 1; - // Identifies the layer as a 3D layer - uint16_t layer_is_3d : 1; - uint16_t look_at_camera : 1; - uint16_t look_at_point_of_interest : 1; - // Includes the current layer in previews and renders, ignoring layers without this switch set - uint16_t solo : 1; - uint16_t markers_locked : 1; -}; - -struct aet_transfer_flags { - uint8_t preserve_alpha : 1; - uint8_t randomize_dissolve : 1; -}; - -struct aet_audio { - uint32_t sound_id; -}; - -struct aet_video_source { - std::string name; - int32_t name_offset; - uint32_t id; -}; - -struct aet_layer_audio { - std::vector volume_left; - std::vector volume_right; - std::vector pan_left; - std::vector pan_right; -}; - -struct aet_layer_transfer_mode { - aet_blend_mode blend_mode; - aet_transfer_flags transfer_flags; - aet_track_matte track_matte; -}; - -struct aet_layer_video_3d { - std::vector anchor_z; - std::vector position_z; - std::vector direction_x; - std::vector direction_y; - std::vector direction_z; - std::vector rotation_x; - std::vector rotation_y; - std::vector scale_z; -}; - -struct aet_layer_video { - aet_layer_transfer_mode transfer_mode; - uint8_t padding; - std::vector anchor_x; - std::vector anchor_y; - std::vector positionx; - std::vector position_y; - std::vector rotation; - std::vector scale_x; - std::vector scale_y; - std::vector opacit_y; - aet_layer_video_3d* video_3d; +enum aet_transfer_flags : uint8_t { + AET_TRANSFRER_FLAGS_PRESERVE_ALPHA = 0x01, + AET_TRANSFRER_FLAGS_RANDOMIZE_DISSOLVE = 0x02, }; struct aet_marker { - float_t frame; + float_t time; std::string name; - int32_t name_offset; + + aet_marker(); + ~aet_marker(); +}; + +typedef std::vector aet_fcurve; + +struct aet_layer_video_3d { + aet_fcurve anchor_z; + aet_fcurve pos_z; + aet_fcurve dir_x; + aet_fcurve dir_y; + aet_fcurve dir_z; + aet_fcurve rot_x; + aet_fcurve rot_y; + aet_fcurve scale_z; + + aet_layer_video_3d(); + ~aet_layer_video_3d(); +}; + +struct aet_transfer_mode { + aet_blend_mode mode; + aet_transfer_flags flag; + aet_track_matte matte; + + aet_transfer_mode(); +}; + +struct aet_layer_video { + aet_transfer_mode transfer_mode; + aet_fcurve anchor_x; + aet_fcurve anchor_y; + aet_fcurve pos_x; + aet_fcurve pos_y; + aet_fcurve rot_z; + aet_fcurve scale_x; + aet_fcurve scale_y; + aet_fcurve opacity; + aet_layer_video_3d _3d; + bool _3d_init; + + aet_layer_video(); + ~aet_layer_video(); +}; + +struct aet_layer_audio { + aet_fcurve volume_l; + aet_fcurve volume_r; + aet_fcurve pan_l; + aet_fcurve pan_r; + + aet_layer_audio(); + ~aet_layer_audio(); +}; + +struct aet_color { + uint8_t r; + uint8_t g; + uint8_t b; + + aet_color(); +}; + +struct aet_video_src { + std::string sprite_name; + int32_t sprite_index; + + aet_video_src(); + ~aet_video_src(); +}; + +struct aet_video { + aet_color color; + uint16_t width; + uint16_t height; + float_t fpf; + std::vector sources; + + aet_video(); + ~aet_video(); +}; + +struct aet_audio { + uint32_t sound_index; + + aet_audio(); }; struct aet_layer { std::string name; - int32_t name_offset; - float_t start_frame; - float_t end_frame; - float_t offset_frame; + float_t start_time; + float_t end_time; + float_t offset_time; float_t time_scale; aet_layer_flags flags; aet_layer_quality quality; - aet_item_type type; - int32_t video_item_offset; - int32_t parent_layer_offset; - std::vector marker; - std::vector video; - std::vector audio; + aet_item_type item_type; + void* item; + aet_layer* parent; + std::vector markers; + aet_layer_video video; + bool video_init; + aet_layer_audio audio; + bool audio_init; - int32_t DataID; + aet_layer(); + ~aet_layer(); }; -struct aet_composition { - int32_t count; - int32_t offset; - aet_layer* elements; -}; - -struct aet_video { - int32_t offset; - uint32_t color; - uint16_t width; - uint16_t height; - float_t frames; - std::vector video_source; -}; +typedef std::vector aet_comp; struct aet_camera { - std::vector eye_x; - std::vector eye_y; - std::vector eye_z; - std::vector position_x; - std::vector position_y; - std::vector position_z; - std::vector direction_x; - std::vector direction_y; - std::vector direction_z; - std::vector rotation_x; - std::vector rotation_y; - std::vector rotation_z; - std::vector zoom; + aet_fcurve eye_x; + aet_fcurve eye_y; + aet_fcurve eye_z; + aet_fcurve pos_x; + aet_fcurve pos_y; + aet_fcurve pos_z; + aet_fcurve dir_x; + aet_fcurve dir_y; + aet_fcurve dir_z; + aet_fcurve rot_x; + aet_fcurve rot_y; + aet_fcurve rot_z; + aet_fcurve zoom; + + aet_camera(); + ~aet_camera(); }; struct aet_scene { std::string name; - int32_t name_offset; - float_t start_frame; - float_t end_frame; - float_t frame_rate; - uint32_t back_color; + float_t start_time; + float_t end_time; + float_t fps; + aet_color color; uint32_t width; uint32_t height; - std::vector camera; - std::vector composition; + aet_camera camera; + bool camera_init; + std::vector comp; std::vector video; std::vector audio; + + aet_scene(); + ~aet_scene(); }; -struct aet_header { - aet_scene scene; +struct aet_set { + bool ready; + bool modern; + bool big_endian; + bool is_x; + + std::vector scenes; + + aet_set(); + virtual ~aet_set(); + + void pack_file(void** data, size_t* size); + void unpack_file(const void* data, size_t size, bool modern); }; diff --git a/src/KKdLib/database/auth_3d.cpp b/src/KKdLib/database/auth_3d.cpp index dc13f387..c1f3fe7b 100644 --- a/src/KKdLib/database/auth_3d.cpp +++ b/src/KKdLib/database/auth_3d.cpp @@ -4,8 +4,9 @@ */ #include "auth_3d.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../key_val.hpp" #include "../hash.hpp" #include "../sort.hpp" @@ -35,12 +36,12 @@ void auth_3d_database_file::read(const char* path) { char* path_bin = str_utils_add(path, ".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, "rb"); - if (s.io.stream) + if (s.check_not_null()) auth_3d_database_file_read_inner(this, s); } - free(path_bin); + free_def(path_bin); } void auth_3d_database_file::read(const wchar_t* path) { @@ -49,19 +50,19 @@ void auth_3d_database_file::read(const wchar_t* path) { wchar_t* path_bin = str_utils_add(path, L".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, L"rb"); - if (s.io.stream) + if (s.check_not_null()) auth_3d_database_file_read_inner(this, s); } - free(path_bin); + free_def(path_bin); } void auth_3d_database_file::read(const void* data, size_t size) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); auth_3d_database_file_read_inner(this, s); } @@ -71,11 +72,11 @@ void auth_3d_database_file::write(const char* path) { return; char* path_bin = str_utils_add(path, ".bin"); - stream s; + file_stream s; s.open(path_bin, "wb"); - if (s.io.stream) + if (s.check_not_null()) auth_3d_database_file_write_inner(this, s); - free(path_bin); + free_def(path_bin); } void auth_3d_database_file::write(const wchar_t* path) { @@ -83,18 +84,18 @@ void auth_3d_database_file::write(const wchar_t* path) { return; wchar_t* path_bin = str_utils_add(path, L".bin"); - stream s; + file_stream s; s.open(path_bin, L"wb"); - if (s.io.stream) + if (s.check_not_null()) auth_3d_database_file_write_inner(this, s); - free(path_bin); + free_def(path_bin); } void auth_3d_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); auth_3d_database_file_write_inner(this, s); s.copy(data, size); @@ -304,7 +305,7 @@ static void auth_3d_database_file_read_inner(auth_3d_database_file* auth_3d_db_f void* a3da_data = force_malloc(string_length); s.read(a3da_data, string_length); auth_3d_database_file_read_text(auth_3d_db_file, a3da_data, string_length); - free(a3da_data); + free_def(a3da_data); auth_3d_db_file->ready = true; } @@ -314,7 +315,7 @@ static void auth_3d_database_file_write_inner(auth_3d_database_file* auth_3d_db_ size_t a3da_data_length = 0; auth_3d_database_file_write_text(auth_3d_db_file, &a3da_data, &a3da_data_length); s.write(a3da_data, a3da_data_length); - free(a3da_data); + free_def(a3da_data); } static void auth_3d_database_file_read_text(auth_3d_database_file* auth_3d_db_file, void* data, size_t size) { @@ -367,7 +368,7 @@ static void auth_3d_database_file_read_text(auth_3d_database_file* auth_3d_db_fi } static void auth_3d_database_file_write_text(auth_3d_database_file* auth_3d_db_file, void** data, size_t* size) { - stream s; + memory_stream s; s.open(); s.write("#A3DA__________\n", 16); diff --git a/src/KKdLib/database/bone.cpp b/src/KKdLib/database/bone.cpp index 944ee7ca..48f82b8d 100644 --- a/src/KKdLib/database/bone.cpp +++ b/src/KKdLib/database/bone.cpp @@ -5,8 +5,9 @@ #include "bone.hpp" #include "../f2/struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../hash.hpp" #include "../str_utils.hpp" @@ -28,7 +29,7 @@ static int64_t bone_database_strings_get_string_offset(std::vector& std::vector& vec_off, const char* str); static bool bone_database_strings_push_back_check(std::vector& vec, const char* str); -bone_database::bone_database() : ready(), modern(), is_x() { +bone_database::bone_database() : ready(), modern(), big_endian(), is_x() { } @@ -43,18 +44,18 @@ void bone_database::read(const char* path, bool modern) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, "rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); bone_database_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { char* path_bon = str_utils_add(path, ".bon"); @@ -62,13 +63,13 @@ void bone_database::read(const char* path, bool modern) { f2_struct st; st.read(path_bon); if (st.header.signature == reverse_endianness_uint32_t('BONE')) { - stream s_bone; + memory_stream s_bone; s_bone.open(st.data); - s_bone.is_big_endian = st.header.use_big_endian; + s_bone.big_endian = st.header.use_big_endian; bone_database_modern_read_inner(this, s_bone, st.header.length); } } - free(path_bon); + free_def(path_bon); } } @@ -79,18 +80,18 @@ void bone_database::read(const wchar_t* path, bool modern) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, L"rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); bone_database_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { wchar_t* path_bon = str_utils_add(path, L".bon"); @@ -98,13 +99,13 @@ void bone_database::read(const wchar_t* path, bool modern) { f2_struct st; st.read(path_bon); if (st.header.signature == reverse_endianness_uint32_t('BONE')) { - stream s_bone; + memory_stream s_bone; s_bone.open(st.data); - s_bone.is_big_endian = st.header.use_big_endian; + s_bone.big_endian = st.header.use_big_endian; bone_database_modern_read_inner(this, s_bone, st.header.length); } } - free(path_bon); + free_def(path_bon); } } @@ -113,7 +114,7 @@ void bone_database::read(const void* data, size_t size, bool modern) { return; if (!modern) { - stream s; + memory_stream s; s.open(data, size); bone_database_classic_read_inner(this, s); } @@ -121,9 +122,9 @@ void bone_database::read(const void* data, size_t size, bool modern) { f2_struct st; st.read(data, size); if (st.header.signature == reverse_endianness_uint32_t('BONE')) { - stream s_bone; + memory_stream s_bone; s_bone.open(st.data); - s_bone.is_big_endian = st.header.use_big_endian; + s_bone.big_endian = st.header.use_big_endian; bone_database_modern_read_inner(this, s_bone, st.header.length); } } @@ -135,19 +136,19 @@ void bone_database::write(const char* path) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); - stream s; + file_stream s; s.open(path_bin, "wb"); - if (s.io.stream) + if (s.check_not_null()) bone_database_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { char* path_bon = str_utils_add(path, ".bon"); - stream s; + file_stream s; s.open(path_bon, "wb"); - if (s.io.stream) + if (s.check_not_null()) bone_database_modern_write_inner(this, s); - free(path_bon); + free_def(path_bon); } } @@ -157,19 +158,19 @@ void bone_database::write(const wchar_t* path) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); - stream s; + file_stream s; s.open(path_bin, L"wb"); - if (s.io.stream) + if (s.check_not_null()) bone_database_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { wchar_t* path_bon = str_utils_add(path, L".bon"); - stream s; + file_stream s; s.open(path_bon, L"wb"); - if (s.io.stream) + if (s.check_not_null()) bone_database_modern_write_inner(this, s); - free(path_bon); + free_def(path_bon); } } @@ -177,7 +178,7 @@ void bone_database::write(void** data, size_t* size) { if (!data || !ready) return; - stream s; + memory_stream s; s.open(); if (!modern) bone_database_classic_write_inner(this, s); @@ -569,9 +570,10 @@ static void bone_database_classic_read_inner(bone_database* bone_data, stream& s bone_data->skeleton[i].name = s.read_string_null_terminated_offset(s.read_uint32_t()); s.position_pop(); - bone_data->is_x = false; - bone_data->modern = false; bone_data->ready = true; + bone_data->modern = false; + bone_data->big_endian = false; + bone_data->is_x = false; } static void bone_database_classic_write_inner(bone_database* bone_data, stream& s) { @@ -707,7 +709,7 @@ static void bone_database_classic_write_inner(bone_database* bone_data, stream& for (uint32_t i = 0; i < skeleton_count; i++) s.write_uint32_t((uint32_t)skeleton_offsets[i]); s.position_pop(); - free(skeleton_offsets); + free_def(skeleton_offsets); } static void bone_database_modern_read_inner(bone_database* bone_data, stream& s, uint32_t header_length) { @@ -715,6 +717,7 @@ static void bone_database_modern_read_inner(bone_database* bone_data, stream& s, if (signature != 0x09102720) return; + bool big_endian = s.big_endian; bool is_x = true; s.set_position(0x0C, SEEK_SET); @@ -870,7 +873,7 @@ static void bone_database_modern_read_inner(bone_database* bone_data, stream& s, s.position_push(parent_indices_offset, SEEK_SET); s.read(skel->parent_index.data(), motion_bone_count * sizeof(uint16_t)); - if (s.is_big_endian) { + if (big_endian) { uint16_t* parent_index = skel->parent_index.data(); for (uint32_t j = 0; j < motion_bone_count; j++) parent_index[j] = reverse_endianness_uint16_t(parent_index[j]); @@ -891,21 +894,25 @@ static void bone_database_modern_read_inner(bone_database* bone_data, stream& s, s.read_offset_x()); s.position_pop(); - bone_data->is_x = is_x; - bone_data->modern = true; bone_data->ready = true; + bone_data->modern = true; + bone_data->big_endian = big_endian; + bone_data->is_x = is_x; } static void bone_database_modern_write_inner(bone_database* bone_data, stream& s) { - stream s_bone; + bool big_endian = bone_data->big_endian; + bool is_x = bone_data->is_x; + + memory_stream s_bone; s_bone.open(); + s_bone.big_endian = big_endian; + uint32_t off; enrs e; enrs_entry ee; pof pof; - bool is_x = bone_data->is_x; - uint32_t skeleton_count = (uint32_t)bone_data->skeleton.size(); if (!is_x) { @@ -1280,24 +1287,24 @@ static void bone_database_modern_write_inner(bone_database* bone_data, stream& s s_bone.position_push(skh[i].offset, SEEK_SET); if (!is_x) { s_bone.write_offset_f2(skh[i].bones_offset, 0x40); - s_bone.write_uint32_t(position_count); + s_bone.write_uint32_t_reverse_endianness(position_count); s_bone.write_offset_f2(skh[i].positions_offset, 0x40); s_bone.write_offset_f2(skh[i].unknown_value_offset, 0x40); - s_bone.write_uint32_t(object_bone_count); + s_bone.write_uint32_t_reverse_endianness(object_bone_count); s_bone.write_offset_f2(skh[i].object_bone_names_offset, 0x40); - s_bone.write_uint32_t(motion_bone_count); + s_bone.write_uint32_t_reverse_endianness(motion_bone_count); s_bone.write_offset_f2(skh[i].motion_bone_names_offset, 0x40); s_bone.write_offset_f2(skh[i].parent_indices_offset, 0x40); s_bone.write(0x14); } else { s_bone.write_offset_x(skh[i].bones_offset); - s_bone.write_uint32_t(position_count); + s_bone.write_uint32_t_reverse_endianness(position_count); s_bone.write_offset_x(skh[i].positions_offset); s_bone.write_offset_x(skh[i].unknown_value_offset); - s_bone.write_uint32_t(object_bone_count); + s_bone.write_uint32_t_reverse_endianness(object_bone_count); s_bone.write_offset_x(skh[i].object_bone_names_offset); - s_bone.write_uint32_t(motion_bone_count); + s_bone.write_uint32_t_reverse_endianness(motion_bone_count); s_bone.write_offset_x(skh[i].motion_bone_names_offset); s_bone.write_offset_x(skh[i].parent_indices_offset); s_bone.write(0x28); @@ -1345,11 +1352,15 @@ static void bone_database_modern_write_inner(bone_database* bone_data, stream& s s_bone.position_pop(); s_bone.position_push(skh[i].positions_offset, SEEK_SET); - s_bone.write(skel->position.data(), sizeof(vec3)* position_count); + for (vec3& j : skel->position) { + s_bone.write_float_t_reverse_endianness(j.x); + s_bone.write_float_t_reverse_endianness(j.y); + s_bone.write_float_t_reverse_endianness(j.z); + } s_bone.position_pop(); s_bone.position_push(skh[i].unknown_value_offset, SEEK_SET); - s_bone.write_float_t(skel->heel_height); + s_bone.write_float_t_reverse_endianness(skel->heel_height); s_bone.position_pop(); s_bone.position_push(skh[i].object_bone_names_offset, SEEK_SET); @@ -1374,13 +1385,14 @@ static void bone_database_modern_write_inner(bone_database* bone_data, stream& s s_bone.position_pop(); s_bone.position_push(skh[i].parent_indices_offset, SEEK_SET); - s_bone.write(skel->parent_index.data(), sizeof(uint16_t) * motion_bone_count); + for (uint16_t& j : skel->parent_index) + s_bone.write_uint16_t_reverse_endianness(j); s_bone.position_pop(); } s_bone.position_push(0x00, SEEK_SET); - s_bone.write_uint32_t(0x09102720); - s_bone.write_uint32_t(skeleton_count); + s_bone.write_uint32_t_reverse_endianness(0x09102720); + s_bone.write_uint32_t_reverse_endianness(skeleton_count); s_bone.write_offset(skeleton_offsets_offset, 0x40, is_x); s_bone.write_offset(skeleton_name_offsets_offset, 0x40, is_x); s_bone.position_pop(); @@ -1405,7 +1417,7 @@ static void bone_database_modern_write_inner(bone_database* bone_data, stream& s string_offsets, i.name.c_str())); s_bone.position_pop(); - free(skh); + free_def(skh); f2_struct st; s_bone.align_write(0x10); @@ -1417,7 +1429,7 @@ static void bone_database_modern_write_inner(bone_database* bone_data, stream& s st.header.signature = reverse_endianness_uint32_t('BONE'); st.header.length = is_x ? 0x20 : 0x40; - st.header.use_big_endian = false; + st.header.use_big_endian = big_endian; st.header.use_section_size = true; st.write(s, true, is_x); @@ -1427,7 +1439,7 @@ inline static int64_t bone_database_strings_get_string_offset(std::vector& vec_off, const char* str) { size_t len = utf8_length(str); for (std::string& i : vec) - if (!memcmp(str, i.c_str(), min(len, i.size()) + 1)) + if (!memcmp(str, i.c_str(), min_def(len, i.size()) + 1)) return vec_off[&i - vec.data()]; return 0; } @@ -1435,7 +1447,7 @@ inline static int64_t bone_database_strings_get_string_offset(std::vector& vec, const char* str) { size_t len = utf8_length(str); for (std::string& i : vec) - if (!memcmp(str, i.c_str(), min(len, i.size()) + 1)) + if (!memcmp(str, i.c_str(), min_def(len, i.size()) + 1)) return false; vec.push_back(std::string(str, len)); diff --git a/src/KKdLib/database/bone.hpp b/src/KKdLib/database/bone.hpp index c03572e3..89bdcdec 100644 --- a/src/KKdLib/database/bone.hpp +++ b/src/KKdLib/database/bone.hpp @@ -64,6 +64,7 @@ struct bone_database_skeleton { struct bone_database { bool ready; bool modern; + bool big_endian; bool is_x; std::vector skeleton; diff --git a/src/KKdLib/database/item_table.cpp b/src/KKdLib/database/item_table.cpp index f13ab403..4461bc1b 100644 --- a/src/KKdLib/database/item_table.cpp +++ b/src/KKdLib/database/item_table.cpp @@ -4,8 +4,9 @@ */ #include "item_table.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../key_val.hpp" #include "../sort.hpp" #include "../str_utils.hpp" @@ -85,12 +86,12 @@ void itm_table::read(const char* path) { char* path_bin = str_utils_add(path, ".txt"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, "rb"); - if (s.io.stream) + if (s.check_not_null()) itm_table_read_inner(this, s); } - free(path_bin); + free_def(path_bin); } void itm_table::read(const wchar_t* path) { @@ -99,19 +100,19 @@ void itm_table::read(const wchar_t* path) { wchar_t* path_bin = str_utils_add(path, L".txt"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, L"rb"); - if (s.io.stream) + if (s.check_not_null()) itm_table_read_inner(this, s); } - free(path_bin); + free_def(path_bin); } void itm_table::read(const void* data, size_t size) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); itm_table_read_inner(this, s); } @@ -121,11 +122,11 @@ void itm_table::write(const char* path) { return; char* path_bin = str_utils_add(path, ".txt"); - stream s; + file_stream s; s.open(path_bin, "wb"); - if (s.io.stream) + if (s.check_not_null()) itm_table_write_inner(this, s); - free(path_bin); + free_def(path_bin); } void itm_table::write(const wchar_t* path) { @@ -133,18 +134,18 @@ void itm_table::write(const wchar_t* path) { return; wchar_t* path_bin = str_utils_add(path, L".txt"); - stream s; + file_stream s; s.open(path_bin, L"wb"); - if (s.io.stream) + if (s.check_not_null()) itm_table_write_inner(this, s); - free(path_bin); + free_def(path_bin); } void itm_table::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); itm_table_write_inner(this, s); s.copy(data, size); @@ -264,7 +265,7 @@ static void itm_table_read_inner(itm_table* itm_tbl, stream& s) { void* itm_tbl_data = force_malloc(s.length); s.read(itm_tbl_data, s.length); itm_table_read_text(itm_tbl, itm_tbl_data, s.length); - free(itm_tbl_data); + free_def(itm_tbl_data); itm_tbl->ready = true; } @@ -274,7 +275,7 @@ static void itm_table_write_inner(itm_table* itm_tbl, stream& s) { size_t itm_tbl_data_length = 0; itm_table_write_text(itm_tbl, &itm_tbl_data, &itm_tbl_data_length); s.write(itm_tbl_data, itm_tbl_data_length); - free(itm_tbl_data); + free_def(itm_tbl_data); } static void itm_table_read_text(itm_table* itm_tbl, void* data, size_t size) { @@ -518,7 +519,7 @@ static void itm_table_read_text(itm_table* itm_tbl, void* data, size_t size) { } static void itm_table_write_text(itm_table* itm_tbl, void** data, size_t* size) { - stream s; + memory_stream s; s.open(); key_val_out kv; diff --git a/src/KKdLib/database/motion.cpp b/src/KKdLib/database/motion.cpp index b2fdbf6d..d618405b 100644 --- a/src/KKdLib/database/motion.cpp +++ b/src/KKdLib/database/motion.cpp @@ -4,8 +4,9 @@ */ #include "motion.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../farc.hpp" #include "../hash.hpp" #include "../str_utils.hpp" @@ -32,12 +33,12 @@ void motion_database_file::read(const char* path) { farc_file* ff = f.read_file("mot_db.bin"); if (ff) { - stream s; + memory_stream s; s.open(ff->data, ff->size); motion_database_file_read_inner(this, s); } } - free(path_farc); + free_def(path_farc); } void motion_database_file::read(const wchar_t* path) { @@ -51,19 +52,19 @@ void motion_database_file::read(const wchar_t* path) { farc_file* ff = f.read_file("mot_db.bin"); if (ff) { - stream s; + memory_stream s; s.open(ff->data, ff->size); motion_database_file_read_inner(this, s); } } - free(path_farc); + free_def(path_farc); } void motion_database_file::read(const void* data, size_t size) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); motion_database_file_read_inner(this, s); } @@ -77,7 +78,7 @@ void motion_database_file::write(const char* path) { f.add_file("mot_db.bin"); farc_file* ff = &f.files.back(); - stream s; + memory_stream s; s.open(); motion_database_file_write_inner(this, s); s.copy(&ff->data, &ff->size); @@ -94,7 +95,7 @@ void motion_database_file::write(const wchar_t* path) { f.add_file("mot_db.bin"); farc_file* ff = &f.files.back(); - stream s; + memory_stream s; s.open(); motion_database_file_write_inner(this, s); s.copy(&ff->data, &ff->size); @@ -106,7 +107,7 @@ void motion_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); motion_database_file_write_inner(this, s); s.copy(data, size); diff --git a/src/KKdLib/database/object.cpp b/src/KKdLib/database/object.cpp index 7a1932ee..2b5961a3 100644 --- a/src/KKdLib/database/object.cpp +++ b/src/KKdLib/database/object.cpp @@ -5,8 +5,9 @@ #include "object.hpp" #include "../f2/struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../hash.hpp" #include "../sort.hpp" #include "../str_utils.hpp" @@ -62,7 +63,7 @@ object_info_data::~object_info_data() { } -object_database_file::object_database_file() : ready(), modern(), is_x() { +object_database_file::object_database_file() : ready(), modern(), big_endian(), is_x() { } @@ -77,18 +78,18 @@ void object_database_file::read(const char* path, bool modern) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, "rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); object_database_file_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { char* path_osi = str_utils_add(path, ".osi"); @@ -96,13 +97,13 @@ void object_database_file::read(const char* path, bool modern) { f2_struct st; st.read(path_osi); if (st.header.signature == reverse_endianness_uint32_t('MOSI')) { - stream s_mosi; + memory_stream s_mosi; s_mosi.open(st.data); - s_mosi.is_big_endian = st.header.use_big_endian; + s_mosi.big_endian = st.header.use_big_endian; object_database_file_modern_read_inner(this, s_mosi, st.header.length); } } - free(path_osi); + free_def(path_osi); } } @@ -113,18 +114,18 @@ void object_database_file::read(const wchar_t* path, bool modern) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, L"rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); object_database_file_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { wchar_t* path_osi = str_utils_add(path, L".osi"); @@ -132,13 +133,13 @@ void object_database_file::read(const wchar_t* path, bool modern) { f2_struct st; st.read(path_osi); if (st.header.signature == reverse_endianness_uint32_t('MOSI')) { - stream s_mosi; + memory_stream s_mosi; s_mosi.open(st.data); - s_mosi.is_big_endian = st.header.use_big_endian; + s_mosi.big_endian = st.header.use_big_endian; object_database_file_modern_read_inner(this, s_mosi, st.header.length); } } - free(path_osi); + free_def(path_osi); } } @@ -147,7 +148,7 @@ void object_database_file::read(const void* data, size_t size, bool modern) { return; if (!modern) { - stream s; + memory_stream s; s.open(data, size); object_database_file_classic_read_inner(this, s); } @@ -155,9 +156,9 @@ void object_database_file::read(const void* data, size_t size, bool modern) { f2_struct st; st.read(data, size); if (st.header.signature == reverse_endianness_uint32_t('MOSI')) { - stream s_mosi; + memory_stream s_mosi; s_mosi.open(st.data); - s_mosi.is_big_endian = st.header.use_big_endian; + s_mosi.big_endian = st.header.use_big_endian; object_database_file_modern_read_inner(this, s_mosi, st.header.length); } } @@ -169,19 +170,19 @@ void object_database_file::write(const char* path) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); - stream s; + file_stream s; s.open(path_bin, "wb"); - if (s.io.stream) + if (s.check_not_null()) object_database_file_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { char* path_osi = str_utils_add(path, ".osi"); - stream s; + file_stream s; s.open(path_osi, "wb"); - if (s.io.stream) + if (s.check_not_null()) object_database_file_modern_write_inner(this, s); - free(path_osi); + free_def(path_osi); } } @@ -191,19 +192,19 @@ void object_database_file::write(const wchar_t* path) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); - stream s; + file_stream s; s.open(path_bin, L"wb"); - if (s.io.stream) + if (s.check_not_null()) object_database_file_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { wchar_t* path_osi = str_utils_add(path, L".osi"); - stream s; + file_stream s; s.open(path_osi, L"wb"); - if (s.io.stream) + if (s.check_not_null()) object_database_file_modern_write_inner(this, s); - free(path_osi); + free_def(path_osi); } } @@ -211,7 +212,7 @@ void object_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); if (!modern) object_database_file_classic_write_inner(this, s); @@ -494,7 +495,7 @@ static void object_database_file_classic_read_inner(object_database_file* obj_db for (uint32_t i = 0; i < object_set_count; i++) object_set[i].object.reserve(object_set_object_count[i]); - free(object_set_object_count); + free_def(object_set_object_count); s.position_push(objects_offset, SEEK_SET); for (uint32_t i = 0; i < object_count; i++) { @@ -518,9 +519,10 @@ static void object_database_file_classic_read_inner(object_database_file* obj_db } s.position_pop(); - obj_db->is_x = false; - obj_db->modern = false; obj_db->ready = true; + obj_db->modern = false; + obj_db->big_endian = false; + obj_db->is_x = false; } static void object_database_file_classic_write_inner(object_database_file* obj_db, stream& s) { @@ -532,7 +534,6 @@ static void object_database_file_classic_write_inner(object_database_file* obj_d s.write_uint32_t(0x90669066); s.write_uint32_t(0x90669066); s.write_uint32_t(0x90669066); - s.align_write(0x20); uint32_t object_set_count = (uint32_t)obj_db->object_set.size(); @@ -585,8 +586,7 @@ static void object_database_file_classic_write_inner(object_database_file* obj_d for (object_set_info_file& i : obj_db->object_set) { uint16_t set_id = (uint16_t)i.id; for (object_info_data_file& j : i.object) { - s.write_uint16_t((uint16_t)j.id); - s.write_uint16_t(set_id); + s.write_uint32_t((uint32_t)((set_id << 16) | (uint16_t)j.id)); s.write_uint32_t((uint32_t)string_offsets[off_idx++]); } } @@ -604,6 +604,7 @@ static void object_database_file_classic_write_inner(object_database_file* obj_d } static void object_database_file_modern_read_inner(object_database_file* obj_db, stream& s, uint32_t header_length) { + bool big_endian = s.big_endian; bool is_x = true; s.set_position(0x0C, SEEK_SET); @@ -677,7 +678,7 @@ static void object_database_file_modern_read_inner(object_database_file* obj_db, for (uint32_t i = 0; i < object_set_count; i++) object_set[i].object.reserve(object_set_object_count[i]); - free(object_set_object_count); + free_def(object_set_object_count); s.position_push(objects_offset, SEEK_SET); if (!is_x) @@ -712,21 +713,25 @@ static void object_database_file_modern_read_inner(object_database_file* obj_db, } s.position_pop(); - obj_db->is_x = is_x; - obj_db->modern = true; obj_db->ready = true; + obj_db->modern = true; + obj_db->big_endian = big_endian; + obj_db->is_x = is_x; } static void object_database_file_modern_write_inner(object_database_file* obj_db, stream& s) { - stream s_mosi; + bool big_endian = obj_db->big_endian; + bool is_x = obj_db->is_x; + + memory_stream s_mosi; s_mosi.open(); + s_mosi.big_endian = big_endian; + uint32_t off; enrs e; enrs_entry ee; pof pof; - bool is_x = obj_db->is_x; - uint32_t object_set_count = (uint32_t)obj_db->object_set.size(); uint32_t object_count = 0; @@ -828,7 +833,7 @@ static void object_database_file_modern_write_inner(object_database_file* obj_db for (object_set_info_file& i : obj_db->object_set) { io_write_offset_f2_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, i.name), 0x20, &pof); - s_mosi.write_uint32_t(i.id); + s_mosi.write_uint32_t_reverse_endianness(i.id); io_write_offset_f2_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, i.object_file_name), 0x20, &pof); io_write_offset_f2_pof_add(s_mosi, object_database_strings_get_string_offset(strings, @@ -841,7 +846,7 @@ static void object_database_file_modern_write_inner(object_database_file* obj_db for (object_set_info_file& i : obj_db->object_set) { io_write_offset_x_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, i.name), &pof); - s_mosi.write_uint32_t(i.id); + s_mosi.write_uint32_t_reverse_endianness(i.id); io_write_offset_x_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, i.object_file_name), &pof); io_write_offset_x_pof_add(s_mosi, object_database_strings_get_string_offset(strings, @@ -856,8 +861,8 @@ static void object_database_file_modern_write_inner(object_database_file* obj_db for (object_set_info_file& i : obj_db->object_set) { uint32_t set_id = i.id; for (object_info_data_file& j : i.object) { - s_mosi.write_uint32_t(j.id); - s_mosi.write_uint32_t(set_id); + s_mosi.write_uint32_t_reverse_endianness(j.id); + s_mosi.write_uint32_t_reverse_endianness(set_id); io_write_offset_f2_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, j.name), 0x20, &pof); } @@ -866,8 +871,8 @@ static void object_database_file_modern_write_inner(object_database_file* obj_db for (object_set_info_file& i : obj_db->object_set) { uint32_t set_id = i.id; for (object_info_data_file& j : i.object) { - s_mosi.write_uint32_t(j.id); - s_mosi.write_uint32_t(set_id); + s_mosi.write_uint32_t_reverse_endianness(j.id); + s_mosi.write_uint32_t_reverse_endianness(set_id); io_write_offset_x_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, j.name), &pof); } @@ -884,7 +889,7 @@ static void object_database_file_modern_write_inner(object_database_file* obj_db st.header.signature = reverse_endianness_uint32_t('MOSI'); st.header.length = 0x20; - st.header.use_big_endian = false; + st.header.use_big_endian = big_endian; st.header.use_section_size = true; st.write(s, true, is_x); diff --git a/src/KKdLib/database/object.hpp b/src/KKdLib/database/object.hpp index 95f3c986..45a7515f 100644 --- a/src/KKdLib/database/object.hpp +++ b/src/KKdLib/database/object.hpp @@ -98,6 +98,7 @@ struct object_set_info { struct object_database_file { bool ready; bool modern; + bool big_endian; bool is_x; std::vector object_set; diff --git a/src/KKdLib/database/sprite.cpp b/src/KKdLib/database/sprite.cpp index c8c8724f..740f5a34 100644 --- a/src/KKdLib/database/sprite.cpp +++ b/src/KKdLib/database/sprite.cpp @@ -4,3 +4,768 @@ */ #include "sprite.hpp" +#include "../f2/struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" +#include "../io/path.hpp" +#include "../hash.hpp" +#include "../sort.hpp" +#include "../str_utils.hpp" + +static void sprite_database_file_classic_read_inner(sprite_database_file* spr_db, stream& s); +static void sprite_database_file_classic_write_inner(sprite_database_file* spr_db, stream& s); +static void sprite_database_file_modern_read_inner(sprite_database_file* spr_db, stream& s, uint32_t header_length); +static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db, stream& s); +static int64_t sprite_database_file_strings_get_string_offset(std::vector& vec, + std::vector& vec_off, std::string& str); +static bool sprite_database_file_strings_push_back_check(std::vector& vec, std::string& str); + +sprite_info_file::sprite_info_file() : id(), index() { + +} + +sprite_info_file::~sprite_info_file() { + +} + +sprite_info::sprite_info() : id(), index() { + name_hash = hash_murmurhash_empty; +} + +sprite_info::~sprite_info() { + +} + +sprite_texture_info_file::sprite_texture_info_file() : id(), index() { + +} + +sprite_texture_info_file::~sprite_texture_info_file() { + +} + +sprite_texture_info::sprite_texture_info() : id(), index() { + name_hash = hash_murmurhash_empty; +} + +sprite_texture_info::~sprite_texture_info() { + +} + +sprite_set_file::sprite_set_file() : id(), index(){ + +} + +sprite_set_file::~sprite_set_file() { + +} + +sprite_set::sprite_set() : id(), index() { + name_hash = hash_murmurhash_empty; + file_name_hash = hash_murmurhash_empty; +} + +sprite_set::~sprite_set() { + +} + +sprite_database_file::sprite_database_file() : ready(), modern(), big_endian(), is_x() { + +} + +sprite_database_file::~sprite_database_file() { + +} + +void sprite_database_file::read(const char* path, bool modern) { + if (!path) + return; + + if (!modern) { + char* path_bin = str_utils_add(path, ".bin"); + if (path_check_file_exists(path_bin)) { + file_stream s; + s.open(path_bin, "rb"); + if (s.check_not_null()) { + uint8_t* data = force_malloc_s(uint8_t, s.length); + s.read(data, s.length); + memory_stream s_bin; + s_bin.open(data, s.length); + sprite_database_file_classic_read_inner(this, s_bin); + free_def(data); + } + } + free_def(path_bin); + } + else { + char* path_spi = str_utils_add(path, ".spi"); + if (path_check_file_exists(path_spi)) { + f2_struct st; + st.read(path_spi); + if (st.header.signature == reverse_endianness_uint32_t('SPDB')) { + memory_stream s_spdb; + s_spdb.open(st.data); + s_spdb.big_endian = st.header.use_big_endian; + sprite_database_file_modern_read_inner(this, s_spdb, st.header.length); + } + } + free_def(path_spi); + } +} + +void sprite_database_file::read(const wchar_t* path, bool modern) { + if (!path) + return; + + if (!modern) { + wchar_t* path_bin = str_utils_add(path, L".bin"); + if (path_check_file_exists(path_bin)) { + file_stream s; + s.open(path_bin, L"rb"); + if (s.check_not_null()) { + uint8_t* data = force_malloc_s(uint8_t, s.length); + s.read(data, s.length); + memory_stream s_bin; + s_bin.open(data, s.length); + sprite_database_file_classic_read_inner(this, s_bin); + free_def(data); + } + } + free_def(path_bin); + } + else { + wchar_t* path_spi = str_utils_add(path, L".spi"); + if (path_check_file_exists(path_spi)) { + f2_struct st; + st.read(path_spi); + if (st.header.signature == reverse_endianness_uint32_t('SPDB')) { + memory_stream s_spdb; + s_spdb.open(st.data); + s_spdb.big_endian = st.header.use_big_endian; + sprite_database_file_modern_read_inner(this, s_spdb, st.header.length); + } + } + free_def(path_spi); + } +} + +void sprite_database_file::read(const void* data, size_t size, bool modern) { + if (!data || !size) + return; + + if (!modern) { + memory_stream s; + s.open(data, size); + sprite_database_file_classic_read_inner(this, s); + } + else { + f2_struct st; + st.read(data, size); + if (st.header.signature == reverse_endianness_uint32_t('SPDB')) { + memory_stream s_spdb; + s_spdb.open(st.data); + s_spdb.big_endian = st.header.use_big_endian; + sprite_database_file_modern_read_inner(this, s_spdb, st.header.length); + } + } +} + +void sprite_database_file::write(const char* path) { + if (!path || !ready) + return; + + if (!modern) { + char* path_bin = str_utils_add(path, ".bin"); + file_stream s; + s.open(path_bin, "wb"); + if (s.check_not_null()) + sprite_database_file_classic_write_inner(this, s); + free_def(path_bin); + } + else { + char* path_spi = str_utils_add(path, ".spi"); + file_stream s; + s.open(path_spi, "wb"); + if (s.check_not_null()) + sprite_database_file_modern_write_inner(this, s); + free_def(path_spi); + } +} + +void sprite_database_file::write(const wchar_t* path) { + if (!path || !ready) + return; + + if (!modern) { + wchar_t* path_bin = str_utils_add(path, L".bin"); + file_stream s; + s.open(path_bin, L"wb"); + if (s.check_not_null()) + sprite_database_file_classic_write_inner(this, s); + free_def(path_bin); + } + else { + wchar_t* path_spi = str_utils_add(path, L".spi"); + file_stream s; + s.open(path_spi, L"wb"); + if (s.check_not_null()) + sprite_database_file_modern_write_inner(this, s); + free_def(path_spi); + } +} + +void sprite_database_file::write(void** data, size_t* size) { + if (!data || !size || !ready) + return; + + memory_stream s; + s.open(); + if (!modern) + sprite_database_file_classic_write_inner(this, s); + else + sprite_database_file_modern_write_inner(this, s); + s.align_write(0x10); + s.copy(data, size); +} + +bool sprite_database_file::load_file(void* data, const char* path, const char* file, uint32_t hash) { + size_t file_len = utf8_length(file); + + const char* t = strrchr(file, '.'); + if (t) + file_len = t - file; + + std::string s = path + std::string(file, file_len); + + sprite_database_file* spr_db = (sprite_database_file*)data; + spr_db->read(s.c_str(), spr_db->modern); + + return spr_db->ready; +} + +sprite_database::sprite_database() { + +} + +sprite_database::~sprite_database() { + +} + +void sprite_database::add(sprite_database_file* spr_db_file) { + if (!spr_db_file || !spr_db_file->ready) + return; + + sprite_set_file* sprite_set = spr_db_file->sprite_set.data(); + + size_t sprite_sets_count = this->sprite_set.size(); + + this->sprite_set.reserve(spr_db_file->sprite_set.size()); + + for (sprite_set_file& i : spr_db_file->sprite_set) { + uint32_t id = i.id; + + ::sprite_set* set_info = 0; + for (::sprite_set& j : this->sprite_set) + if (id == j.id) { + set_info = &j; + break; + } + + if (!set_info) { + this->sprite_set.push_back({}); + set_info = &this->sprite_set.back(); + } + + set_info->id = i.id; + set_info->name.assign(i.name); + set_info->name_hash = hash_string_murmurhash(set_info->name); + set_info->file_name.assign(i.file_name); + set_info->file_name_hash = hash_string_murmurhash(set_info->file_name); + + set_info->sprite.clear(); + set_info->sprite.reserve(i.sprite.size()); + + for (sprite_info_file& j : i.sprite) { + set_info->sprite.push_back({}); + sprite_info& info = set_info->sprite.back(); + info.id = j.id; + info.name.assign(j.name); + info.name_hash = hash_string_murmurhash(info.name); + } + + set_info->texture.clear(); + set_info->texture.reserve(i.texture.size()); + + for (sprite_texture_info_file& j : i.texture) { + set_info->texture.push_back({}); + sprite_texture_info& info = set_info->texture.back(); + info.id = j.id; + info.name.assign(j.name); + info.name_hash = hash_string_murmurhash(info.name); + } + + set_info->index = (uint32_t)(sprite_sets_count + i.index); + } +} + +static void sprite_database_file_classic_read_inner(sprite_database_file* spr_db, stream& s) { + uint32_t sprite_sets_count = s.read_uint32_t(); + uint32_t sprite_sets_offset = s.read_uint32_t(); + uint32_t sprites_count = s.read_uint32_t(); + uint32_t sprites_offset = s.read_uint32_t(); + + spr_db->sprite_set.resize(sprite_sets_count); + + sprite_set_file* sprite_set = spr_db->sprite_set.data(); + + s.position_push(sprite_sets_offset, SEEK_SET); + for (uint32_t i = 0; i < sprite_sets_count; i++) { + sprite_set_file& set_info = sprite_set[i]; + set_info.id = s.read_uint32_t(); + set_info.name = s.read_string_null_terminated_offset(s.read_uint32_t()); + set_info.file_name = s.read_string_null_terminated_offset(s.read_uint32_t()); + set_info.index = s.read_uint32_t(); + } + s.position_pop(); + + s.position_push(sprites_offset, SEEK_SET); + for (uint32_t i = 0; i < sprites_count; i++) { + uint32_t id = s.read_uint32_t(); + uint32_t name_offset = s.read_uint32_t(); + uint32_t info = s.read_uint32_t(); + + uint16_t index = (uint16_t)(info & 0xFFFF); + uint16_t set_index = (uint16_t)((info >> 16) & 0x0FFF); + + sprite_set_file& set_info = sprite_set[set_index]; + + if ((info >> 16) & 0x1000) { + set_info.texture.push_back({}); + sprite_texture_info_file& info = set_info.texture.back(); + info.id = id; + info.name.assign(s.read_string_null_terminated_offset(name_offset)); + info.index = index; + } + else { + set_info.sprite.push_back({}); + sprite_info_file& info = set_info.sprite.back(); + info.id = id; + info.name.assign(s.read_string_null_terminated_offset(name_offset)); + info.index = index; + } + } + s.position_pop(); + + spr_db->ready = true; + spr_db->modern = false; + spr_db->big_endian = false; + spr_db->is_x = false; +} + +static void sprite_database_file_classic_write_inner(sprite_database_file* spr_db, stream& s) { + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.align_write(0x20); + + size_t sprite_sets_count = spr_db->sprite_set.size(); + + size_t sprites_count = 0; + for (sprite_set_file& i : spr_db->sprite_set) + sprites_count += i.sprite.size() + i.texture.size(); + + int64_t sprites_offset = s.get_position(); + s.write(0x0C * sprites_count); + s.align_write(0x20); + + int64_t sprite_sets_offset = s.get_position(); + s.write(0x10 * spr_db->sprite_set.size()); + s.align_write(0x20); + + std::vector strings; + std::vector string_offsets; + + strings.reserve(sprite_sets_count + sprites_count); + + for (sprite_set_file& i : spr_db->sprite_set) { + for (sprite_texture_info_file& j : i.texture) + if (sprite_database_file_strings_push_back_check(strings, j.name)) { + string_offsets.push_back(s.get_position()); + s.write_string_null_terminated(j.name); + } + + for (sprite_info_file& j : i.sprite) + if (sprite_database_file_strings_push_back_check(strings, j.name)) { + string_offsets.push_back(s.get_position()); + s.write_string_null_terminated(j.name); + } + } + s.align_write(0x04); + + for (sprite_set_file& i : spr_db->sprite_set) { + if (sprite_database_file_strings_push_back_check(strings, i.name)) { + string_offsets.push_back(s.get_position()); + s.write_string_null_terminated(i.name); + } + + if (sprite_database_file_strings_push_back_check(strings, i.file_name)) { + string_offsets.push_back(s.get_position()); + s.write_string_null_terminated(i.file_name); + } + } + s.align_write(0x04); + + s.position_push(sprites_offset, SEEK_SET); + for (sprite_set_file& i : spr_db->sprite_set) { + uint16_t sprite_set_index = (uint16_t)(i.index & 0x0FFF); + + for (sprite_texture_info_file& j : i.texture) { + s.write_uint32_t(j.id); + s.write_uint32_t((uint32_t)sprite_database_file_strings_get_string_offset(strings, + string_offsets, j.name)); + s.write_uint32_t(((0x1000 | sprite_set_index) << 16) | j.index); + } + + for (sprite_info_file& j : i.sprite) { + s.write_uint32_t(j.id); + s.write_uint32_t((uint32_t)sprite_database_file_strings_get_string_offset(strings, + string_offsets, j.name)); + s.write_uint32_t((sprite_set_index << 16) | j.index); + } + } + s.position_pop(); + + s.position_push(sprite_sets_offset, SEEK_SET); + for (sprite_set_file& i : spr_db->sprite_set) { + s.write_uint32_t(i.id); + s.write_uint32_t((uint32_t)sprite_database_file_strings_get_string_offset(strings, + string_offsets, i.name)); + s.write_uint32_t((uint32_t)sprite_database_file_strings_get_string_offset(strings, + string_offsets, i.file_name)); + s.write_uint32_t(i.index); + } + s.position_pop(); + + s.position_push(0x00, SEEK_SET); + s.write_uint32_t((uint32_t)sprite_sets_count); + s.write_uint32_t((uint32_t)sprite_sets_offset); + s.write_uint32_t((uint32_t)sprites_count); + s.write_uint32_t((uint32_t)sprites_offset); + s.position_pop(); +} + +static void sprite_database_file_modern_read_inner(sprite_database_file* spr_db, stream& s, uint32_t header_length) { + bool big_endian = s.big_endian; + bool is_x = true; + + s.set_position(0x04, SEEK_SET); + is_x &= s.read_uint32_t_reverse_endianness() == 0; + + s.set_position(0x00, SEEK_SET); + + uint32_t sprite_sets_count = s.read_uint32_t_reverse_endianness(); + int64_t sprite_sets_offset = s.read_offset(header_length, is_x); + uint32_t sprites_count = s.read_uint32_t_reverse_endianness(); + int64_t sprites_offset = s.read_offset(header_length, is_x); + + spr_db->sprite_set.resize(sprite_sets_count); + + sprite_set_file* sprite_set = spr_db->sprite_set.data(); + + s.position_push(sprite_sets_offset, SEEK_SET); + if (!is_x) + for (uint32_t i = 0; i < sprite_sets_count; i++) { + sprite_set_file& set_info = sprite_set[i]; + set_info.id = s.read_uint32_t_reverse_endianness(); + set_info.name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); + set_info.file_name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); + set_info.index = s.read_uint32_t_reverse_endianness(); + } + else + for (uint32_t i = 0; i < sprite_sets_count; i++) { + sprite_set_file& set_info = sprite_set[i]; + set_info.id = s.read_uint32_t_reverse_endianness(); + set_info.name = s.read_string_null_terminated_offset(s.read_offset_x()); + set_info.file_name = s.read_string_null_terminated_offset(s.read_offset_x()); + set_info.index = s.read_uint32_t_reverse_endianness(); + s.align_read(0x08); + } + s.position_pop(); + + s.position_push(sprites_offset, SEEK_SET); + if (!is_x) + for (uint32_t i = 0; i < sprites_count; i++) { + uint32_t id = s.read_uint32_t_reverse_endianness(); + int64_t name_offset = s.read_offset_f2(header_length); + uint32_t info = s.read_uint32_t_reverse_endianness(); + + uint16_t index = (uint16_t)(info & 0xFFFF); + uint16_t set_index = (uint16_t)((info >> 16) & 0x0FFF); + + sprite_set_file& set_info = sprite_set[set_index]; + + if ((info >> 16) & 0x1000) { + set_info.texture.push_back({}); + sprite_texture_info_file& info = set_info.texture.back(); + info.id = id; + info.name.assign(s.read_string_null_terminated_offset(name_offset)); + info.index = index; + } + else { + set_info.sprite.push_back({}); + sprite_info_file& info = set_info.sprite.back(); + info.id = id; + info.name.assign(s.read_string_null_terminated_offset(name_offset)); + info.index = index; + } + } + else + for (uint32_t i = 0; i < sprites_count; i++) { + uint32_t id = s.read_uint32_t_reverse_endianness(); + int64_t name_offset = s.read_offset_x(); + uint32_t info = s.read_uint32_t_reverse_endianness(); + s.align_read(0x08); + + uint16_t index = (uint16_t)(info & 0xFFFF); + uint16_t set_index = (uint16_t)((info >> 16) & 0x0FFF); + + sprite_set_file& set_info = sprite_set[set_index]; + + if ((info >> 16) & 0x1000) { + set_info.texture.push_back({}); + sprite_texture_info_file& info = set_info.texture.back(); + info.id = id; + info.name.assign(s.read_string_null_terminated_offset(name_offset)); + info.index = index; + } + else { + set_info.sprite.push_back({}); + sprite_info_file& info = set_info.sprite.back(); + info.id = id; + info.name.assign(s.read_string_null_terminated_offset(name_offset)); + info.index = index; + } + } + s.position_pop(); + + spr_db->ready = true; + spr_db->modern = true; + spr_db->big_endian = big_endian; + spr_db->is_x = is_x; +} + +static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db, stream& s) { + bool big_endian = spr_db->big_endian; + bool is_x = spr_db->is_x; + + memory_stream s_spdb; + s_spdb.open(); + s_spdb.big_endian = big_endian; + + uint32_t off; + enrs e; + enrs_entry ee; + pof pof; + + size_t sprite_sets_count = spr_db->sprite_set.size(); + + size_t sprites_count = 0; + for (sprite_set_file& i : spr_db->sprite_set) + sprites_count += i.sprite.size() + i.texture.size(); + + if (!is_x) { + ee = { 0, 1, 16, 1 }; + ee.append(0, 4, ENRS_DWORD); + e.vec.push_back(ee); + off = 16; + off = align_val(off, 0x10); + + ee = { off, 1, 16, (uint32_t)sprite_sets_count }; + ee.append(0, 4, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(sprite_sets_count * 16ULL); + off = align_val(off, 0x10); + + ee = { off, 1, 12, (uint32_t)sprites_count }; + ee.append(0, 3, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(sprites_count * 12ULL); + off = align_val(off, 0x10); + } + else { + ee = { 0, 4, 32, 1 }; + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 1, ENRS_QWORD); + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 1, ENRS_QWORD); + e.vec.push_back(ee); + off = 32; + off = align_val(off, 0x10); + + ee = { off, 3, 32, (uint32_t)sprite_sets_count }; + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 2, ENRS_QWORD); + ee.append(0, 1, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(sprite_sets_count * 32ULL); + off = align_val(off, 0x10); + + ee = { off, 3, 24, (uint32_t)sprites_count }; + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 1, ENRS_QWORD); + ee.append(0, 1, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(sprites_count * 24ULL); + off = align_val(off, 0x10); + } + + s_spdb.write(is_x ? 0x20 : 0x10); + s_spdb.align_write(0x10); + + int64_t sprite_sets_offset = s_spdb.get_position(); + s_spdb.write(sprite_sets_count * (is_x ? 0x20ULL : 0x10ULL)); + s_spdb.align_write(0x10); + + int64_t sprites_offset = s_spdb.get_position(); + s_spdb.write(sprites_count * (is_x ? 0x18ULL : 0x0CULL)); + s_spdb.align_write(0x10); + + std::vector strings; + std::vector string_offsets; + + strings.reserve(sprite_sets_count + sprites_count); + + for (sprite_set_file& i : spr_db->sprite_set) { + if (sprite_database_file_strings_push_back_check(strings, i.name)) { + string_offsets.push_back(s_spdb.get_position()); + s_spdb.write_string_null_terminated(i.name); + } + + if (sprite_database_file_strings_push_back_check(strings, i.file_name)) { + string_offsets.push_back(s_spdb.get_position()); + s_spdb.write_string_null_terminated(i.file_name); + } + } + + for (sprite_set_file& i : spr_db->sprite_set) { + for (sprite_texture_info_file& j : i.texture) + if (sprite_database_file_strings_push_back_check(strings, j.name)) { + string_offsets.push_back(s_spdb.get_position()); + s_spdb.write_string_null_terminated(j.name); + } + + for (sprite_info_file& j : i.sprite) + if (sprite_database_file_strings_push_back_check(strings, j.name)) { + string_offsets.push_back(s_spdb.get_position()); + s_spdb.write_string_null_terminated(j.name); + } + } + s_spdb.align_write(0x10); + + s_spdb.position_push(0x00, SEEK_SET); + s_spdb.write_uint32_t_reverse_endianness((uint32_t)sprite_sets_count); + io_write_offset_pof_add(s_spdb, sprite_sets_offset, 0x20, is_x, &pof); + s_spdb.write_uint32_t_reverse_endianness((uint32_t)sprites_count); + io_write_offset_pof_add(s_spdb, sprites_offset, 0x20, is_x, &pof); + s_spdb.position_pop(); + + s_spdb.position_push(sprite_sets_offset, SEEK_SET); + if (!is_x) + for (sprite_set_file& i : spr_db->sprite_set) { + s_spdb.write_uint32_t_reverse_endianness(i.id); + io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, i.name), 0x20, &pof); + io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, i.file_name), 0x20, &pof); + s_spdb.write_uint32_t_reverse_endianness(i.index); + } + else + for (sprite_set_file& i : spr_db->sprite_set) { + s_spdb.write_uint32_t_reverse_endianness(i.id); + io_write_offset_x_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, i.name), &pof); + io_write_offset_x_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, i.file_name), &pof); + s_spdb.write_uint32_t_reverse_endianness(i.index); + } + s_spdb.position_pop(); + + s_spdb.position_push(sprites_offset, SEEK_SET); + for (sprite_set_file& i : spr_db->sprite_set) { + uint16_t sprite_set_index = (uint16_t)(i.index & 0x0FFF); + + if (!is_x) + for (sprite_texture_info_file& j : i.texture) { + s_spdb.write_uint32_t_reverse_endianness(j.id); + io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, j.name), 0x20, &pof); + s_spdb.write_uint32_t_reverse_endianness(((0x1000 | sprite_set_index) << 16) | j.index); + } + else + for (sprite_texture_info_file& j : i.texture) { + s_spdb.write_uint32_t_reverse_endianness(j.id); + io_write_offset_x_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, j.name), &pof); + s_spdb.write_uint32_t_reverse_endianness(((0x1000 | sprite_set_index) << 16) | j.index); + s_spdb.align_write(0x08); + } + + if (!is_x) + for (sprite_info_file& j : i.sprite) { + s_spdb.write_uint32_t_reverse_endianness(j.id); + io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, j.name), 0x20, &pof); + s_spdb.write_uint32_t_reverse_endianness((sprite_set_index << 16) | j.index); + } + else + for (sprite_info_file& j : i.sprite) { + s_spdb.write_uint32_t_reverse_endianness(j.id); + io_write_offset_x_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, j.name), &pof); + s_spdb.write_uint32_t_reverse_endianness((sprite_set_index << 16) | j.index); + s_spdb.align_write(0x08); + } + } + s_spdb.position_pop(); + + f2_struct st; + s_spdb.align_write(0x10); + s_spdb.copy(st.data); + s_spdb.close(); + + st.enrs = e; + st.pof = pof; + + st.header.signature = reverse_endianness_uint32_t('SPDB'); + st.header.length = 0x20; + st.header.use_big_endian = big_endian; + st.header.use_section_size = true; + + st.write(s, true, spr_db->is_x); +} + +inline static int64_t sprite_database_file_strings_get_string_offset(std::vector& vec, + std::vector& vec_off, std::string& str) { + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) + return vec_off[&i - vec.data()]; + return 0; +} + +inline static bool sprite_database_file_strings_push_back_check(std::vector& vec, std::string& str) { + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) + return false; + + vec.push_back(str); + return true; +} diff --git a/src/KKdLib/database/sprite.hpp b/src/KKdLib/database/sprite.hpp index 3b25d82b..996f9248 100644 --- a/src/KKdLib/database/sprite.hpp +++ b/src/KKdLib/database/sprite.hpp @@ -6,3 +6,99 @@ #pragma once #include "../default.hpp" +#include +#include + +struct sprite_info_file { + uint32_t id; + std::string name; + uint16_t index; + + sprite_info_file(); + ~sprite_info_file(); +}; + +struct sprite_info { + uint32_t id; + std::string name; + uint32_t name_hash; + uint16_t index; + + sprite_info(); + ~sprite_info(); +}; + +struct sprite_texture_info_file { + uint32_t id; + std::string name; + uint16_t index; + + sprite_texture_info_file(); + ~sprite_texture_info_file(); +}; + +struct sprite_texture_info { + uint32_t id; + std::string name; + uint32_t name_hash; + uint16_t index; + + sprite_texture_info(); + ~sprite_texture_info(); +}; + +struct sprite_set_file { + uint32_t id; + std::string name; + std::string file_name; + std::vector sprite; + std::vector texture; + uint32_t index; + + sprite_set_file(); + ~sprite_set_file(); +}; + +struct sprite_set { + uint32_t id; + std::string name; + uint32_t name_hash; + std::string file_name; + uint32_t file_name_hash; + std::vector sprite; + std::vector texture; + uint32_t index; + + sprite_set(); + ~sprite_set(); +}; + +struct sprite_database_file { + bool ready; + bool modern; + bool big_endian; + bool is_x; + + std::vector sprite_set; + + sprite_database_file(); + virtual ~sprite_database_file(); + + void read(const char* path, bool modern); + void read(const wchar_t* path, bool modern); + void read(const void* data, size_t size, bool modern); + void write(const char* path); + void write(const wchar_t* path); + void write(void** data, size_t* size); + + static bool load_file(void* data, const char* path, const char* file, uint32_t hash); +}; + +struct sprite_database { + std::vector sprite_set; + + sprite_database(); + virtual ~sprite_database(); + + void add(sprite_database_file* spr_db_file); +}; diff --git a/src/KKdLib/database/stage.cpp b/src/KKdLib/database/stage.cpp index fb78d3cd..6847b182 100644 --- a/src/KKdLib/database/stage.cpp +++ b/src/KKdLib/database/stage.cpp @@ -5,8 +5,9 @@ #include "stage.hpp" #include "../f2/struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../hash.hpp" #include "../str_utils.hpp" @@ -65,7 +66,7 @@ stage_data_modern::~stage_data_modern() { } -stage_database_file::stage_database_file() : ready(), modern(), is_x(), format() { +stage_database_file::stage_database_file() : ready(), modern(), big_endian(), is_x(), format() { } @@ -80,18 +81,18 @@ void stage_database_file::read(const char* path, bool modern) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, "rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); stage_database_file_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { char* path_stg = str_utils_add(path, ".stg"); @@ -99,13 +100,13 @@ void stage_database_file::read(const char* path, bool modern) { f2_struct st; st.read(path_stg); if (st.header.signature == reverse_endianness_uint32_t('STGC')) { - stream s_stgc; + memory_stream s_stgc; s_stgc.open(st.data); - s_stgc.is_big_endian = st.header.use_big_endian; + s_stgc.big_endian = st.header.use_big_endian; stage_database_file_modern_read_inner(this, s_stgc, st.header.length); } } - free(path_stg); + free_def(path_stg); } } @@ -116,18 +117,18 @@ void stage_database_file::read(const wchar_t* path, bool modern) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, L"rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); stage_database_file_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { wchar_t* path_stg = str_utils_add(path, L".stg"); @@ -135,13 +136,13 @@ void stage_database_file::read(const wchar_t* path, bool modern) { f2_struct st; st.read(path_stg); if (st.header.signature == reverse_endianness_uint32_t('STGC')) { - stream s_stgc; + memory_stream s_stgc; s_stgc.open(st.data); - s_stgc.is_big_endian = st.header.use_big_endian; + s_stgc.big_endian = st.header.use_big_endian; stage_database_file_modern_read_inner(this, s_stgc, st.header.length); } } - free(path_stg); + free_def(path_stg); } } @@ -150,7 +151,7 @@ void stage_database_file::read(const void* data, size_t size, bool modern) { return; if (!modern) { - stream s; + memory_stream s; s.open(data, size); stage_database_file_classic_read_inner(this, s); } @@ -158,9 +159,9 @@ void stage_database_file::read(const void* data, size_t size, bool modern) { f2_struct st; st.read(data, size); if (st.header.signature == reverse_endianness_uint32_t('STGC')) { - stream s_stgc; + memory_stream s_stgc; s_stgc.open(st.data); - s_stgc.is_big_endian = st.header.use_big_endian; + s_stgc.big_endian = st.header.use_big_endian; stage_database_file_modern_read_inner(this, s_stgc, st.header.length); } } @@ -172,19 +173,19 @@ void stage_database_file::write(const char* path) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); - stream s; + file_stream s; s.open(path_bin, "wb"); - if (s.io.stream) + if (s.check_not_null()) stage_database_file_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { char* path_stg = str_utils_add(path, ".stg"); - stream s; + file_stream s; s.open(path_stg, "wb"); - if (s.io.stream) + if (s.check_not_null()) stage_database_file_modern_write_inner(this, s); - free(path_stg); + free_def(path_stg); } } @@ -194,19 +195,19 @@ void stage_database_file::write(const wchar_t* path) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); - stream s; + file_stream s; s.open(path_bin, L"wb"); - if (s.io.stream) + if (s.check_not_null()) stage_database_file_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { wchar_t* path_stg = str_utils_add(path, L".stg"); - stream s; + file_stream s; s.open(path_stg, L"wb"); - if (s.io.stream) + if (s.check_not_null()) stage_database_file_modern_write_inner(this, s); - free(path_stg); + free_def(path_stg); } } @@ -214,7 +215,7 @@ void stage_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); if (!modern) stage_database_file_classic_write_inner(this, s); @@ -408,6 +409,7 @@ static void stage_database_file_classic_read_inner(stage_database_file* stage_da if (stage_data->format == STAGE_DATA_UNK) { stage_data->ready = false; stage_data->modern = false; + stage_data->big_endian = false; stage_data->is_x = false; return; } @@ -571,6 +573,7 @@ static void stage_database_file_classic_read_inner(stage_database_file* stage_da stage_data->ready = true; stage_data->modern = false; + stage_data->big_endian = false; stage_data->is_x = false; } @@ -579,6 +582,7 @@ static void stage_database_file_classic_write_inner(stage_database_file* stage_d } static void stage_database_file_modern_read_inner(stage_database_file* stage_data, stream& s, uint32_t header_length) { + bool big_endian = s.big_endian; bool is_x = true; s.set_position(0x04, SEEK_SET); @@ -686,6 +690,7 @@ static void stage_database_file_modern_read_inner(stage_database_file* stage_dat stage_data->ready = true; stage_data->modern = true; + stage_data->big_endian = big_endian; stage_data->is_x = is_x; stage_data->format = STAGE_DATA_UNK; } diff --git a/src/KKdLib/database/stage.hpp b/src/KKdLib/database/stage.hpp index 7a011108..b13826c0 100644 --- a/src/KKdLib/database/stage.hpp +++ b/src/KKdLib/database/stage.hpp @@ -231,6 +231,7 @@ struct stage_data_modern { struct stage_database_file { bool ready; bool modern; + bool big_endian; bool is_x; stage_data_format format; diff --git a/src/KKdLib/database/texture.cpp b/src/KKdLib/database/texture.cpp index e0e81130..189dd541 100644 --- a/src/KKdLib/database/texture.cpp +++ b/src/KKdLib/database/texture.cpp @@ -5,8 +5,9 @@ #include "texture.hpp" #include "../f2/struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../hash.hpp" #include "../sort.hpp" #include "../str_utils.hpp" @@ -15,9 +16,9 @@ static void texture_database_file_classic_read_inner(texture_database_file* tex_ static void texture_database_file_classic_write_inner(texture_database_file* tex_db, stream& s); static void texture_database_file_modern_read_inner(texture_database_file* tex_db, stream& s, uint32_t header_length); static void texture_database_file_modern_write_inner(texture_database_file* tex_db, stream& s); -static int64_t texture_database_file_strings_get_string_offset(std::vector& vec, +static int64_t texture_database_file_strings_get_string_offset(std::vector& vec, std::vector& vec_off, std::string& str); -static void texture_database_file_strings_push_back_check(std::vector& vec, std::string& str); +static void texture_database_file_strings_push_back_check(std::vector& vec, std::string& str); texture_info_file::texture_info_file() { id = (uint32_t)-1; @@ -36,7 +37,7 @@ texture_info::~texture_info() { } -texture_database_file::texture_database_file() : ready(), modern(), is_x() { +texture_database_file::texture_database_file() : ready(), modern(), big_endian(), is_x() { } @@ -51,18 +52,18 @@ void texture_database_file::read(const char* path, bool modern) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, "rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); texture_database_file_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { char* path_txi = str_utils_add(path, ".txi"); @@ -70,13 +71,13 @@ void texture_database_file::read(const char* path, bool modern) { f2_struct st; st.read(path_txi); if (st.header.signature == reverse_endianness_uint32_t('MTXI')) { - stream s_mtxi; + memory_stream s_mtxi; s_mtxi.open(st.data); - s_mtxi.is_big_endian = st.header.use_big_endian; + s_mtxi.big_endian = st.header.use_big_endian; texture_database_file_modern_read_inner(this, s_mtxi, st.header.length); } } - free(path_txi); + free_def(path_txi); } } @@ -87,18 +88,18 @@ void texture_database_file::read(const wchar_t* path, bool modern) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, L"rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); texture_database_file_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { wchar_t* path_txi = str_utils_add(path, L".txi"); @@ -106,13 +107,13 @@ void texture_database_file::read(const wchar_t* path, bool modern) { f2_struct st; st.read(path_txi); if (st.header.signature == reverse_endianness_uint32_t('MTXI')) { - stream s_mtxi; + memory_stream s_mtxi; s_mtxi.open(st.data); - s_mtxi.is_big_endian = st.header.use_big_endian; + s_mtxi.big_endian = st.header.use_big_endian; texture_database_file_modern_read_inner(this, s_mtxi, st.header.length); } } - free(path_txi); + free_def(path_txi); } } @@ -121,7 +122,7 @@ void texture_database_file::read(const void* data, size_t size, bool modern) { return; if (!modern) { - stream s; + memory_stream s; s.open(data, size); texture_database_file_classic_read_inner(this, s); } @@ -129,9 +130,9 @@ void texture_database_file::read(const void* data, size_t size, bool modern) { f2_struct st; st.read(data, size); if (st.header.signature == reverse_endianness_uint32_t('MTXI')) { - stream s_mtxi; + memory_stream s_mtxi; s_mtxi.open(st.data); - s_mtxi.is_big_endian = st.header.use_big_endian; + s_mtxi.big_endian = st.header.use_big_endian; texture_database_file_modern_read_inner(this, s_mtxi, st.header.length); } } @@ -143,19 +144,19 @@ void texture_database_file::write(const char* path) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); - stream s; + file_stream s; s.open(path_bin, "wb"); - if (s.io.stream) + if (s.check_not_null()) texture_database_file_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { char* path_txi = str_utils_add(path, ".txi"); - stream s; + file_stream s; s.open(path_txi, "wb"); - if (s.io.stream) + if (s.check_not_null()) texture_database_file_modern_write_inner(this, s); - free(path_txi); + free_def(path_txi); } } @@ -165,19 +166,19 @@ void texture_database_file::write(const wchar_t* path) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); - stream s; + file_stream s; s.open(path_bin, L"wb"); - if (s.io.stream) + if (s.check_not_null()) texture_database_file_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { wchar_t* path_txi = str_utils_add(path, L".txi"); - stream s; + file_stream s; s.open(path_txi, L"wb"); - if (s.io.stream) + if (s.check_not_null()) texture_database_file_modern_write_inner(this, s); - free(path_txi); + free_def(path_txi); } } @@ -185,7 +186,7 @@ void texture_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); if (!modern) texture_database_file_classic_write_inner(this, s); @@ -283,9 +284,10 @@ static void texture_database_file_classic_read_inner(texture_database_file* tex_ } s.position_pop(); - tex_db->is_x = false; - tex_db->modern = false; tex_db->ready = true; + tex_db->modern = false; + tex_db->big_endian = false; + tex_db->is_x = false; } static void texture_database_file_classic_write_inner(texture_database_file* tex_db, stream& s) { @@ -327,6 +329,7 @@ static void texture_database_file_classic_write_inner(texture_database_file* tex } static void texture_database_file_modern_read_inner(texture_database_file* tex_db, stream& s, uint32_t header_length) { + bool big_endian = s.big_endian; bool is_x = true; s.set_position(0x04, SEEK_SET); @@ -356,31 +359,35 @@ static void texture_database_file_modern_read_inner(texture_database_file* tex_d } s.position_pop(); - tex_db->is_x = is_x; - tex_db->modern = true; tex_db->ready = true; + tex_db->modern = true; + tex_db->big_endian = big_endian; + tex_db->is_x = is_x; } static void texture_database_file_modern_write_inner(texture_database_file* tex_db, stream& s) { - stream s_mtxi; + bool big_endian = tex_db->big_endian; + bool is_x = tex_db->is_x; + + memory_stream s_mtxi; s_mtxi.open(); + s_mtxi.big_endian = big_endian; + uint32_t off; enrs e; enrs_entry ee; pof pof; - bool is_x = tex_db->is_x; - uint32_t textures_count = (uint32_t)tex_db->texture.size(); if (!is_x) { - ee = { 0, 2, 8, textures_count }; - ee.append(0, 9, ENRS_DWORD); + ee = { 0, 1, 8, textures_count }; + ee.append(0, 2, ENRS_DWORD); e.vec.push_back(ee); off = 8; off = align_val(off, 0x10); - ee = { off, 2, 8, textures_count }; + ee = { off, 1, 8, textures_count }; ee.append(0, 2, ENRS_DWORD); e.vec.push_back(ee); off = (uint32_t)(textures_count * 16ULL); @@ -395,7 +402,7 @@ static void texture_database_file_modern_write_inner(texture_database_file* tex_ textures_count--; } - s_mtxi.write_int32_t(0); + s_mtxi.write_int32_t_reverse_endianness(0); s_mtxi.write_offset(0, 0x20, is_x); s_mtxi.align_write(0x10); @@ -403,7 +410,7 @@ static void texture_database_file_modern_write_inner(texture_database_file* tex_ s_mtxi.write(textures_count * (is_x ? 0x10ULL : 0x08ULL)); s_mtxi.align_write(0x10); - std::vector strings; + std::vector strings; std::vector string_offsets; strings.reserve(textures_count); @@ -411,29 +418,29 @@ static void texture_database_file_modern_write_inner(texture_database_file* tex_ for (texture_info_file& i : tex_db->texture) texture_database_file_strings_push_back_check(strings, i.name); - quicksort_string(strings.data(), strings.size()); + quicksort_string_hash(strings.data(), strings.size()); string_offsets.reserve(strings.size()); - for (std::string& i : strings) { + for (string_hash& i : strings) { string_offsets.push_back(s_mtxi.get_position()); - s_mtxi.write_string_null_terminated(i); + s_mtxi.write_string_null_terminated(i.str); } s_mtxi.align_write(0x10); s_mtxi.position_push(0x00, SEEK_SET); - s_mtxi.write_uint32_t(textures_count); + s_mtxi.write_uint32_t_reverse_endianness(textures_count); io_write_offset_pof_add(s_mtxi, textures_offset, 0x20, is_x, &pof); s_mtxi.align_write(0x10); if (!is_x) for (texture_info_file& i : tex_db->texture) { - s_mtxi.write_uint32_t(i.id); + s_mtxi.write_uint32_t_reverse_endianness(i.id); int64_t offset = texture_database_file_strings_get_string_offset(strings, string_offsets, i.name); io_write_offset_f2_pof_add(s_mtxi, offset, 0x20, &pof); } else for (texture_info_file& i : tex_db->texture) { - s_mtxi.write_uint32_t(i.id); + s_mtxi.write_uint32_t_reverse_endianness(i.id); int64_t offset = texture_database_file_strings_get_string_offset(strings, string_offsets, i.name); io_write_offset_x_pof_add(s_mtxi, offset, &pof); @@ -450,23 +457,27 @@ static void texture_database_file_modern_write_inner(texture_database_file* tex_ st.header.signature = reverse_endianness_uint32_t('MTXI'); st.header.length = 0x20; - st.header.use_big_endian = false; + st.header.use_big_endian = big_endian; st.header.use_section_size = true; st.write(s, true, tex_db->is_x); } -inline static int64_t texture_database_file_strings_get_string_offset(std::vector& vec, +inline static int64_t texture_database_file_strings_get_string_offset(std::vector& vec, std::vector& vec_off, std::string& str) { - for (std::string& i : vec) - if (str == i) + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) return vec_off[&i - vec.data()]; return 0; } -inline static void texture_database_file_strings_push_back_check(std::vector& vec, std::string& str) { - for (std::string& i : vec) - if (str == i) +inline static void texture_database_file_strings_push_back_check(std::vector& vec, std::string& str) { + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) return; vec.push_back(str); diff --git a/src/KKdLib/database/texture.hpp b/src/KKdLib/database/texture.hpp index 6df6cabe..84af7f8b 100644 --- a/src/KKdLib/database/texture.hpp +++ b/src/KKdLib/database/texture.hpp @@ -29,6 +29,7 @@ struct texture_info { struct texture_database_file { bool ready; bool modern; + bool big_endian; bool is_x; std::vector texture; diff --git a/src/KKdLib/dds.cpp b/src/KKdLib/dds.cpp index 9935f06e..832824c5 100644 --- a/src/KKdLib/dds.cpp +++ b/src/KKdLib/dds.cpp @@ -4,7 +4,7 @@ */ #include "dds.hpp" -#include "io/stream.hpp" +#include "io/file_stream.hpp" #include "str_utils.hpp" #pragma pack(push, 1) @@ -154,7 +154,7 @@ dds::dds() : format(), width(), height(), mipmaps_count(), has_cube_map() { dds::~dds() { for (void*& i : data) { - free(i); + free_def(i); i = 0; } } @@ -165,7 +165,7 @@ void dds::read( const char* path) { wchar_t* path_buf = utf8_to_utf16(path); read(path_buf); - free(path_buf); + free_def(path_buf); } void dds::read(const wchar_t* path) { @@ -181,9 +181,9 @@ void dds::read(const wchar_t* path) { data.shrink_to_fit(); wchar_t* path_dds = str_utils_add(path, L".dds"); - stream s; + file_stream s; s.open(path_dds, L"rb"); - if (s.io.stream) { + if (s.check_not_null()) { if (s.read_uint32_t_reverse_endianness(true) != DDS_MAGIC) goto End; @@ -268,10 +268,10 @@ void dds::read(const wchar_t* path) { do for (uint32_t i = 0; i < mipmaps_count; i++) { - uint32_t width = max(this->width >> i, 1); - uint32_t height = max(this->height >> i, 1); + uint32_t width = max_def(this->width >> i, 1); + uint32_t height = max_def(this->height >> i, 1); uint32_t size = txp::get_size(format, - max(this->width >> i, 1), max(this->height >> i, 1)); + max_def(this->width >> i, 1), max_def(this->height >> i, 1)); void* data = force_malloc(size); s.read(data, size); if (reverse) @@ -283,7 +283,7 @@ void dds::read(const wchar_t* path) { while (has_cube_map && data.size() / mipmaps_count < 6); } End: - free(path_dds); + free_def(path_dds); } void dds::write(const char* path) { @@ -292,7 +292,7 @@ void dds::write(const char* path) { wchar_t* path_buf = utf8_to_utf16(path); write( path_buf); - free(path_buf); + free_def(path_buf); } void dds::write(const wchar_t* path) { @@ -300,9 +300,9 @@ void dds::write(const wchar_t* path) { return; wchar_t* path_dds = str_utils_add(path, L".dds"); - stream s; + file_stream s; s.open(path_dds, L"wb"); - if (s.io.stream) { + if (s.check_not_null()) { DDS_HEADER dds_h; memset(&dds_h, 0, sizeof(DDS_HEADER)); dds_h.size = sizeof(DDS_HEADER); @@ -373,17 +373,17 @@ void dds::write(const wchar_t* path) { do for (uint32_t i = 0; i < mipmaps_count; i++) { uint32_t size = txp::get_size(format, - max(width >> i, 1), max(height >> i, 1)); + max_def(width >> i, 1), max_def(height >> i, 1)); void* data = force_malloc(size); memcpy(data, this->data[index], size); dds_reverse_rgb(format, size, (uint8_t*)data); s.write(data, size); - free(data); + free_def(data); index++; } while (has_cube_map && index / mipmaps_count < 6); } - free(path_dds); + free_def(path_dds); } static void dds_reverse_rgb(txp_format format, int64_t size, uint8_t* data) { diff --git a/src/KKdLib/default.cpp b/src/KKdLib/default.cpp index 1c0650cf..799ae375 100644 --- a/src/KKdLib/default.cpp +++ b/src/KKdLib/default.cpp @@ -16,214 +16,6 @@ void* force_malloc(size_t size) { return buf; } -inline int16_t load_reverse_endianness_int16_t(const void* ptr) { - return (int16_t)_byteswap_ushort(*(uint16_t*)ptr); -} - -inline uint16_t load_reverse_endianness_uint16_t(const void* ptr) { - return (uint16_t)_byteswap_ushort(*(uint16_t*)ptr); -} - -inline int32_t load_reverse_endianness_int32_t(const void* ptr) { - return (int32_t)_byteswap_ulong(*(uint32_t*)ptr); -} - -inline uint32_t load_reverse_endianness_uint32_t(const void* ptr) { - return (uint32_t)_byteswap_ulong(*(uint32_t*)ptr); -} - -inline int64_t load_reverse_endianness_int64_t(const void* ptr) { - return (int64_t)_byteswap_uint64(*(uint64_t*)ptr); -} - -inline uint64_t load_reverse_endianness_uint64_t(const void* ptr) { - return (uint64_t)_byteswap_uint64(*(uint64_t*)ptr); -} - -inline ssize_t load_reverse_endianness_ssize_t(const void* ptr) { - return (ssize_t)_byteswap_uint64(*(uint64_t*)ptr); -} - -inline size_t load_reverse_endianness_size_t(const void* ptr) { - return (size_t)_byteswap_uint64(*(uint64_t*)ptr); -} - -inline float_t load_reverse_endianness_float_t(const void* ptr) { - uint32_t v = (uint32_t)_byteswap_ulong(*(uint32_t*)ptr); - return *(float_t*)&v; -} - -inline double_t load_reverse_endianness_double_t(const void* ptr) { - uint64_t v = (uint64_t)_byteswap_uint64(*(uint64_t*)ptr); - return *(double_t*)&v; -} - -inline void store_reverse_endianness_int16_t(int16_t value, void* ptr) { - *(int16_t*)ptr = (int16_t)_byteswap_ushort((uint16_t)value); -} - -inline void store_reverse_endianness_int16_t(uint16_t value, void* ptr) { - *(int16_t*)ptr = (int16_t)_byteswap_ushort(value); -} - -inline void store_reverse_endianness_uint16_t(int16_t value, void* ptr) { - *(uint16_t*)ptr = (uint16_t)_byteswap_ushort((uint16_t)value); -} - -inline void store_reverse_endianness_uint16_t(uint16_t value, void* ptr) { - *(uint16_t*)ptr = (uint16_t)_byteswap_ushort(value); -} - -inline void store_reverse_endianness_int32_t(int32_t value, void* ptr) { - *(int32_t*)ptr = (int32_t)_byteswap_ulong((uint32_t)value); -} - -inline void store_reverse_endianness_int32_t(uint32_t value, void* ptr) { - *(int32_t*)ptr = (int32_t)_byteswap_ulong(value); -} - -inline void store_reverse_endianness_uint32_t(int32_t value, void* ptr) { - *(uint32_t*)ptr = (uint32_t)_byteswap_ulong((uint32_t)value); -} - -inline void store_reverse_endianness_uint32_t(uint32_t value, void* ptr) { - *(uint32_t*)ptr = (uint32_t)_byteswap_ulong(value); -} - -inline void store_reverse_endianness_int64_t(int64_t value, void* ptr) { - *(int64_t*)ptr = (int64_t)_byteswap_uint64((uint64_t)value); -} - -inline void store_reverse_endianness_int64_t(uint64_t value, void* ptr) { - *(int64_t*)ptr = (int64_t)_byteswap_uint64(value); -} - -inline void store_reverse_endianness_uint64_t(int64_t value, void* ptr) { - *(uint64_t*)ptr = (uint64_t)_byteswap_uint64((uint64_t)value); -} - -inline void store_reverse_endianness_uint64_t(uint64_t value, void* ptr) { - *(uint64_t*)ptr = (uint64_t)_byteswap_uint64(value); -} - -inline void store_reverse_endianness_ssize_t(ssize_t value, void* ptr) { - *(ssize_t*)ptr = (ssize_t)_byteswap_uint64((uint64_t)value); -} - -inline void store_reverse_endianness_ssize_t(size_t value, void* ptr) { - *(ssize_t*)ptr = (ssize_t)_byteswap_uint64((uint64_t)value); -} - -inline void store_reverse_endianness_size_t(ssize_t value, void* ptr) { - *(size_t*)ptr = (size_t)_byteswap_uint64((uint64_t)value); -} - -inline void store_reverse_endianness_size_t(size_t value, void* ptr) { - *(size_t*)ptr = (size_t)_byteswap_uint64((uint64_t)value); -} - -inline void store_reverse_endianness_float_t(float_t value, void* ptr) { - *(uint32_t*)ptr = (uint32_t)_byteswap_ulong(*(uint32_t*)&value); -} - -inline void store_reverse_endianness_double_t(double_t value, void* ptr) { - *(uint64_t*)ptr = (uint64_t)_byteswap_uint64(*(uint64_t*)&value); -} - -inline int16_t reverse_endianness_int16_t(int16_t value) { - return (int16_t)_byteswap_ushort((uint16_t)value); -} - -inline int16_t reverse_endianness_int16_t(uint16_t value) { - return (int16_t)_byteswap_ushort(value); -} - -inline uint16_t reverse_endianness_uint16_t(int16_t value) { - return (uint16_t)_byteswap_ushort((uint16_t)value); -} - -inline uint16_t reverse_endianness_uint16_t(uint16_t value) { - return (uint16_t)_byteswap_ushort(value); -} - -inline int32_t reverse_endianness_int32_t(int32_t value) { - return (int32_t)_byteswap_ulong((uint32_t)value); -} - -inline int32_t reverse_endianness_int32_t(uint32_t value) { - return (int32_t)_byteswap_ulong(value); -} - -inline uint32_t reverse_endianness_uint32_t(int32_t value) { - return (uint32_t)_byteswap_ulong((uint32_t)value); -} - -inline uint32_t reverse_endianness_uint32_t(uint32_t value) { - return (uint32_t)_byteswap_ulong(value); -} - -inline int64_t reverse_endianness_int64_t(int64_t value) { - return (int64_t)_byteswap_uint64((uint64_t)value); -} - -inline int64_t reverse_endianness_int64_t(uint64_t value) { - return (int64_t)_byteswap_uint64(value); -} - -inline uint64_t reverse_endianness_uint64_t(int64_t value) { - return (uint64_t)_byteswap_uint64((uint64_t)value); -} - -inline uint64_t reverse_endianness_uint64_t(uint64_t value) { - return (uint64_t)_byteswap_uint64(value); -} - -inline ssize_t reverse_endianness_ssize_t(ssize_t value) { - return (ssize_t)_byteswap_uint64((uint64_t)value); -} - -inline ssize_t reverse_endianness_ssize_t(size_t value) { - return (ssize_t)_byteswap_uint64((uint64_t)value); -} - -inline size_t reverse_endianness_size_t(ssize_t value) { - return (size_t)_byteswap_uint64((uint64_t)value); -} - -inline size_t reverse_endianness_size_t(size_t value) { - return (size_t)_byteswap_uint64((uint64_t)value); -} - -inline float_t reverse_endianness_float_t(float_t value) { - uint32_t v = (uint32_t)_byteswap_ulong(*(uint32_t*)&value); - return *(float_t*)&v; -} - -inline double_t reverse_endianness_double_t(double_t value) { - uint64_t v = (uint64_t)_byteswap_uint64(*(uint64_t*)&value); - return *(double_t*)&v; -} - -constexpr size_t utf8_length(const char* s) { - if (!s) - return 0; - - size_t len = 0; - while (*s++) - len++; - return len; -} - -constexpr size_t utf16_length(const wchar_t* s) { - if (!s) - return 0; - - size_t len = 0; - while (*s++) - len++; - return len; -} - wchar_t* utf8_to_utf16(const char* s) { if (!s) return 0; @@ -331,95 +123,6 @@ char* utf16_to_utf8(const wchar_t* s) { return str; } -constexpr bool utf8_check_for_ascii_only(const char* s) { - char c = 0; - while (c = *s++) - if (c & 0x80) - return false; - return true; -} - -constexpr size_t utf8_to_utf16_length(const char* s) { - if (!s) - return 0; - - uint32_t c = 0; - size_t length = 0; - size_t l = 0; - - while (*s) { - char t = *s++; - if (~t & 0x80) { - l = 0; - length++; - c = 0; - continue; - } - else if ((t & 0xFC) == 0xF8) - continue; - else if ((t & 0xF8) == 0xF0) { - c = t & 0x07; - l = 3; - } - else if ((t & 0xF0) == 0xE0) { - c = t & 0x0F; - l = 2; - } - else if ((t & 0xE0) == 0xC0) { - c = t & 0x1F; - l = 1; - } - else if ((t & 0xC0) == 0x80) { - c = (c << 6) | (t & 0x3F); - l--; - } - - if (!l) { - if (c <= 0xD7FF || (c >= 0xE000 && c <= 0xFFFF)) - length++; - else if (c >= 0x10000 && c <= 0x10FFFF) { - length++; - length++; - } - c = 0; - } - } - return length; -} - -constexpr size_t utf16_to_utf8_length(const wchar_t* s) { - uint32_t c = 0; - size_t length = 0; - while (*s) { - c = *s++; - if ((c & 0xFC00) == 0xD800) { - if (!*s) - break; - - wchar_t _c = *s++; - if ((_c & 0xFC00) != 0xDC00) - continue; - - c &= 0x3FF; - c <<= 10; - c |= _c & 0x3FF; - c += 0x10000; - } - else if ((c & 0xFC00) == 0xDC00) - continue; - - if (c <= 0x7F) - length++; - else if (c <= 0x7FF) - length += 2; - else if ((c >= 0x800 && c <= 0xD7FF) || (c >= 0xE000 && c <= 0xFFFF)) - length += 3; - else if (c >= 0x10000 && c <= 0x10FFFF) - length += 4; - } - return length; -} - std::wstring utf8_to_utf16(const std::string& s) { if (!s.size()) return {}; diff --git a/src/KKdLib/default.hpp b/src/KKdLib/default.hpp index afdc2be0..ff9de82d 100644 --- a/src/KKdLib/default.hpp +++ b/src/KKdLib/default.hpp @@ -5,6 +5,7 @@ #pragma once +#define NOMINMAX #define _USE_MATH_DEFINES #include "types.hpp" #include @@ -19,7 +20,7 @@ #pragma warning( push ) #pragma warning( disable: 26812 ) -#define free(ptr) \ +#define free_def(ptr) \ { \ if (ptr) \ free(ptr); \ @@ -46,19 +47,15 @@ null(double_t) null(size_t) null(ssize_t) -#ifndef max -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#endif +#define max_def(a, b) (((a) > (b)) ? (a) : (b)) -#ifndef min -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#endif +#define min_def(a, b) (((a) < (b)) ? (a) : (b)) -#define mult_min_max(a, b, c) (((a) >= 0) ? ((a) * (b)) : ((a) * (c))) +#define mult_min_max_def(a, b, c) (((a) >= 0) ? ((a) * (b)) : ((a) * (c))) -#define div_min_max(a, b, c) (((a) >= 0) ? ((a) / (b)) : ((a) / (c))) +#define div_min_max_def(a, b, c) (((a) >= 0) ? ((a) / (b)) : ((a) / (c))) -#define clamp(a, b, c) (((((a) > (b)) ? (a) : (b)) < (c)) ? (((a) > (b)) ? (a) : (b)) : (c)) +#define clamp_def(a, b, c) (((((a) > (b)) ? (a) : (b)) < (c)) ? (((a) > (b)) ? (a) : (b)) : (c)) #define align_val(a, b) ((((a) + (b) - 1) / (b)) * (b)) @@ -90,7 +87,7 @@ null(ssize_t) #define actgh(x) (1.0 / atanh(x)) -#define lerp(x, y, blend) ((1.0f - (blend)) * (x) + (blend) * (y)) +#define lerp_def(x, y, blend) ((1.0f - (blend)) * (x) + (blend) * (y)) extern void* force_malloc(size_t size); #define force_malloc_s(s, size) (s*)force_malloc(sizeof(s) * (size)) @@ -107,59 +104,304 @@ extern void* force_malloc(size_t size); #define enum_not(s0, s1) \ (s0) = (decltype(s0))(~(int32_t)(s0)) -extern int16_t load_reverse_endianness_int16_t(const void* ptr); -extern uint16_t load_reverse_endianness_uint16_t(const void* ptr); -extern int32_t load_reverse_endianness_int32_t(const void* ptr); -extern uint32_t load_reverse_endianness_uint32_t(const void* ptr); -extern int64_t load_reverse_endianness_int64_t(const void* ptr); -extern uint64_t load_reverse_endianness_uint64_t(const void* ptr); -extern ssize_t load_reverse_endianness_ssize_t(const void* ptr); -extern size_t load_reverse_endianness_size_t(const void* ptr); -extern float_t load_reverse_endianness_float_t(const void* ptr); -extern double_t load_reverse_endianness_double_t(const void* ptr); -extern void store_reverse_endianness_int16_t(int16_t value, void* ptr); -extern void store_reverse_endianness_int16_t(uint16_t value, void* ptr); -extern void store_reverse_endianness_uint16_t(int16_t value, void* ptr); -extern void store_reverse_endianness_uint16_t(uint16_t value, void* ptr); -extern void store_reverse_endianness_int32_t(int32_t value, void* ptr); -extern void store_reverse_endianness_int32_t(uint32_t value, void* ptr); -extern void store_reverse_endianness_uint32_t(int32_t value, void* ptr); -extern void store_reverse_endianness_uint32_t(uint32_t value, void* ptr); -extern void store_reverse_endianness_int64_t(int64_t value, void* ptr); -extern void store_reverse_endianness_int64_t(uint64_t value, void* ptr); -extern void store_reverse_endianness_uint64_t(int64_t value, void* ptr); -extern void store_reverse_endianness_uint64_t(uint64_t value, void* ptr); -extern void store_reverse_endianness_ssize_t(ssize_t value, void* ptr); -extern void store_reverse_endianness_ssize_t(size_t value, void* ptr); -extern void store_reverse_endianness_size_t(ssize_t value, void* ptr); -extern void store_reverse_endianness_size_t(size_t value, void* ptr); -extern void store_reverse_endianness_float_t(float_t value, void* ptr); -extern void store_reverse_endianness_double_t(double_t value, void* ptr); -extern int16_t reverse_endianness_int16_t(int16_t value); -extern int16_t reverse_endianness_int16_t(uint16_t value); -extern uint16_t reverse_endianness_uint16_t(int16_t value); -extern uint16_t reverse_endianness_uint16_t(uint16_t value); -extern int32_t reverse_endianness_int32_t(int32_t value); -extern int32_t reverse_endianness_int32_t(uint32_t value); -extern uint32_t reverse_endianness_uint32_t(int32_t value); -extern uint32_t reverse_endianness_uint32_t(uint32_t value); -extern int64_t reverse_endianness_int64_t(int64_t value); -extern int64_t reverse_endianness_int64_t(uint64_t value); -extern uint64_t reverse_endianness_uint64_t(int64_t value); -extern uint64_t reverse_endianness_uint64_t(uint64_t value); -extern ssize_t reverse_endianness_ssize_t(ssize_t value); -extern ssize_t reverse_endianness_ssize_t(size_t value); -extern size_t reverse_endianness_size_t(ssize_t value); -extern size_t reverse_endianness_size_t(size_t value); -extern float_t reverse_endianness_float_t(float_t value); -extern double_t reverse_endianness_double_t(double_t value); +inline int16_t load_reverse_endianness_int16_t(const void* ptr) { + return (int16_t)_byteswap_ushort(*(uint16_t*)ptr); +} + +inline uint16_t load_reverse_endianness_uint16_t(const void* ptr) { + return (uint16_t)_byteswap_ushort(*(uint16_t*)ptr); +} + +inline int32_t load_reverse_endianness_int32_t(const void* ptr) { + return (int32_t)_byteswap_ulong(*(uint32_t*)ptr); +} + +inline uint32_t load_reverse_endianness_uint32_t(const void* ptr) { + return (uint32_t)_byteswap_ulong(*(uint32_t*)ptr); +} + +inline int64_t load_reverse_endianness_int64_t(const void* ptr) { + return (int64_t)_byteswap_uint64(*(uint64_t*)ptr); +} + +inline uint64_t load_reverse_endianness_uint64_t(const void* ptr) { + return (uint64_t)_byteswap_uint64(*(uint64_t*)ptr); +} + +inline ssize_t load_reverse_endianness_ssize_t(const void* ptr) { + return (ssize_t)_byteswap_uint64(*(uint64_t*)ptr); +} + +inline size_t load_reverse_endianness_size_t(const void* ptr) { + return (size_t)_byteswap_uint64(*(uint64_t*)ptr); +} + +inline float_t load_reverse_endianness_float_t(const void* ptr) { + uint32_t v = (uint32_t)_byteswap_ulong(*(uint32_t*)ptr); + return *(float_t*)&v; +} + +inline double_t load_reverse_endianness_double_t(const void* ptr) { + uint64_t v = (uint64_t)_byteswap_uint64(*(uint64_t*)ptr); + return *(double_t*)&v; +} + +inline void store_reverse_endianness_int16_t(void* ptr, int16_t value) { + *(int16_t*)ptr = (int16_t)_byteswap_ushort((uint16_t)value); +} + +inline void store_reverse_endianness_int16_t(void* ptr, uint16_t value) { + *(int16_t*)ptr = (int16_t)_byteswap_ushort(value); +} + +inline void store_reverse_endianness_uint16_t(void* ptr, int16_t value) { + *(uint16_t*)ptr = (uint16_t)_byteswap_ushort((uint16_t)value); +} + +inline void store_reverse_endianness_uint16_t(void* ptr, uint16_t value) { + *(uint16_t*)ptr = (uint16_t)_byteswap_ushort(value); +} + +inline void store_reverse_endianness_int32_t(void* ptr, int32_t value) { + *(int32_t*)ptr = (int32_t)_byteswap_ulong((uint32_t)value); +} + +inline void store_reverse_endianness_int32_t(void* ptr, uint32_t value) { + *(int32_t*)ptr = (int32_t)_byteswap_ulong(value); +} + +inline void store_reverse_endianness_uint32_t(void* ptr, int32_t value) { + *(uint32_t*)ptr = (uint32_t)_byteswap_ulong((uint32_t)value); +} + +inline void store_reverse_endianness_uint32_t(void* ptr, uint32_t value) { + *(uint32_t*)ptr = (uint32_t)_byteswap_ulong(value); +} + +inline void store_reverse_endianness_int64_t(void* ptr, int64_t value) { + *(int64_t*)ptr = (int64_t)_byteswap_uint64((uint64_t)value); +} + +inline void store_reverse_endianness_int64_t(void* ptr, uint64_t value) { + *(int64_t*)ptr = (int64_t)_byteswap_uint64(value); +} + +inline void store_reverse_endianness_uint64_t(void* ptr, int64_t value) { + *(uint64_t*)ptr = (uint64_t)_byteswap_uint64((uint64_t)value); +} + +inline void store_reverse_endianness_uint64_t(void* ptr, uint64_t value) { + *(uint64_t*)ptr = (uint64_t)_byteswap_uint64(value); +} + +inline void store_reverse_endianness_ssize_t(void* ptr, ssize_t value) { + *(ssize_t*)ptr = (ssize_t)_byteswap_uint64((uint64_t)value); +} + +inline void store_reverse_endianness_ssize_t(void* ptr, size_t value) { + *(ssize_t*)ptr = (ssize_t)_byteswap_uint64((uint64_t)value); +} + +inline void store_reverse_endianness_size_t(void* ptr, ssize_t value) { + *(size_t*)ptr = (size_t)_byteswap_uint64((uint64_t)value); +} + +inline void store_reverse_endianness_size_t(void* ptr, size_t value) { + *(size_t*)ptr = (size_t)_byteswap_uint64((uint64_t)value); +} + +inline void store_reverse_endianness_float_t(void* ptr, float_t value) { + *(uint32_t*)ptr = (uint32_t)_byteswap_ulong(*(uint32_t*)&value); +} + +inline void store_reverse_endianness_double_t(void* ptr, double_t value) { + *(uint64_t*)ptr = (uint64_t)_byteswap_uint64(*(uint64_t*)&value); +} + +inline int16_t reverse_endianness_int16_t(int16_t value) { + return (int16_t)_byteswap_ushort((uint16_t)value); +} + +inline int16_t reverse_endianness_int16_t(uint16_t value) { + return (int16_t)_byteswap_ushort(value); +} + +inline uint16_t reverse_endianness_uint16_t(int16_t value) { + return (uint16_t)_byteswap_ushort((uint16_t)value); +} + +inline uint16_t reverse_endianness_uint16_t(uint16_t value) { + return (uint16_t)_byteswap_ushort(value); +} + +inline int32_t reverse_endianness_int32_t(int32_t value) { + return (int32_t)_byteswap_ulong((uint32_t)value); +} + +inline int32_t reverse_endianness_int32_t(uint32_t value) { + return (int32_t)_byteswap_ulong(value); +} + +inline uint32_t reverse_endianness_uint32_t(int32_t value) { + return (uint32_t)_byteswap_ulong((uint32_t)value); +} + +inline uint32_t reverse_endianness_uint32_t(uint32_t value) { + return (uint32_t)_byteswap_ulong(value); +} + +inline int64_t reverse_endianness_int64_t(int64_t value) { + return (int64_t)_byteswap_uint64((uint64_t)value); +} + +inline int64_t reverse_endianness_int64_t(uint64_t value) { + return (int64_t)_byteswap_uint64(value); +} + +inline uint64_t reverse_endianness_uint64_t(int64_t value) { + return (uint64_t)_byteswap_uint64((uint64_t)value); +} + +inline uint64_t reverse_endianness_uint64_t(uint64_t value) { + return (uint64_t)_byteswap_uint64(value); +} + +inline ssize_t reverse_endianness_ssize_t(ssize_t value) { + return (ssize_t)_byteswap_uint64((uint64_t)value); +} + +inline ssize_t reverse_endianness_ssize_t(size_t value) { + return (ssize_t)_byteswap_uint64((uint64_t)value); +} + +inline size_t reverse_endianness_size_t(ssize_t value) { + return (size_t)_byteswap_uint64((uint64_t)value); +} + +inline size_t reverse_endianness_size_t(size_t value) { + return (size_t)_byteswap_uint64((uint64_t)value); +} + +inline float_t reverse_endianness_float_t(float_t value) { + uint32_t v = (uint32_t)_byteswap_ulong(*(uint32_t*)&value); + return *(float_t*)&v; +} + +inline double_t reverse_endianness_double_t(double_t value) { + uint64_t v = (uint64_t)_byteswap_uint64(*(uint64_t*)&value); + return *(double_t*)&v; +} + +inline constexpr size_t utf8_length(const char* s) { + if (!s) + return 0; + + size_t len = 0; + while (*s++) + len++; + return len; +} + +inline constexpr size_t utf16_length(const wchar_t* s) { + if (!s) + return 0; + + size_t len = 0; + while (*s++) + len++; + return len; +} + +inline constexpr bool utf8_check_for_ascii_only(const char* s) { + char c = 0; + while (c = *s++) + if (c & 0x80) + return false; + return true; +} + +inline constexpr size_t utf8_to_utf16_length(const char* s) { + if (!s) + return 0; + + uint32_t c = 0; + size_t length = 0; + size_t l = 0; + + while (*s) { + char t = *s++; + if (~t & 0x80) { + l = 0; + length++; + c = 0; + continue; + } + else if ((t & 0xFC) == 0xF8) + continue; + else if ((t & 0xF8) == 0xF0) { + c = t & 0x07; + l = 3; + } + else if ((t & 0xF0) == 0xE0) { + c = t & 0x0F; + l = 2; + } + else if ((t & 0xE0) == 0xC0) { + c = t & 0x1F; + l = 1; + } + else if ((t & 0xC0) == 0x80) { + c = (c << 6) | (t & 0x3F); + l--; + } + + if (!l) { + if (c <= 0xD7FF || (c >= 0xE000 && c <= 0xFFFF)) + length++; + else if (c >= 0x10000 && c <= 0x10FFFF) { + length++; + length++; + } + c = 0; + } + } + return length; +} + +inline constexpr size_t utf16_to_utf8_length(const wchar_t* s) { + uint32_t c = 0; + size_t length = 0; + while (*s) { + c = *s++; + if ((c & 0xFC00) == 0xD800) { + if (!*s) + break; + + wchar_t _c = *s++; + if ((_c & 0xFC00) != 0xDC00) + continue; + + c &= 0x3FF; + c <<= 10; + c |= _c & 0x3FF; + c += 0x10000; + } + else if ((c & 0xFC00) == 0xDC00) + continue; + + if (c <= 0x7F) + length++; + else if (c <= 0x7FF) + length += 2; + else if ((c >= 0x800 && c <= 0xD7FF) || (c >= 0xE000 && c <= 0xFFFF)) + length += 3; + else if (c >= 0x10000 && c <= 0x10FFFF) + length += 4; + } + return length; +} -extern constexpr size_t utf8_length(const char* s); -extern constexpr size_t utf16_length(const wchar_t* s); extern wchar_t* utf8_to_utf16(const char* s); extern char* utf16_to_utf8(const wchar_t* s); -extern constexpr bool utf8_check_for_ascii_only(const char* s); -extern constexpr size_t utf8_to_utf16_length(const char* s); -extern constexpr size_t utf16_to_utf8_length(const wchar_t* s); extern std::wstring utf8_to_utf16(const std::string& s); extern std::string utf16_to_utf8(const std::wstring& s); diff --git a/src/KKdLib/deflate.cpp b/src/KKdLib/deflate.cpp index 20176df5..24c95078 100644 --- a/src/KKdLib/deflate.cpp +++ b/src/KKdLib/deflate.cpp @@ -34,6 +34,37 @@ namespace deflate { return result >= 0 ? result : result - 0x10; } + int32_t compress_gzip(const void* src, size_t src_length, void** dst, + size_t* dst_length, int32_t compression_level, const char* file_name) { + if (!src_length) + return -1; + else if (!src) + return -2; + else if (!dst) + return -3; + else if (!dst_length) + return -4; + + struct libdeflate_compressor* c = libdeflate_alloc_compressor(compression_level); + if (!c) + return -5; + + int32_t result = compress_static(c, src, src_length, dst, dst_length, compression_level, MODE_GZIP); + libdeflate_free_compressor(c); + if (result < 0) + return result - 0x10; + + size_t file_name_length = utf8_length(file_name); + void* temp = force_malloc(*dst_length + file_name_length + 1); + size_t t = (size_t)temp; + size_t d = (size_t)*dst; + memcpy((void*)t, (void*)d, 0x0A); + memcpy((void*)(t + 0x0A), file_name, file_name_length + 1); + memcpy((void*)(t + 0x0A + file_name_length + 1), (void*)(d + 0x0A), *dst_length - 0x0A); + ((uint8_t*)t)[0x03] |= 0x08; + return result; + } + int32_t decompress(const void* src, size_t src_length, void** dst, size_t* dst_length, mode mode) { if (!src_length) @@ -69,6 +100,7 @@ namespace deflate { dst_max_length = libdeflate_deflate_compress_bound(c, src_length); break; } + *dst = force_malloc(dst_max_length); if (!*dst) return -1; @@ -93,12 +125,12 @@ namespace deflate { void* temp = force_malloc(dst_act_length); if (!temp) { - free(*dst); + free_def(*dst); return -2; } memcpy(temp, *dst, dst_act_length); - free(*dst); + free_def(*dst); *dst = temp; *dst_length = dst_act_length; return 0; @@ -126,11 +158,11 @@ namespace deflate { switch (result) { case LIBDEFLATE_BAD_DATA: - free(*dst); + free_def(*dst); return -2; break; case LIBDEFLATE_INSUFFICIENT_SPACE: - free(*dst); + free_def(*dst); *dst_length *= 2; decompress_static(d, src, src_length, dst, dst_length, mode); break; @@ -140,12 +172,12 @@ namespace deflate { void* temp = force_malloc(dst_act_length); if (!temp) { - free(*dst); + free_def(*dst); return -3; } memcpy(temp, *dst, dst_act_length); - free(*dst); + free_def(*dst); *dst = temp; *dst_length = dst_act_length; break; diff --git a/src/KKdLib/deflate.hpp b/src/KKdLib/deflate.hpp index c63f892f..e62904b4 100644 --- a/src/KKdLib/deflate.hpp +++ b/src/KKdLib/deflate.hpp @@ -16,6 +16,8 @@ namespace deflate { extern int32_t compress(const void* src, size_t src_length, void** dst, size_t* dst_length, int32_t compression_level, mode mode); + extern int32_t compress_gzip(const void* src, size_t src_length, void** dst, + size_t* dst_length, int32_t compression_level, const char* file_name = 0); extern int32_t decompress(const void* src, size_t src_length, void** dst, size_t* dst_length, mode mode); } diff --git a/src/KKdLib/divafile.cpp b/src/KKdLib/divafile.cpp index 2aa2d987..3802ed9c 100644 --- a/src/KKdLib/divafile.cpp +++ b/src/KKdLib/divafile.cpp @@ -4,6 +4,7 @@ */ #include "divafile.hpp" +#include "io/file_stream.hpp" #include "aes.hpp" #include "str_utils.hpp" @@ -16,14 +17,14 @@ namespace divafile { void decrypt(const char* path) { wchar_t* file_buf = utf8_to_utf16(path); decrypt(file_buf); - free(file_buf); + free_def(file_buf); } void decrypt(const wchar_t* path) { wchar_t* file_temp = str_utils_add(path, L"_dec"); - stream s_enc; + file_stream s_enc; s_enc.open(path, L"rb"); - if (s_enc.io.stream) { + if (s_enc.check_not_null()) { uint64_t signature = s_enc.read_uint64_t(); if (signature == 0x454C494641564944) { uint32_t stream_length = s_enc.read_uint32_t(); @@ -35,13 +36,13 @@ namespace divafile { aes128_init_ctx(&ctx, key); aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)data, stream_length); - stream s_dec; + file_stream s_dec; s_dec.open(file_temp, L"wb"); - s_dec.write(data, min(file_length, stream_length)); - free(data); + s_dec.write(data, min_def(file_length, stream_length)); + free_def(data); } } - free(file_temp); + free_def(file_temp); } void decrypt(void* enc_data, void** dec_data, size_t* dec_size) { @@ -70,38 +71,46 @@ namespace divafile { *dec_size = file_length; } - void decrypt(stream& s) { - size_t pos = s.get_position(); - uint64_t signature = s.read_uint64_t(); + void decrypt(stream& enc, memory_stream& dec) { + size_t pos = enc.get_position(); + uint64_t signature = enc.read_uint64_t(); if (signature != 0x454C494641564944) { - s.set_position(pos, SEEK_SET); + std::vector data; + enc.set_position(0, SEEK_SET); + int64_t length = enc.get_length(); + data.resize(length); + enc.read(data.data(), length); + enc.set_position(pos, SEEK_SET); + dec.open(data); return; } - uint32_t stream_length = s.read_uint32_t(); - uint32_t file_length = s.read_uint32_t(); + uint32_t stream_length = enc.read_uint32_t(); + uint32_t file_length = enc.read_uint32_t(); void* data = force_malloc(stream_length); - s.read(data, stream_length); + enc.read(data, stream_length); aes128_ctx ctx; aes128_init_ctx(&ctx, key); aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)data, stream_length); - s.open(data, file_length); - free(data); + dec.open(data, file_length); + free_def(data); + } + void decrypt(memory_stream& s) { } void encrypt(const char* path) { wchar_t* file_buf = utf8_to_utf16(path); encrypt(file_buf); - free(file_buf); + free_def(file_buf); } void encrypt(const wchar_t* path) { wchar_t* file_temp = str_utils_add(path, L"_enc"); - stream s_dec; + file_stream s_dec; s_dec.open(path, L"rb"); - if (s_dec.io.stream) { + if (s_dec.check_not_null()) { size_t len = s_dec.length; size_t len_align = align_val(len, 0x10); @@ -112,15 +121,15 @@ namespace divafile { aes128_init_ctx(&ctx, key); aes128_ecb_encrypt_buffer(&ctx, (uint8_t*)data, len_align); - stream s_enc; + file_stream s_enc; s_enc.open(file_temp, L"wb"); s_enc.write_uint64_t(0x454C494641564944); s_enc.write_uint32_t((uint32_t)len_align); s_enc.write_uint32_t((uint32_t)len); s_enc.write(data, len_align); - free(data); + free_def(data); } - free(file_temp); + free_def(file_temp); } void encrypt(void* dec_data, size_t dec_size, void** enc_data, size_t* enc_size) { diff --git a/src/KKdLib/divafile.hpp b/src/KKdLib/divafile.hpp index debe1ea3..005df9bd 100644 --- a/src/KKdLib/divafile.hpp +++ b/src/KKdLib/divafile.hpp @@ -6,13 +6,13 @@ #pragma once #include "default.hpp" -#include "io/stream.hpp" +#include "io/memory_stream.hpp" namespace divafile { extern void decrypt(const char* path); extern void decrypt(const wchar_t* path); extern void decrypt(void* enc_data, void** dec_data, size_t* dec_size); - extern void decrypt(stream& s); + extern void decrypt(stream& enc, memory_stream& dec); extern void encrypt(const char* path); extern void encrypt(const wchar_t* path); extern void encrypt(void* dec_data, size_t dec_size, void** enc_data, size_t* enc_size); diff --git a/src/KKdLib/dsc.cpp b/src/KKdLib/dsc.cpp index 39cbc6ed..84b879f2 100644 --- a/src/KKdLib/dsc.cpp +++ b/src/KKdLib/dsc.cpp @@ -1,812 +1,813 @@ -/* +/* by korenkonder GitHub/GitLab: korenkonder */ #include "dsc.hpp" #include "f2/struct.hpp" +#include "io/file_stream.hpp" #include "hash.hpp" #include "sort.hpp" #include "str_utils.hpp" static const dsc_func dsc_ac101_func[] = { - { 0, 0, "END" }, - { 1, 1, "TIME" }, - { 2, 3, "MIKU_MOVE" }, - { 3, 1, "MIKU_ROT" }, - { 4, 1, "MIKU_DISP" }, - { 5, 1, "MIKU_SHADOW" }, - { 6, 7, "TARGET" }, - { 7, 3, "SET_MOTION" }, - { 8, 1, "SET_PLAYDATA" }, - { 9, 5, "EFFECT" }, - { 10, 2, "FADEIN_FIELD" }, - { 11, 1, "EFFECT_OFF" }, - { 12, 6, "SET_CAMERA" }, - { 13, 2, "DATA_CAMERA" }, - { 14, 1, "CHANGE_FIELD" }, - { 15, 1, "HIDE_FIELD" }, - { 16, 3, "MOVE_FIELD" }, - { 17, 2, "FADEOUT_FIELD" }, - { 18, 2, "EYE_ANIM" }, - { 19, 3, "MOUTH_ANIM" }, - { 20, 4, "HAND_ANIM" }, - { 21, 3, "LOOK_ANIM" }, - { 22, 3, "EXPRESSION" }, - { 23, 4, "LOOK_CAMERA" }, - { 24, 1, "LYRIC" }, - { 25, 0, "MUSIC_PLAY" }, - { 26, 1, "MODE_SELECT" }, - { 27, 2, "EDIT_MOTION" }, - { 28, 2, "BAR_TIME_SET" }, - { 29, 1, "SHADOWHEIGHT" }, - { 30, 2, "EDIT_FACE" }, - { 31, 19, "MOVE_CAMERA" }, - { 32, 0, "PV_END" }, - { 33, 2, "SHADOWPOS" }, - { 34, 2, "NEAR_CLIP" }, - { 35, 1, "CLOTH_WET" }, - { 36, 6, "SCENE_FADE" }, // AC110 - { 37, 6, "TONE_TRANS" }, // AC120 - { 38, 1, "SATURATE" }, - { 39, 1, "FADE_MODE" }, + { 0, 0, u8"END" }, + { 1, 1, u8"TIME" }, + { 2, 3, u8"MIKU_MOVE" }, + { 3, 1, u8"MIKU_ROT" }, + { 4, 1, u8"MIKU_DISP" }, + { 5, 1, u8"MIKU_SHADOW" }, + { 6, 7, u8"TARGET" }, + { 7, 3, u8"SET_MOTION" }, + { 8, 1, u8"SET_PLAYDATA" }, + { 9, 5, u8"EFFECT" }, + { 10, 2, u8"FADEIN_FIELD" }, + { 11, 1, u8"EFFECT_OFF" }, + { 12, 6, u8"SET_CAMERA" }, + { 13, 2, u8"DATA_CAMERA" }, + { 14, 1, u8"CHANGE_FIELD" }, + { 15, 1, u8"HIDE_FIELD" }, + { 16, 3, u8"MOVE_FIELD" }, + { 17, 2, u8"FADEOUT_FIELD" }, + { 18, 2, u8"EYE_ANIM" }, + { 19, 3, u8"MOUTH_ANIM" }, + { 20, 4, u8"HAND_ANIM" }, + { 21, 3, u8"LOOK_ANIM" }, + { 22, 3, u8"EXPRESSION" }, + { 23, 4, u8"LOOK_CAMERA" }, + { 24, 1, u8"LYRIC" }, + { 25, 0, u8"MUSIC_PLAY" }, + { 26, 1, u8"MODE_SELECT" }, + { 27, 2, u8"EDIT_MOTION" }, + { 28, 2, u8"BAR_TIME_SET" }, + { 29, 1, u8"SHADOWHEIGHT" }, + { 30, 2, u8"EDIT_FACE" }, + { 31, 19, u8"MOVE_CAMERA" }, + { 32, 0, u8"PV_END" }, + { 33, 2, u8"SHADOWPOS" }, + { 34, 2, u8"NEAR_CLIP" }, + { 35, 1, u8"CLOTH_WET" }, + { 36, 6, u8"SCENE_FADE" }, // AC110 + { 37, 6, u8"TONE_TRANS" }, // AC120 + { 38, 1, u8"SATURATE" }, + { 39, 1, u8"FADE_MODE" }, }; static const dsc_func_ac dsc_ac_func[] = { - { 0, 0, 0, "END" }, - { 1, 1, 1, "TIME" }, - { 2, 3, 4, "MIKU_MOVE" }, - { 3, 1, 2, "MIKU_ROT" }, - { 4, 1, 2, "MIKU_DISP" }, - { 5, 1, 2, "MIKU_SHADOW" }, - { 6, 7, 7, "TARGET" }, - { 7, 3, 4, "SET_MOTION" }, - { 8, 1, 2, "SET_PLAYDATA" }, - { 9, 5, 6, "EFFECT" }, - { 10, 2, 2, "FADEIN_FIELD" }, - { 11, 1, 1, "EFFECT_OFF" }, - { 12, 6, 6, "SET_CAMERA" }, - { 13, 2, 2, "DATA_CAMERA" }, - { 14, 1, 1, "CHANGE_FIELD" }, - { 15, 1, 1, "HIDE_FIELD" }, - { 16, 3, 3, "MOVE_FIELD" }, - { 17, 2, 2, "FADEOUT_FIELD" }, - { 18, 2, 3, "EYE_ANIM" }, - { 19, 3, 5, "MOUTH_ANIM" }, - { 20, 4, 5, "HAND_ANIM" }, - { 21, 3, 4, "LOOK_ANIM" }, - { 22, 3, 4, "EXPRESSION" }, - { 23, 4, 5, "LOOK_CAMERA" }, - { 24, 1, 2, "LYRIC" }, - { 25, 0, 0, "MUSIC_PLAY" }, - { 26, 1, 2, "MODE_SELECT" }, - { 27, 2, 4, "EDIT_MOTION" }, - { 28, 2, 2, "BAR_TIME_SET" }, - { 29, 1, 2, "SHADOWHEIGHT" }, - { 30, 2, 1, "EDIT_FACE" }, - { 31, 19, 21, "MOVE_CAMERA" }, - { 32, 0, 0, "PV_END" }, - { 33, 2, 3, "SHADOWPOS" }, - { 34, 2, 2, "EDIT_LYRIC" }, - { 35, 5, 5, "EDIT_TARGET" }, - { 36, 1, 1, "EDIT_MOUTH" }, - { 37, 1, 1, "SET_CHARA" }, - { 38, 7, 7, "EDIT_MOVE" }, - { 39, 1, 1, "EDIT_SHADOW" }, - { 40, 1, 1, "EDIT_EYELID" }, - { 41, 2, 2, "EDIT_EYE" }, - { 42, 1, 1, "EDIT_ITEM" }, - { 43, 2, 2, "EDIT_EFFECT" }, - { 44, 1, 1, "EDIT_DISP" }, - { 45, 2, 2, "EDIT_HAND_ANIM" }, - { 46, 3, 3, "AIM" }, - { 47, 3, 3, "HAND_ITEM" }, - { 48, 1, 1, "EDIT_BLUSH" }, - { 49, 2, 2, "NEAR_CLIP" }, - { 50, 1, 2, "CLOTH_WET" }, - { 51, 3, 3, "LIGHT_ROT" }, - { 52, 6, 6, "SCENE_FADE" }, - { 53, 6, 6, "TONE_TRANS" }, - { 54, 1, 1, "SATURATE" }, - { 55, 1, 1, "FADE_MODE" }, - { 56, 2, 2, "AUTO_BLINK" }, - { 57, 3, 3, "PARTS_DISP" }, - { 58, 1, 1, "TARGET_FLYING_TIME" }, // AC210 - { 59, 2, 2, "CHARA_SIZE" }, - { 60, 2, 2, "CHARA_HEIGHT_ADJUST" }, - { 61, 4, 4, "ITEM_ANIM" }, - { 62, 4, 4, "CHARA_POS_ADJUST" }, - { 63, 1, 1, "SCENE_ROT" }, - { 64, 2, 2, "EDIT_MOT_SMOOTH_LEN" }, // AC500 - { 65, 1, 1, "PV_BRANCH_MODE" }, // AC510 - { 66, 2, 2, "DATA_CAMERA_START" }, - { 67, 1, 1, "MOVIE_PLAY" }, - { 68, 1, 1, "MOVIE_DISP" }, - { 69, 3, 3, "WIND" }, - { 70, 3, 3, "OSAGE_STEP" }, - { 71, 3, 3, "OSAGE_MV_CCL" }, - { 72, 2, 2, "CHARA_COLOR" }, - { 73, 1, 1, "SE_EFFECT" }, - { 74, 9, 9, "EDIT_MOVE_XYZ" }, - { 75, 3, 3, "EDIT_EYELID_ANIM" }, - { 76, 2, 2, "EDIT_INSTRUMENT_ITEM" }, - { 77, 4, 4, "EDIT_MOTION_LOOP" }, - { 78, 2, 2, "EDIT_EXPRESSION" }, - { 79, 3, 3, "EDIT_EYE_ANIM" }, - { 80, 2, 2, "EDIT_MOUTH_ANIM" }, - { 81, 24, 24, "EDIT_CAMERA" }, - { 82, 1, 1, "EDIT_MODE_SELECT" }, - { 83, 2, 2, "PV_END_FADEOUT" }, - { 84, 1, 1, "TARGET_FLAG" }, - { 85, 3, 3, "ITEM_ANIM_ATTACH" }, - { 86, 1, 1, "SHADOW_RANGE" }, - { 87, 3, 3, "HAND_SCALE" }, // AFT101 - { 88, 4, 4, "LIGHT_POS" }, - { 89, 1, 1, "FACE_TYPE" }, // AFT200 - { 90, 2, 2, "SHADOW_CAST" }, // AFT300 - { 91, 6, 6, "EDIT_MOTION_F" }, // AFT310 - { 92, 3, 3, "FOG" }, // AFT410 - { 93, 2, 2, "BLOOM" }, - { 94, 3, 3, "COLOR_COLLE" }, - { 95, 3, 3, "DOF" }, - { 96, 4, 4, "CHARA_ALPHA" }, - { 97, 1, 1, "AOTO_CAP" }, - { 98, 1, 1, "MAN_CAP" }, - { 99, 3, 3, "TOON" }, - { 100, 3, 3, "SHIMMER" }, - { 101, 4, 4, "ITEM_ALPHA" }, - { 102, 1, 1, "MOVIE_CUT_CHG" }, - { 103, 3, 3, "CHARA_LIGHT" }, - { 104, 3, 3, "STAGE_LIGHT" }, - { 105, 8, 8, "AGEAGE_CTR" }, // AFT701 - { 106, 2, 2, "PSE" }, // FT + { 0, 0, 0, u8"END" }, + { 1, 1, 1, u8"TIME" }, + { 2, 3, 4, u8"MIKU_MOVE" }, + { 3, 1, 2, u8"MIKU_ROT" }, + { 4, 1, 2, u8"MIKU_DISP" }, + { 5, 1, 2, u8"MIKU_SHADOW" }, + { 6, 7, 7, u8"TARGET" }, + { 7, 3, 4, u8"SET_MOTION" }, + { 8, 1, 2, u8"SET_PLAYDATA" }, + { 9, 5, 6, u8"EFFECT" }, + { 10, 2, 2, u8"FADEIN_FIELD" }, + { 11, 1, 1, u8"EFFECT_OFF" }, + { 12, 6, 6, u8"SET_CAMERA" }, + { 13, 2, 2, u8"DATA_CAMERA" }, + { 14, 1, 1, u8"CHANGE_FIELD" }, + { 15, 1, 1, u8"HIDE_FIELD" }, + { 16, 3, 3, u8"MOVE_FIELD" }, + { 17, 2, 2, u8"FADEOUT_FIELD" }, + { 18, 2, 3, u8"EYE_ANIM" }, + { 19, 3, 5, u8"MOUTH_ANIM" }, + { 20, 4, 5, u8"HAND_ANIM" }, + { 21, 3, 4, u8"LOOK_ANIM" }, + { 22, 3, 4, u8"EXPRESSION" }, + { 23, 4, 5, u8"LOOK_CAMERA" }, + { 24, 1, 2, u8"LYRIC" }, + { 25, 0, 0, u8"MUSIC_PLAY" }, + { 26, 1, 2, u8"MODE_SELECT" }, + { 27, 2, 4, u8"EDIT_MOTION" }, + { 28, 2, 2, u8"BAR_TIME_SET" }, + { 29, 1, 2, u8"SHADOWHEIGHT" }, + { 30, 2, 1, u8"EDIT_FACE" }, + { 31, 19, 21, u8"MOVE_CAMERA" }, + { 32, 0, 0, u8"PV_END" }, + { 33, 2, 3, u8"SHADOWPOS" }, + { 34, 2, 2, u8"EDIT_LYRIC" }, + { 35, 5, 5, u8"EDIT_TARGET" }, + { 36, 1, 1, u8"EDIT_MOUTH" }, + { 37, 1, 1, u8"SET_CHARA" }, + { 38, 7, 7, u8"EDIT_MOVE" }, + { 39, 1, 1, u8"EDIT_SHADOW" }, + { 40, 1, 1, u8"EDIT_EYELID" }, + { 41, 2, 2, u8"EDIT_EYE" }, + { 42, 1, 1, u8"EDIT_ITEM" }, + { 43, 2, 2, u8"EDIT_EFFECT" }, + { 44, 1, 1, u8"EDIT_DISP" }, + { 45, 2, 2, u8"EDIT_HAND_ANIM" }, + { 46, 3, 3, u8"AIM" }, + { 47, 3, 3, u8"HAND_ITEM" }, + { 48, 1, 1, u8"EDIT_BLUSH" }, + { 49, 2, 2, u8"NEAR_CLIP" }, + { 50, 1, 2, u8"CLOTH_WET" }, + { 51, 3, 3, u8"LIGHT_ROT" }, + { 52, 6, 6, u8"SCENE_FADE" }, + { 53, 6, 6, u8"TONE_TRANS" }, + { 54, 1, 1, u8"SATURATE" }, + { 55, 1, 1, u8"FADE_MODE" }, + { 56, 2, 2, u8"AUTO_BLINK" }, + { 57, 3, 3, u8"PARTS_DISP" }, + { 58, 1, 1, u8"TARGET_FLYING_TIME" }, // AC210 + { 59, 2, 2, u8"CHARA_SIZE" }, + { 60, 2, 2, u8"CHARA_HEIGHT_ADJUST" }, + { 61, 4, 4, u8"ITEM_ANIM" }, + { 62, 4, 4, u8"CHARA_POS_ADJUST" }, + { 63, 1, 1, u8"SCENE_ROT" }, + { 64, 2, 2, u8"EDIT_MOT_SMOOTH_LEN" }, // AC500 + { 65, 1, 1, u8"PV_BRANCH_MODE" }, // AC510 + { 66, 2, 2, u8"DATA_CAMERA_START" }, + { 67, 1, 1, u8"MOVIE_PLAY" }, + { 68, 1, 1, u8"MOVIE_DISP" }, + { 69, 3, 3, u8"WIND" }, + { 70, 3, 3, u8"OSAGE_STEP" }, + { 71, 3, 3, u8"OSAGE_MV_CCL" }, + { 72, 2, 2, u8"CHARA_COLOR" }, + { 73, 1, 1, u8"SE_EFFECT" }, + { 74, 9, 9, u8"EDIT_MOVE_XYZ" }, + { 75, 3, 3, u8"EDIT_EYELID_ANIM" }, + { 76, 2, 2, u8"EDIT_INSTRUMENT_ITEM" }, + { 77, 4, 4, u8"EDIT_MOTION_LOOP" }, + { 78, 2, 2, u8"EDIT_EXPRESSION" }, + { 79, 3, 3, u8"EDIT_EYE_ANIM" }, + { 80, 2, 2, u8"EDIT_MOUTH_ANIM" }, + { 81, 24, 24, u8"EDIT_CAMERA" }, + { 82, 1, 1, u8"EDIT_MODE_SELECT" }, + { 83, 2, 2, u8"PV_END_FADEOUT" }, + { 84, 1, 1, u8"TARGET_FLAG" }, + { 85, 3, 3, u8"ITEM_ANIM_ATTACH" }, + { 86, 1, 1, u8"SHADOW_RANGE" }, + { 87, 3, 3, u8"HAND_SCALE" }, // AFT101 + { 88, 4, 4, u8"LIGHT_POS" }, + { 89, 1, 1, u8"FACE_TYPE" }, // AFT200 + { 90, 2, 2, u8"SHADOW_CAST" }, // AFT300 + { 91, 6, 6, u8"EDIT_MOTION_F" }, // AFT310 + { 92, 3, 3, u8"FOG" }, // AFT410 + { 93, 2, 2, u8"BLOOM" }, + { 94, 3, 3, u8"COLOR_COLLE" }, + { 95, 3, 3, u8"DOF" }, + { 96, 4, 4, u8"CHARA_ALPHA" }, + { 97, 1, 1, u8"AOTO_CAP" }, + { 98, 1, 1, u8"MAN_CAP" }, + { 99, 3, 3, u8"TOON" }, + { 100, 3, 3, u8"SHIMMER" }, + { 101, 4, 4, u8"ITEM_ALPHA" }, + { 102, 1, 1, u8"MOVIE_CUT_CHG" }, + { 103, 3, 3, u8"CHARA_LIGHT" }, + { 104, 3, 3, u8"STAGE_LIGHT" }, + { 105, 8, 8, u8"AGEAGE_CTR" }, // AFT701 + { 106, 2, 2, u8"PSE" }, // FT }; static const dsc_func_ac dsc_f_func[] = { - { 0, 0, 0, "END" }, - { 1, 1, 1, "TIME" }, - { 2, 3, 4, "MIKU_MOVE" }, - { 3, 1, 2, "MIKU_ROT" }, - { 4, 1, 2, "MIKU_DISP" }, - { 5, 1, 2, "MIKU_SHADOW" }, - { 6, 7, 11, "TARGET" }, - { 7, 3, 4, "SET_MOTION" }, - { 8, 1, 2, "SET_PLAYDATA" }, - { 9, 5, 6, "EFFECT" }, - { 10, 2, 2, "FADEIN_FIELD" }, - { 11, 1, 1, "EFFECT_OFF" }, - { 12, 6, 6, "SET_CAMERA" }, - { 13, 2, 2, "DATA_CAMERA" }, - { 14, 1, 1, "CHANGE_FIELD" }, - { 15, 1, 1, "HIDE_FIELD" }, - { 16, 3, 3, "MOVE_FIELD" }, - { 17, 2, 2, "FADEOUT_FIELD" }, - { 18, 2, 3, "EYE_ANIM" }, - { 19, 3, 5, "MOUTH_ANIM" }, - { 20, 4, 5, "HAND_ANIM" }, - { 21, 3, 4, "LOOK_ANIM" }, - { 22, 3, 4, "EXPRESSION" }, - { 23, 4, 5, "LOOK_CAMERA" }, - { 24, 1, 2, "LYRIC" }, - { 25, 0, 0, "MUSIC_PLAY" }, - { 26, 1, 2, "MODE_SELECT" }, - { 27, 2, 4, "EDIT_MOTION" }, - { 28, 2, 2, "BAR_TIME_SET" }, - { 29, 1, 2, "SHADOWHEIGHT" }, - { 30, 2, 1, "EDIT_FACE" }, - { 31, 19, 21, "MOVE_CAMERA" }, - { 32, 0, 0, "PV_END" }, - { 33, 2, 3, "SHADOWPOS" }, - { 34, 2, 2, "EDIT_LYRIC" }, - { 35, 5, 5, "EDIT_TARGET" }, - { 36, 1, 1, "EDIT_MOUTH" }, - { 37, 1, 1, "SET_CHARA" }, - { 38, 7, 7, "EDIT_MOVE" }, - { 39, 1, 1, "EDIT_SHADOW" }, - { 40, 1, 1, "EDIT_EYELID" }, - { 41, 2, 2, "EDIT_EYE" }, - { 42, 1, 1, "EDIT_ITEM" }, - { 43, 2, 2, "EDIT_EFFECT" }, - { 44, 1, 1, "EDIT_DISP" }, - { 45, 2, 2, "EDIT_HAND_ANIM" }, - { 46, 3, 3, "AIM" }, - { 47, 3, 3, "HAND_ITEM" }, - { 48, 1, 1, "EDIT_BLUSH" }, - { 49, 2, 2, "NEAR_CLIP" }, // DT 2nd - { 50, 1, 2, "CLOTH_WET" }, - { 51, 3, 3, "LIGHT_ROT" }, - { 52, 6, 6, "SCENE_FADE" }, - { 53, 6, 6, "TONE_TRANS" }, - { 54, 1, 1, "SATURATE" }, - { 55, 1, 1, "FADE_MODE" }, - { 56, 2, 2, "AUTO_BLINK" }, - { 57, 3, 3, "PARTS_DISP" }, - { 58, 1, 1, "TARGET_FLYING_TIME" }, - { 59, 2, 2, "CHARA_SIZE" }, - { 60, 2, 2, "CHARA_HEIGHT_ADJUST" }, - { 61, 4, 4, "ITEM_ANIM" }, - { 62, 4, 4, "CHARA_POS_ADJUST" }, - { 63, 1, 1, "SCENE_ROT" }, - { 64, 2, 2, "EDIT_MOT_SMOOTH_LEN" }, // F - { 65, 1, 1, "PV_BRANCH_MODE" }, - { 66, 2, 2, "DATA_CAMERA_START" }, - { 67, 1, 1, "MOVIE_PLAY" }, - { 68, 1, 1, "MOVIE_DISP" }, - { 69, 3, 3, "WIND" }, - { 70, 3, 3, "OSAGE_STEP" }, - { 71, 3, 3, "OSAGE_MV_CCL" }, - { 72, 2, 2, "CHARA_COLOR" }, - { 73, 1, 1, "SE_EFFECT" }, - { 74, 9, 9, "EDIT_MOVE_XYZ" }, - { 75, 3, 3, "EDIT_EYELID_ANIM" }, - { 76, 2, 2, "EDIT_INSTRUMENT_ITEM" }, - { 77, 4, 4, "EDIT_MOTION_LOOP" }, - { 78, 2, 2, "EDIT_EXPRESSION" }, - { 79, 3, 3, "EDIT_EYE_ANIM" }, - { 80, 2, 2, "EDIT_MOUTH_ANIM" }, - { 81, 24, 24, "EDIT_CAMERA" }, - { 82, 1, 1, "EDIT_MODE_SELECT" }, - { 83, 2, 2, "PV_END_FADEOUT" }, + { 0, 0, 0, u8"END" }, + { 1, 1, 1, u8"TIME" }, + { 2, 3, 4, u8"MIKU_MOVE" }, + { 3, 1, 2, u8"MIKU_ROT" }, + { 4, 1, 2, u8"MIKU_DISP" }, + { 5, 1, 2, u8"MIKU_SHADOW" }, + { 6, 7, 11, u8"TARGET" }, + { 7, 3, 4, u8"SET_MOTION" }, + { 8, 1, 2, u8"SET_PLAYDATA" }, + { 9, 5, 6, u8"EFFECT" }, + { 10, 2, 2, u8"FADEIN_FIELD" }, + { 11, 1, 1, u8"EFFECT_OFF" }, + { 12, 6, 6, u8"SET_CAMERA" }, + { 13, 2, 2, u8"DATA_CAMERA" }, + { 14, 1, 1, u8"CHANGE_FIELD" }, + { 15, 1, 1, u8"HIDE_FIELD" }, + { 16, 3, 3, u8"MOVE_FIELD" }, + { 17, 2, 2, u8"FADEOUT_FIELD" }, + { 18, 2, 3, u8"EYE_ANIM" }, + { 19, 3, 5, u8"MOUTH_ANIM" }, + { 20, 4, 5, u8"HAND_ANIM" }, + { 21, 3, 4, u8"LOOK_ANIM" }, + { 22, 3, 4, u8"EXPRESSION" }, + { 23, 4, 5, u8"LOOK_CAMERA" }, + { 24, 1, 2, u8"LYRIC" }, + { 25, 0, 0, u8"MUSIC_PLAY" }, + { 26, 1, 2, u8"MODE_SELECT" }, + { 27, 2, 4, u8"EDIT_MOTION" }, + { 28, 2, 2, u8"BAR_TIME_SET" }, + { 29, 1, 2, u8"SHADOWHEIGHT" }, + { 30, 2, 1, u8"EDIT_FACE" }, + { 31, 19, 21, u8"MOVE_CAMERA" }, + { 32, 0, 0, u8"PV_END" }, + { 33, 2, 3, u8"SHADOWPOS" }, + { 34, 2, 2, u8"EDIT_LYRIC" }, + { 35, 5, 5, u8"EDIT_TARGET" }, + { 36, 1, 1, u8"EDIT_MOUTH" }, + { 37, 1, 1, u8"SET_CHARA" }, + { 38, 7, 7, u8"EDIT_MOVE" }, + { 39, 1, 1, u8"EDIT_SHADOW" }, + { 40, 1, 1, u8"EDIT_EYELID" }, + { 41, 2, 2, u8"EDIT_EYE" }, + { 42, 1, 1, u8"EDIT_ITEM" }, + { 43, 2, 2, u8"EDIT_EFFECT" }, + { 44, 1, 1, u8"EDIT_DISP" }, + { 45, 2, 2, u8"EDIT_HAND_ANIM" }, + { 46, 3, 3, u8"AIM" }, + { 47, 3, 3, u8"HAND_ITEM" }, + { 48, 1, 1, u8"EDIT_BLUSH" }, + { 49, 2, 2, u8"NEAR_CLIP" }, // DT 2nd + { 50, 1, 2, u8"CLOTH_WET" }, + { 51, 3, 3, u8"LIGHT_ROT" }, + { 52, 6, 6, u8"SCENE_FADE" }, + { 53, 6, 6, u8"TONE_TRANS" }, + { 54, 1, 1, u8"SATURATE" }, + { 55, 1, 1, u8"FADE_MODE" }, + { 56, 2, 2, u8"AUTO_BLINK" }, + { 57, 3, 3, u8"PARTS_DISP" }, + { 58, 1, 1, u8"TARGET_FLYING_TIME" }, + { 59, 2, 2, u8"CHARA_SIZE" }, + { 60, 2, 2, u8"CHARA_HEIGHT_ADJUST" }, + { 61, 4, 4, u8"ITEM_ANIM" }, + { 62, 4, 4, u8"CHARA_POS_ADJUST" }, + { 63, 1, 1, u8"SCENE_ROT" }, + { 64, 2, 2, u8"EDIT_MOT_SMOOTH_LEN" }, // F + { 65, 1, 1, u8"PV_BRANCH_MODE" }, + { 66, 2, 2, u8"DATA_CAMERA_START" }, + { 67, 1, 1, u8"MOVIE_PLAY" }, + { 68, 1, 1, u8"MOVIE_DISP" }, + { 69, 3, 3, u8"WIND" }, + { 70, 3, 3, u8"OSAGE_STEP" }, + { 71, 3, 3, u8"OSAGE_MV_CCL" }, + { 72, 2, 2, u8"CHARA_COLOR" }, + { 73, 1, 1, u8"SE_EFFECT" }, + { 74, 9, 9, u8"EDIT_MOVE_XYZ" }, + { 75, 3, 3, u8"EDIT_EYELID_ANIM" }, + { 76, 2, 2, u8"EDIT_INSTRUMENT_ITEM" }, + { 77, 4, 4, u8"EDIT_MOTION_LOOP" }, + { 78, 2, 2, u8"EDIT_EXPRESSION" }, + { 79, 3, 3, u8"EDIT_EYE_ANIM" }, + { 80, 2, 2, u8"EDIT_MOUTH_ANIM" }, + { 81, 24, 24, u8"EDIT_CAMERA" }, + { 82, 1, 1, u8"EDIT_MODE_SELECT" }, + { 83, 2, 2, u8"PV_END_FADEOUT" }, }; static const dsc_func dsc_f2_func[] = { - { 0, 0, "END" }, - { 1, 1, "TIME" }, - { 2, 4, "MIKU_MOVE" }, - { 3, 2, "MIKU_ROT" }, - { 4, 2, "MIKU_DISP" }, - { 5, 2, "MIKU_SHADOW" }, - { 6, 12, "TARGET" }, - { 7, 4, "SET_MOTION" }, - { 8, 2, "SET_PLAYDATA" }, - { 9, 6, "EFFECT" }, - { 10, 2, "FADEIN_FIELD" }, - { 11, 1, "EFFECT_OFF" }, - { 12, 6, "SET_CAMERA" }, - { 13, 2, "DATA_CAMERA" }, - { 14, 2, "CHANGE_FIELD" }, - { 15, 1, "HIDE_FIELD" }, - { 16, 3, "MOVE_FIELD" }, - { 17, 2, "FADEOUT_FIELD" }, - { 18, 3, "EYE_ANIM" }, - { 19, 5, "MOUTH_ANIM" }, - { 20, 5, "HAND_ANIM" }, - { 21, 4, "LOOK_ANIM" }, - { 22, 4, "EXPRESSION" }, - { 23, 5, "LOOK_CAMERA" }, - { 24, 2, "LYRIC" }, - { 25, 0, "MUSIC_PLAY" }, - { 26, 2, "MODE_SELECT" }, - { 27, 4, "EDIT_MOTION" }, - { 28, 2, "BAR_TIME_SET" }, - { 29, 2, "SHADOWHEIGHT" }, - { 30, 1, "EDIT_FACE" }, - { 31, 21, "MOVE_CAMERA" }, - { 32, 0, "PV_END" }, - { 33, 3, "SHADOWPOS" }, - { 34, 2, "EDIT_LYRIC" }, - { 35, 5, "EDIT_TARGET" }, - { 36, 1, "EDIT_MOUTH" }, - { 37, 1, "SET_CHARA" }, - { 38, 7, "EDIT_MOVE" }, - { 39, 1, "EDIT_SHADOW" }, - { 40, 1, "EDIT_EYELID" }, - { 41, 2, "EDIT_EYE" }, - { 42, 1, "EDIT_ITEM" }, - { 43, 2, "EDIT_EFFECT" }, - { 44, 1, "EDIT_DISP" }, - { 45, 2, "EDIT_HAND_ANIM" }, - { 46, 3, "AIM" }, - { 47, 3, "HAND_ITEM" }, - { 48, 1, "EDIT_BLUSH" }, - { 49, 2, "NEAR_CLIP" }, - { 50, 2, "CLOTH_WET" }, - { 51, 3, "LIGHT_ROT" }, - { 52, 6, "SCENE_FADE" }, - { 53, 6, "TONE_TRANS" }, - { 54, 1, "SATURATE" }, - { 55, 1, "FADE_MODE" }, - { 56, 2, "AUTO_BLINK" }, - { 57, 3, "PARTS_DISP" }, - { 58, 1, "TARGET_FLYING_TIME" }, - { 59, 2, "CHARA_SIZE" }, - { 60, 2, "CHARA_HEIGHT_ADJUST" }, - { 61, 4, "ITEM_ANIM" }, - { 62, 4, "CHARA_POS_ADJUST" }, - { 63, 1, "SCENE_ROT" }, - { 64, 2, "EDIT_MOT_SMOOTH_LEN" }, - { 65, 1, "PV_BRANCH_MODE" }, - { 66, 2, "DATA_CAMERA_START" }, - { 67, 1, "MOVIE_PLAY" }, - { 68, 1, "MOVIE_DISP" }, - { 69, 3, "WIND" }, - { 70, 3, "OSAGE_STEP" }, - { 71, 3, "OSAGE_MV_CCL" }, - { 72, 2, "CHARA_COLOR" }, - { 73, 1, "SE_EFFECT" }, - { 74, 9, "EDIT_MOVE_XYZ" }, - { 75, 3, "EDIT_EYELID_ANIM" }, - { 76, 2, "EDIT_INSTRUMENT_ITEM" }, - { 77, 4, "EDIT_MOTION_LOOP" }, - { 78, 2, "EDIT_EXPRESSION" }, - { 79, 3, "EDIT_EYE_ANIM" }, - { 80, 2, "EDIT_MOUTH_ANIM" }, - { 81, 22, "EDIT_CAMERA" }, - { 82, 1, "EDIT_MODE_SELECT" }, - { 83, 2, "PV_END_FADEOUT" }, - { 84, 1, "RESERVE" }, - { 85, 6, "RESERVE" }, - { 86, 1, "RESERVE" }, - { 87, 9, "RESERVE" }, - { 88, 2, "PV_AUTH_LIGHT_PRIORITY" }, - { 89, 3, "PV_CHARA_LIGHT" }, - { 90, 3, "PV_STAGE_LIGHT" }, - { 91, 11, "TARGET_EFFECT" }, - { 92, 3, "FOG" }, - { 93, 2, "BLOOM" }, - { 94, 3, "COLOR_CORRECTION" }, - { 95, 3, "DOF" }, - { 96, 4, "CHARA_ALPHA" }, - { 97, 1, "AUTO_CAPTURE_BEGIN" }, - { 98, 1, "MANUAL_CAPTURE" }, - { 99, 3, "TOON_EDGE" }, - { 100, 3, "SHIMMER" }, - { 101, 4, "ITEM_ALPHA" }, - { 102, 1, "MOVIE_CUT" }, - { 103, 112, "EDIT_CAMERA_BOX" }, - { 104, 1, "EDIT_STAGE_PARAM" }, - { 105, 1, "EDIT_CHANGE_FIELD" }, - { 106, 7, "MIKUDAYO_ADJUST" }, - { 107, 2, "LYRIC_2" }, // US/EU - { 108, 2, "LYRIC_READ" }, - { 109, 2, "LYRIC_READ_2" }, - { 110, 5, "ANNOTATION" }, + { 0, 0, u8"END" }, + { 1, 1, u8"TIME" }, + { 2, 4, u8"MIKU_MOVE" }, + { 3, 2, u8"MIKU_ROT" }, + { 4, 2, u8"MIKU_DISP" }, + { 5, 2, u8"MIKU_SHADOW" }, + { 6, 12, u8"TARGET" }, + { 7, 4, u8"SET_MOTION" }, + { 8, 2, u8"SET_PLAYDATA" }, + { 9, 6, u8"EFFECT" }, + { 10, 2, u8"FADEIN_FIELD" }, + { 11, 1, u8"EFFECT_OFF" }, + { 12, 6, u8"SET_CAMERA" }, + { 13, 2, u8"DATA_CAMERA" }, + { 14, 2, u8"CHANGE_FIELD" }, + { 15, 1, u8"HIDE_FIELD" }, + { 16, 3, u8"MOVE_FIELD" }, + { 17, 2, u8"FADEOUT_FIELD" }, + { 18, 3, u8"EYE_ANIM" }, + { 19, 5, u8"MOUTH_ANIM" }, + { 20, 5, u8"HAND_ANIM" }, + { 21, 4, u8"LOOK_ANIM" }, + { 22, 4, u8"EXPRESSION" }, + { 23, 5, u8"LOOK_CAMERA" }, + { 24, 2, u8"LYRIC" }, + { 25, 0, u8"MUSIC_PLAY" }, + { 26, 2, u8"MODE_SELECT" }, + { 27, 4, u8"EDIT_MOTION" }, + { 28, 2, u8"BAR_TIME_SET" }, + { 29, 2, u8"SHADOWHEIGHT" }, + { 30, 1, u8"EDIT_FACE" }, + { 31, 21, u8"MOVE_CAMERA" }, + { 32, 0, u8"PV_END" }, + { 33, 3, u8"SHADOWPOS" }, + { 34, 2, u8"EDIT_LYRIC" }, + { 35, 5, u8"EDIT_TARGET" }, + { 36, 1, u8"EDIT_MOUTH" }, + { 37, 1, u8"SET_CHARA" }, + { 38, 7, u8"EDIT_MOVE" }, + { 39, 1, u8"EDIT_SHADOW" }, + { 40, 1, u8"EDIT_EYELID" }, + { 41, 2, u8"EDIT_EYE" }, + { 42, 1, u8"EDIT_ITEM" }, + { 43, 2, u8"EDIT_EFFECT" }, + { 44, 1, u8"EDIT_DISP" }, + { 45, 2, u8"EDIT_HAND_ANIM" }, + { 46, 3, u8"AIM" }, + { 47, 3, u8"HAND_ITEM" }, + { 48, 1, u8"EDIT_BLUSH" }, + { 49, 2, u8"NEAR_CLIP" }, + { 50, 2, u8"CLOTH_WET" }, + { 51, 3, u8"LIGHT_ROT" }, + { 52, 6, u8"SCENE_FADE" }, + { 53, 6, u8"TONE_TRANS" }, + { 54, 1, u8"SATURATE" }, + { 55, 1, u8"FADE_MODE" }, + { 56, 2, u8"AUTO_BLINK" }, + { 57, 3, u8"PARTS_DISP" }, + { 58, 1, u8"TARGET_FLYING_TIME" }, + { 59, 2, u8"CHARA_SIZE" }, + { 60, 2, u8"CHARA_HEIGHT_ADJUST" }, + { 61, 4, u8"ITEM_ANIM" }, + { 62, 4, u8"CHARA_POS_ADJUST" }, + { 63, 1, u8"SCENE_ROT" }, + { 64, 2, u8"EDIT_MOT_SMOOTH_LEN" }, + { 65, 1, u8"PV_BRANCH_MODE" }, + { 66, 2, u8"DATA_CAMERA_START" }, + { 67, 1, u8"MOVIE_PLAY" }, + { 68, 1, u8"MOVIE_DISP" }, + { 69, 3, u8"WIND" }, + { 70, 3, u8"OSAGE_STEP" }, + { 71, 3, u8"OSAGE_MV_CCL" }, + { 72, 2, u8"CHARA_COLOR" }, + { 73, 1, u8"SE_EFFECT" }, + { 74, 9, u8"EDIT_MOVE_XYZ" }, + { 75, 3, u8"EDIT_EYELID_ANIM" }, + { 76, 2, u8"EDIT_INSTRUMENT_ITEM" }, + { 77, 4, u8"EDIT_MOTION_LOOP" }, + { 78, 2, u8"EDIT_EXPRESSION" }, + { 79, 3, u8"EDIT_EYE_ANIM" }, + { 80, 2, u8"EDIT_MOUTH_ANIM" }, + { 81, 22, u8"EDIT_CAMERA" }, + { 82, 1, u8"EDIT_MODE_SELECT" }, + { 83, 2, u8"PV_END_FADEOUT" }, + { 84, 1, u8"RESERVE" }, + { 85, 6, u8"RESERVE" }, + { 86, 1, u8"RESERVE" }, + { 87, 9, u8"RESERVE" }, + { 88, 2, u8"PV_AUTH_LIGHT_PRIORITY" }, + { 89, 3, u8"PV_CHARA_LIGHT" }, + { 90, 3, u8"PV_STAGE_LIGHT" }, + { 91, 11, u8"TARGET_EFFECT" }, + { 92, 3, u8"FOG" }, + { 93, 2, u8"BLOOM" }, + { 94, 3, u8"COLOR_CORRECTION" }, + { 95, 3, u8"DOF" }, + { 96, 4, u8"CHARA_ALPHA" }, + { 97, 1, u8"AUTO_CAPTURE_BEGIN" }, + { 98, 1, u8"MANUAL_CAPTURE" }, + { 99, 3, u8"TOON_EDGE" }, + { 100, 3, u8"SHIMMER" }, + { 101, 4, u8"ITEM_ALPHA" }, + { 102, 1, u8"MOVIE_CUT" }, + { 103, 112, u8"EDIT_CAMERA_BOX" }, + { 104, 1, u8"EDIT_STAGE_PARAM" }, + { 105, 1, u8"EDIT_CHANGE_FIELD" }, + { 106, 7, u8"MIKUDAYO_ADJUST" }, + { 107, 2, u8"LYRIC_2" }, // US/EU + { 108, 2, u8"LYRIC_READ" }, + { 109, 2, u8"LYRIC_READ_2" }, + { 110, 5, u8"ANNOTATION" }, }; static const dsc_func dsc_mgf_func[] = { - { 0, 0, "END" }, - { 1, 1, "TIME" }, - { 2, 4, "MIKU_MOVE" }, - { 3, 2, "MIKU_ROT" }, - { 4, 2, "MIKU_DISP" }, - { 5, 2, "MIKU_SHADOW" }, - { 6, 12, "TARGET" }, - { 7, 4, "SET_MOTION" }, - { 8, 2, "SET_PLAYDATA" }, - { 9, 6, "EFFECT" }, - { 10, 2, "FADEIN_FIELD" }, - { 11, 1, "EFFECT_OFF" }, - { 12, 6, "SET_CAMERA" }, - { 13, 2, "DATA_CAMERA" }, - { 14, 2, "CHANGE_FIELD" }, - { 15, 1, "HIDE_FIELD" }, - { 16, 3, "MOVE_FIELD" }, - { 17, 2, "FADEOUT_FIELD" }, - { 18, 3, "EYE_ANIM" }, - { 19, 5, "MOUTH_ANIM" }, - { 20, 5, "HAND_ANIM" }, - { 21, 4, "LOOK_ANIM" }, - { 22, 4, "EXPRESSION" }, - { 23, 5, "LOOK_CAMERA" }, - { 24, 2, "LYRIC" }, - { 25, 0, "MUSIC_PLAY" }, - { 26, 2, "MODE_SELECT" }, - { 27, 4, "EDIT_MOTION" }, - { 28, 2, "BAR_TIME_SET" }, - { 29, 2, "SHADOWHEIGHT" }, - { 30, 1, "EDIT_FACE" }, - { 31, 21, "MOVE_CAMERA" }, - { 32, 0, "PV_END" }, - { 33, 3, "SHADOWPOS" }, - { 34, 2, "EDIT_LYRIC" }, - { 35, 5, "EDIT_TARGET" }, - { 36, 1, "EDIT_MOUTH" }, - { 37, 1, "SET_CHARA" }, - { 38, 7, "EDIT_MOVE" }, - { 39, 1, "EDIT_SHADOW" }, - { 40, 1, "EDIT_EYELID" }, - { 41, 2, "EDIT_EYE" }, - { 42, 1, "EDIT_ITEM" }, - { 43, 2, "EDIT_EFFECT" }, - { 44, 1, "EDIT_DISP" }, - { 45, 2, "EDIT_HAND_ANIM" }, - { 46, 3, "AIM" }, - { 47, 3, "HAND_ITEM" }, - { 48, 1, "EDIT_BLUSH" }, - { 49, 2, "NEAR_CLIP" }, - { 50, 2, "CLOTH_WET" }, - { 51, 3, "LIGHT_ROT" }, - { 52, 6, "SCENE_FADE" }, - { 53, 6, "TONE_TRANS" }, - { 54, 1, "SATURATE" }, - { 55, 1, "FADE_MODE" }, - { 56, 2, "AUTO_BLINK" }, - { 57, 3, "PARTS_DISP" }, - { 58, 1, "TARGET_FLYING_TIME" }, - { 59, 2, "CHARA_SIZE" }, - { 60, 2, "CHARA_HEIGHT_ADJUST" }, - { 61, 4, "ITEM_ANIM" }, - { 62, 4, "CHARA_POS_ADJUST" }, - { 63, 1, "SCENE_ROT" }, - { 64, 2, "EDIT_MOT_SMOOTH_LEN" }, - { 65, 1, "PV_BRANCH_MODE" }, - { 66, 2, "DATA_CAMERA_START" }, - { 67, 1, "MOVIE_PLAY" }, - { 68, 1, "MOVIE_DISP" }, - { 69, 3, "WIND" }, - { 70, 3, "OSAGE_STEP" }, - { 71, 3, "OSAGE_MV_CCL" }, - { 72, 2, "CHARA_COLOR" }, - { 73, 1, "SE_EFFECT" }, - { 74, 9, "EDIT_MOVE_XYZ" }, - { 75, 3, "EDIT_EYELID_ANIM" }, - { 76, 2, "EDIT_INSTRUMENT_ITEM" }, - { 77, 4, "EDIT_MOTION_LOOP" }, - { 78, 2, "EDIT_EXPRESSION" }, - { 79, 3, "EDIT_EYE_ANIM" }, - { 80, 2, "EDIT_MOUTH_ANIM" }, - { 81, 22, "EDIT_CAMERA" }, - { 82, 1, "EDIT_MODE_SELECT" }, - { 83, 2, "PV_END_FADEOUT" }, - { 84, 1, "RESERVE" }, - { 85, 6, "RESERVE" }, - { 86, 1, "RESERVE" }, - { 87, 9, "RESERVE" }, - { 88, 2, "PV_AUTH_LIGHT_PRIORITY" }, - { 89, 3, "PV_CHARA_LIGHT" }, - { 90, 3, "PV_STAGE_LIGHT" }, - { 91, 11, "TARGET_EFFECT" }, - { 92, 3, "FOG" }, - { 93, 2, "BLOOM" }, - { 94, 3, "COLOR_CORRECTION" }, - { 95, 3, "DOF" }, - { 96, 4, "CHARA_ALPHA" }, - { 97, 1, "AUTO_CAPTURE_BEGIN" }, - { 98, 1, "MANUAL_CAPTURE" }, - { 99, 3, "TOON_EDGE" }, - { 100, 3, "SHIMMER" }, - { 101, 4, "ITEM_ALPHA" }, - { 102, 1, "MOVIE_CUT" }, - { 103, 1, "CROSSFADE" }, - { 104, 1, "SUBFRAMERENDER" }, - { 105, 36, "EVENT_JUDGE" }, - { 106, 2, "TOON_EDGE" }, - { 107, 2, "FOG_ENABLE" }, - { 108, 112, "EDIT_CAMERA_BOX" }, - { 109, 1, "EDIT_STAGE_PARAM" }, - { 110, 1, "EDIT_CHANGE_FIELD" }, + { 0, 0, u8"END" }, + { 1, 1, u8"TIME" }, + { 2, 4, u8"MIKU_MOVE" }, + { 3, 2, u8"MIKU_ROT" }, + { 4, 2, u8"MIKU_DISP" }, + { 5, 2, u8"MIKU_SHADOW" }, + { 6, 12, u8"TARGET" }, + { 7, 4, u8"SET_MOTION" }, + { 8, 2, u8"SET_PLAYDATA" }, + { 9, 6, u8"EFFECT" }, + { 10, 2, u8"FADEIN_FIELD" }, + { 11, 1, u8"EFFECT_OFF" }, + { 12, 6, u8"SET_CAMERA" }, + { 13, 2, u8"DATA_CAMERA" }, + { 14, 2, u8"CHANGE_FIELD" }, + { 15, 1, u8"HIDE_FIELD" }, + { 16, 3, u8"MOVE_FIELD" }, + { 17, 2, u8"FADEOUT_FIELD" }, + { 18, 3, u8"EYE_ANIM" }, + { 19, 5, u8"MOUTH_ANIM" }, + { 20, 5, u8"HAND_ANIM" }, + { 21, 4, u8"LOOK_ANIM" }, + { 22, 4, u8"EXPRESSION" }, + { 23, 5, u8"LOOK_CAMERA" }, + { 24, 2, u8"LYRIC" }, + { 25, 0, u8"MUSIC_PLAY" }, + { 26, 2, u8"MODE_SELECT" }, + { 27, 4, u8"EDIT_MOTION" }, + { 28, 2, u8"BAR_TIME_SET" }, + { 29, 2, u8"SHADOWHEIGHT" }, + { 30, 1, u8"EDIT_FACE" }, + { 31, 21, u8"MOVE_CAMERA" }, + { 32, 0, u8"PV_END" }, + { 33, 3, u8"SHADOWPOS" }, + { 34, 2, u8"EDIT_LYRIC" }, + { 35, 5, u8"EDIT_TARGET" }, + { 36, 1, u8"EDIT_MOUTH" }, + { 37, 1, u8"SET_CHARA" }, + { 38, 7, u8"EDIT_MOVE" }, + { 39, 1, u8"EDIT_SHADOW" }, + { 40, 1, u8"EDIT_EYELID" }, + { 41, 2, u8"EDIT_EYE" }, + { 42, 1, u8"EDIT_ITEM" }, + { 43, 2, u8"EDIT_EFFECT" }, + { 44, 1, u8"EDIT_DISP" }, + { 45, 2, u8"EDIT_HAND_ANIM" }, + { 46, 3, u8"AIM" }, + { 47, 3, u8"HAND_ITEM" }, + { 48, 1, u8"EDIT_BLUSH" }, + { 49, 2, u8"NEAR_CLIP" }, + { 50, 2, u8"CLOTH_WET" }, + { 51, 3, u8"LIGHT_ROT" }, + { 52, 6, u8"SCENE_FADE" }, + { 53, 6, u8"TONE_TRANS" }, + { 54, 1, u8"SATURATE" }, + { 55, 1, u8"FADE_MODE" }, + { 56, 2, u8"AUTO_BLINK" }, + { 57, 3, u8"PARTS_DISP" }, + { 58, 1, u8"TARGET_FLYING_TIME" }, + { 59, 2, u8"CHARA_SIZE" }, + { 60, 2, u8"CHARA_HEIGHT_ADJUST" }, + { 61, 4, u8"ITEM_ANIM" }, + { 62, 4, u8"CHARA_POS_ADJUST" }, + { 63, 1, u8"SCENE_ROT" }, + { 64, 2, u8"EDIT_MOT_SMOOTH_LEN" }, + { 65, 1, u8"PV_BRANCH_MODE" }, + { 66, 2, u8"DATA_CAMERA_START" }, + { 67, 1, u8"MOVIE_PLAY" }, + { 68, 1, u8"MOVIE_DISP" }, + { 69, 3, u8"WIND" }, + { 70, 3, u8"OSAGE_STEP" }, + { 71, 3, u8"OSAGE_MV_CCL" }, + { 72, 2, u8"CHARA_COLOR" }, + { 73, 1, u8"SE_EFFECT" }, + { 74, 9, u8"EDIT_MOVE_XYZ" }, + { 75, 3, u8"EDIT_EYELID_ANIM" }, + { 76, 2, u8"EDIT_INSTRUMENT_ITEM" }, + { 77, 4, u8"EDIT_MOTION_LOOP" }, + { 78, 2, u8"EDIT_EXPRESSION" }, + { 79, 3, u8"EDIT_EYE_ANIM" }, + { 80, 2, u8"EDIT_MOUTH_ANIM" }, + { 81, 22, u8"EDIT_CAMERA" }, + { 82, 1, u8"EDIT_MODE_SELECT" }, + { 83, 2, u8"PV_END_FADEOUT" }, + { 84, 1, u8"RESERVE" }, + { 85, 6, u8"RESERVE" }, + { 86, 1, u8"RESERVE" }, + { 87, 9, u8"RESERVE" }, + { 88, 2, u8"PV_AUTH_LIGHT_PRIORITY" }, + { 89, 3, u8"PV_CHARA_LIGHT" }, + { 90, 3, u8"PV_STAGE_LIGHT" }, + { 91, 11, u8"TARGET_EFFECT" }, + { 92, 3, u8"FOG" }, + { 93, 2, u8"BLOOM" }, + { 94, 3, u8"COLOR_CORRECTION" }, + { 95, 3, u8"DOF" }, + { 96, 4, u8"CHARA_ALPHA" }, + { 97, 1, u8"AUTO_CAPTURE_BEGIN" }, + { 98, 1, u8"MANUAL_CAPTURE" }, + { 99, 3, u8"TOON_EDGE" }, + { 100, 3, u8"SHIMMER" }, + { 101, 4, u8"ITEM_ALPHA" }, + { 102, 1, u8"MOVIE_CUT" }, + { 103, 1, u8"CROSSFADE" }, + { 104, 1, u8"SUBFRAMERENDER" }, + { 105, 36, u8"EVENT_JUDGE" }, + { 106, 2, u8"TOON_EDGE" }, + { 107, 2, u8"FOG_ENABLE" }, + { 108, 112, u8"EDIT_CAMERA_BOX" }, + { 109, 1, u8"EDIT_STAGE_PARAM" }, + { 110, 1, u8"EDIT_CHANGE_FIELD" }, }; static const dsc_func dsc_x_func[] = { - { 0, 0, "END" }, - { 1, 1, "TIME" }, - { 2, 4, "MIKU_MOVE" }, - { 3, 2, "MIKU_ROT" }, - { 4, 2, "MIKU_DISP" }, - { 5, 2, "MIKU_SHADOW" }, - { 6, 12, "TARGET" }, - { 7, 4, "SET_MOTION" }, - { 8, 2, "SET_PLAYDATA" }, - { 9, 6, "EFFECT" }, - { 10, 2, "FADEIN_FIELD" }, - { 11, 1, "EFFECT_OFF" }, - { 12, 6, "SET_CAMERA" }, - { 13, 2, "DATA_CAMERA" }, - { 14, 2, "CHANGE_FIELD" }, - { 15, 1, "HIDE_FIELD" }, - { 16, 3, "MOVE_FIELD" }, - { 17, 2, "FADEOUT_FIELD" }, - { 18, 3, "EYE_ANIM" }, - { 19, 5, "MOUTH_ANIM" }, - { 20, 5, "HAND_ANIM" }, - { 21, 4, "LOOK_ANIM" }, - { 22, 4, "EXPRESSION" }, - { 23, 5, "LOOK_CAMERA" }, - { 24, 2, "LYRIC" }, - { 25, 0, "MUSIC_PLAY" }, - { 26, 2, "MODE_SELECT" }, - { 27, 4, "EDIT_MOTION" }, - { 28, 2, "BAR_TIME_SET" }, - { 29, 2, "SHADOWHEIGHT" }, - { 30, 1, "EDIT_FACE" }, - { 31, 21, "DUMMY" }, - { 32, 0, "PV_END" }, - { 33, 3, "SHADOWPOS" }, - { 34, 2, "EDIT_LYRIC" }, - { 35, 5, "EDIT_TARGET" }, - { 36, 1, "EDIT_MOUTH" }, - { 37, 1, "SET_CHARA" }, - { 38, 7, "EDIT_MOVE" }, - { 39, 1, "EDIT_SHADOW" }, - { 40, 1, "EDIT_EYELID" }, - { 41, 2, "EDIT_EYE" }, - { 42, 1, "EDIT_ITEM" }, - { 43, 2, "EDIT_EFFECT" }, - { 44, 1, "EDIT_DISP" }, - { 45, 2, "EDIT_HAND_ANIM" }, - { 46, 3, "AIM" }, - { 47, 3, "HAND_ITEM" }, - { 48, 1, "EDIT_BLUSH" }, - { 49, 2, "NEAR_CLIP" }, - { 50, 2, "CLOTH_WET" }, - { 51, 3, "LIGHT_ROT" }, - { 52, 6, "SCENE_FADE" }, - { 53, 6, "TONE_TRANS" }, - { 54, 1, "SATURATE" }, - { 55, 1, "FADE_MODE" }, - { 56, 2, "AUTO_BLINK" }, - { 57, 3, "PARTS_DISP" }, - { 58, 1, "TARGET_FLYING_TIME" }, - { 59, 2, "CHARA_SIZE" }, - { 60, 2, "CHARA_HEIGHT_ADJUST" }, - { 61, 4, "ITEM_ANIM" }, - { 62, 4, "CHARA_POS_ADJUST" }, - { 63, 1, "SCENE_ROT" }, - { 64, 2, "EDIT_MOT_SMOOTH_LEN" }, - { 65, 1, "PV_BRANCH_MODE" }, - { 66, 2, "DATA_CAMERA_START" }, - { 67, 1, "MOVIE_PLAY" }, - { 68, 1, "MOVIE_DISP" }, - { 69, 3, "WIND" }, - { 70, 3, "OSAGE_STEP" }, - { 71, 3, "OSAGE_MV_CCL" }, - { 72, 2, "CHARA_COLOR" }, - { 73, 1, "SE_EFFECT" }, - { 74, 2, "CHARA_SHADOW_QUALITY" }, - { 75, 2, "STAGE_SHADOW_QUALITY" }, - { 76, 2, "COMMON_LIGHT" }, - { 77, 2, "TONE_MAP" }, - { 78, 2, "IBL_COLOR" }, - { 79, 2, "REFLECTION" }, - { 80, 3, "CHROMATIC_ABERRATION" }, - { 81, 2, "STAGE_SHADOW" }, - { 82, 2, "REFLECTION_QUALITY" }, - { 83, 2, "PV_END_FADEOUT" }, - { 84, 1, "CREDIT_TITLE" }, - { 85, 1, "BAR_POINT" }, - { 86, 1, "BEAT_POINT" }, - { 87, 0, "RESERVE" }, - { 88, 2, "PV_AUTH_LIGHT_PRIORITY" }, - { 89, 3, "PV_CHARA_LIGHT" }, - { 90, 3, "PV_STAGE_LIGHT" }, - { 91, 11, "TARGET_EFFECT" }, - { 92, 3, "FOG" }, - { 93, 2, "BLOOM" }, - { 94, 3, "COLOR_CORRECTION" }, - { 95, 3, "DOF" }, - { 96, 4, "CHARA_ALPHA" }, - { 97, 1, "AUTO_CAPTURE_BEGIN" }, - { 98, 1, "MANUAL_CAPTURE" }, - { 99, 3, "TOON_EDGE" }, - { 100, 3, "SHIMMER" }, - { 101, 4, "ITEM_ALPHA" }, - { 102, 1, "MOVIE_CUT" }, - { 103, 112, "EDIT_CAMERA_BOX" }, - { 104, 1, "EDIT_STAGE_PARAM" }, - { 105, 1, "EDIT_CHANGE_FIELD" }, - { 106, 7, "MIKUDAYO_ADJUST" }, - { 107, 2, "LYRIC_2" }, - { 108, 2, "LYRIC_READ" }, - { 109, 2, "LYRIC_READ_2" }, - { 110, 5, "ANNOTATION" }, - { 111, 2, "STAGE_EFFECT" }, - { 112, 3, "SONG_EFFECT" }, - { 113, 3, "SONG_EFFECT_ATTACH" }, - { 114, 2, "LIGHT_AUTH" }, - { 115, 2, "FADE" }, - { 116, 2, "SET_STAGE_EFFECT_ENV" }, - { 117, 2, "RESERVE" }, - { 118, 2, "COMMON_EFFECT_AET_FRONT" }, - { 119, 2, "COMMON_EFFECT_AET_FRONT_LOW" }, - { 120, 2, "COMMON_EFFECT_PARTICLE" }, - { 121, 3, "SONG_EFFECT_ALPHA_SORT" }, - { 122, 5, "LOOK_CAMERA_FACE_LIMIT" }, - { 123, 3, "ITEM_LIGHT" }, - { 124, 3, "CHARA_EFFECT" }, - { 125, 2, "MARKER" }, - { 126, 3, "CHARA_EFFECT_CHARA_LIGHT" }, - { 127, 2, "ENABLE_COMMON_LIGHT_TO_CHARA" }, - { 128, 2, "ENABLE_FXAA" }, - { 129, 2, "ENABLE_TEMPORAL_AA" }, - { 130, 2, "ENABLE_REFLECTION" }, - { 131, 2, "BANK_BRANCH" }, - { 132, 2, "BANK_END" }, - { 133, 2, "" }, - { 134, 2, "" }, - { 135, 2, "" }, - { 136, 2, "" }, - { 137, 2, "" }, - { 138, 2, "" }, - { 139, 2, "" }, - { 140, 2, "" }, - { 141, 2, "VR_LIVE_MOVIE" }, - { 142, 2, "VR_CHEER" }, - { 143, 2, "VR_CHARA_PSMOVE" }, - { 144, 2, "VR_MOVE_PATH" }, - { 145, 2, "VR_SET_BASE" }, - { 146, 2, "VR_TECH_DEMO_EFFECT" }, - { 147, 2, "VR_TRANSFORM" }, - { 148, 2, "GAZE" }, - { 149, 2, "TECH_DEMO_GESUTRE" }, - { 150, 2, "VR_CHEMICAL_LIGHT_COLOR" }, - { 151, 5, "VR_LIVE_MOB" }, - { 152, 9, "VR_LIVE_HAIR_OSAGE" }, - { 153, 9, "VR_LIVE_LOOK_CAMERA" }, - { 154, 5, "VR_LIVE_CHEER" }, - { 155, 3, "VR_LIVE_GESTURE" }, - { 156, 7, "VR_LIVE_CLONE" }, - { 157, 7, "VR_LOOP_EFFECT" }, - { 158, 6, "VR_LIVE_ONESHOT_EFFECT" }, - { 159, 9, "VR_LIVE_PRESENT" }, - { 160, 5, "VR_LIVE_TRANSFORM" }, - { 161, 5, "VR_LIVE_FLY" }, - { 162, 2, "VR_LIVE_CHARA_VOICE" }, + { 0, 0, u8"END" }, + { 1, 1, u8"TIME" }, + { 2, 4, u8"MIKU_MOVE" }, + { 3, 2, u8"MIKU_ROT" }, + { 4, 2, u8"MIKU_DISP" }, + { 5, 2, u8"MIKU_SHADOW" }, + { 6, 12, u8"TARGET" }, + { 7, 4, u8"SET_MOTION" }, + { 8, 2, u8"SET_PLAYDATA" }, + { 9, 6, u8"EFFECT" }, + { 10, 2, u8"FADEIN_FIELD" }, + { 11, 1, u8"EFFECT_OFF" }, + { 12, 6, u8"SET_CAMERA" }, + { 13, 2, u8"DATA_CAMERA" }, + { 14, 2, u8"CHANGE_FIELD" }, + { 15, 1, u8"HIDE_FIELD" }, + { 16, 3, u8"MOVE_FIELD" }, + { 17, 2, u8"FADEOUT_FIELD" }, + { 18, 3, u8"EYE_ANIM" }, + { 19, 5, u8"MOUTH_ANIM" }, + { 20, 5, u8"HAND_ANIM" }, + { 21, 4, u8"LOOK_ANIM" }, + { 22, 4, u8"EXPRESSION" }, + { 23, 5, u8"LOOK_CAMERA" }, + { 24, 2, u8"LYRIC" }, + { 25, 0, u8"MUSIC_PLAY" }, + { 26, 2, u8"MODE_SELECT" }, + { 27, 4, u8"EDIT_MOTION" }, + { 28, 2, u8"BAR_TIME_SET" }, + { 29, 2, u8"SHADOWHEIGHT" }, + { 30, 1, u8"EDIT_FACE" }, + { 31, 21, u8"DUMMY" }, + { 32, 0, u8"PV_END" }, + { 33, 3, u8"SHADOWPOS" }, + { 34, 2, u8"EDIT_LYRIC" }, + { 35, 5, u8"EDIT_TARGET" }, + { 36, 1, u8"EDIT_MOUTH" }, + { 37, 1, u8"SET_CHARA" }, + { 38, 7, u8"EDIT_MOVE" }, + { 39, 1, u8"EDIT_SHADOW" }, + { 40, 1, u8"EDIT_EYELID" }, + { 41, 2, u8"EDIT_EYE" }, + { 42, 1, u8"EDIT_ITEM" }, + { 43, 2, u8"EDIT_EFFECT" }, + { 44, 1, u8"EDIT_DISP" }, + { 45, 2, u8"EDIT_HAND_ANIM" }, + { 46, 3, u8"AIM" }, + { 47, 3, u8"HAND_ITEM" }, + { 48, 1, u8"EDIT_BLUSH" }, + { 49, 2, u8"NEAR_CLIP" }, + { 50, 2, u8"CLOTH_WET" }, + { 51, 3, u8"LIGHT_ROT" }, + { 52, 6, u8"SCENE_FADE" }, + { 53, 6, u8"TONE_TRANS" }, + { 54, 1, u8"SATURATE" }, + { 55, 1, u8"FADE_MODE" }, + { 56, 2, u8"AUTO_BLINK" }, + { 57, 3, u8"PARTS_DISP" }, + { 58, 1, u8"TARGET_FLYING_TIME" }, + { 59, 2, u8"CHARA_SIZE" }, + { 60, 2, u8"CHARA_HEIGHT_ADJUST" }, + { 61, 4, u8"ITEM_ANIM" }, + { 62, 4, u8"CHARA_POS_ADJUST" }, + { 63, 1, u8"SCENE_ROT" }, + { 64, 2, u8"EDIT_MOT_SMOOTH_LEN" }, + { 65, 1, u8"PV_BRANCH_MODE" }, + { 66, 2, u8"DATA_CAMERA_START" }, + { 67, 1, u8"MOVIE_PLAY" }, + { 68, 1, u8"MOVIE_DISP" }, + { 69, 3, u8"WIND" }, + { 70, 3, u8"OSAGE_STEP" }, + { 71, 3, u8"OSAGE_MV_CCL" }, + { 72, 2, u8"CHARA_COLOR" }, + { 73, 1, u8"SE_EFFECT" }, + { 74, 2, u8"CHARA_SHADOW_QUALITY" }, + { 75, 2, u8"STAGE_SHADOW_QUALITY" }, + { 76, 2, u8"COMMON_LIGHT" }, + { 77, 2, u8"TONE_MAP" }, + { 78, 2, u8"IBL_COLOR" }, + { 79, 2, u8"REFLECTION" }, + { 80, 3, u8"CHROMATIC_ABERRATION" }, + { 81, 2, u8"STAGE_SHADOW" }, + { 82, 2, u8"REFLECTION_QUALITY" }, + { 83, 2, u8"PV_END_FADEOUT" }, + { 84, 1, u8"CREDIT_TITLE" }, + { 85, 1, u8"BAR_POINT" }, + { 86, 1, u8"BEAT_POINT" }, + { 87, 0, u8"RESERVE" }, + { 88, 2, u8"PV_AUTH_LIGHT_PRIORITY" }, + { 89, 3, u8"PV_CHARA_LIGHT" }, + { 90, 3, u8"PV_STAGE_LIGHT" }, + { 91, 11, u8"TARGET_EFFECT" }, + { 92, 3, u8"FOG" }, + { 93, 2, u8"BLOOM" }, + { 94, 3, u8"COLOR_CORRECTION" }, + { 95, 3, u8"DOF" }, + { 96, 4, u8"CHARA_ALPHA" }, + { 97, 1, u8"AUTO_CAPTURE_BEGIN" }, + { 98, 1, u8"MANUAL_CAPTURE" }, + { 99, 3, u8"TOON_EDGE" }, + { 100, 3, u8"SHIMMER" }, + { 101, 4, u8"ITEM_ALPHA" }, + { 102, 1, u8"MOVIE_CUT" }, + { 103, 112, u8"EDIT_CAMERA_BOX" }, + { 104, 1, u8"EDIT_STAGE_PARAM" }, + { 105, 1, u8"EDIT_CHANGE_FIELD" }, + { 106, 7, u8"MIKUDAYO_ADJUST" }, + { 107, 2, u8"LYRIC_2" }, + { 108, 2, u8"LYRIC_READ" }, + { 109, 2, u8"LYRIC_READ_2" }, + { 110, 5, u8"ANNOTATION" }, + { 111, 2, u8"STAGE_EFFECT" }, + { 112, 3, u8"SONG_EFFECT" }, + { 113, 3, u8"SONG_EFFECT_ATTACH" }, + { 114, 2, u8"LIGHT_AUTH" }, + { 115, 2, u8"FADE" }, + { 116, 2, u8"SET_STAGE_EFFECT_ENV" }, + { 117, 2, u8"RESERVE" }, + { 118, 2, u8"COMMON_EFFECT_AET_FRONT" }, + { 119, 2, u8"COMMON_EFFECT_AET_FRONT_LOW" }, + { 120, 2, u8"COMMON_EFFECT_PARTICLE" }, + { 121, 3, u8"SONG_EFFECT_ALPHA_SORT" }, + { 122, 5, u8"LOOK_CAMERA_FACE_LIMIT" }, + { 123, 3, u8"ITEM_LIGHT" }, + { 124, 3, u8"CHARA_EFFECT" }, + { 125, 2, u8"MARKER" }, + { 126, 3, u8"CHARA_EFFECT_CHARA_LIGHT" }, + { 127, 2, u8"ENABLE_COMMON_LIGHT_TO_CHARA" }, + { 128, 2, u8"ENABLE_FXAA" }, + { 129, 2, u8"ENABLE_TEMPORAL_AA" }, + { 130, 2, u8"ENABLE_REFLECTION" }, + { 131, 2, u8"BANK_BRANCH" }, + { 132, 2, u8"BANK_END" }, + { 133, 2, u8"" }, + { 134, 2, u8"" }, + { 135, 2, u8"" }, + { 136, 2, u8"" }, + { 137, 2, u8"" }, + { 138, 2, u8"" }, + { 139, 2, u8"" }, + { 140, 2, u8"" }, + { 141, 2, u8"VR_LIVE_MOVIE" }, + { 142, 2, u8"VR_CHEER" }, + { 143, 2, u8"VR_CHARA_PSMOVE" }, + { 144, 2, u8"VR_MOVE_PATH" }, + { 145, 2, u8"VR_SET_BASE" }, + { 146, 2, u8"VR_TECH_DEMO_EFFECT" }, + { 147, 2, u8"VR_TRANSFORM" }, + { 148, 2, u8"GAZE" }, + { 149, 2, u8"TECH_DEMO_GESUTRE" }, + { 150, 2, u8"VR_CHEMICAL_LIGHT_COLOR" }, + { 151, 5, u8"VR_LIVE_MOB" }, + { 152, 9, u8"VR_LIVE_HAIR_OSAGE" }, + { 153, 9, u8"VR_LIVE_LOOK_CAMERA" }, + { 154, 5, u8"VR_LIVE_CHEER" }, + { 155, 3, u8"VR_LIVE_GESTURE" }, + { 156, 7, u8"VR_LIVE_CLONE" }, + { 157, 7, u8"VR_LOOP_EFFECT" }, + { 158, 6, u8"VR_LIVE_ONESHOT_EFFECT" }, + { 159, 9, u8"VR_LIVE_PRESENT" }, + { 160, 5, u8"VR_LIVE_TRANSFORM" }, + { 161, 5, u8"VR_LIVE_FLY" }, + { 162, 2, u8"VR_LIVE_CHARA_VOICE" }, }; static const dsc_func dsc_vrfl_func[] = { - { 0, 0, "END" }, - { 1, 1, "TIME" }, - { 2, 4, "MIKU_MOVE" }, - { 3, 2, "MIKU_ROT" }, - { 4, 2, "MIKU_DISP" }, - { 5, 2, "MIKU_SHADOW" }, - { 6, 12, "TARGET" }, - { 7, 4, "SET_MOTION" }, - { 8, 2, "SET_PLAYDATA" }, - { 9, 6, "EFFECT" }, - { 10, 2, "FADEIN_FIELD" }, - { 11, 1, "EFFECT_OFF" }, - { 12, 6, "SET_CAMERA" }, - { 13, 2, "DATA_CAMERA" }, - { 14, 2, "CHANGE_FIELD" }, - { 15, 1, "HIDE_FIELD" }, - { 16, 3, "MOVE_FIELD" }, - { 17, 2, "FADEOUT_FIELD" }, - { 18, 3, "EYE_ANIM" }, - { 19, 5, "MOUTH_ANIM" }, - { 20, 5, "HAND_ANIM" }, - { 21, 4, "LOOK_ANIM" }, - { 22, 4, "EXPRESSION" }, - { 23, 5, "LOOK_CAMERA" }, - { 24, 2, "LYRIC" }, - { 25, 0, "MUSIC_PLAY" }, - { 26, 2, "MODE_SELECT" }, - { 27, 4, "EDIT_MOTION" }, - { 28, 2, "BAR_TIME_SET" }, - { 29, 2, "SHADOWHEIGHT" }, - { 30, 1, "EDIT_FACE" }, - { 31, 21, "DUMMY" }, - { 32, 0, "PV_END" }, - { 33, 3, "SHADOWPOS" }, - { 34, 2, "EDIT_LYRIC" }, - { 35, 5, "EDIT_TARGET" }, - { 36, 1, "EDIT_MOUTH" }, - { 37, 1, "SET_CHARA" }, - { 38, 7, "EDIT_MOVE" }, - { 39, 1, "EDIT_SHADOW" }, - { 40, 1, "EDIT_EYELID" }, - { 41, 2, "EDIT_EYE" }, - { 42, 1, "EDIT_ITEM" }, - { 43, 2, "EDIT_EFFECT" }, - { 44, 1, "EDIT_DISP" }, - { 45, 2, "EDIT_HAND_ANIM" }, - { 46, 3, "AIM" }, - { 47, 3, "HAND_ITEM" }, - { 48, 1, "EDIT_BLUSH" }, - { 49, 2, "NEAR_CLIP" }, - { 50, 2, "CLOTH_WET" }, - { 51, 3, "LIGHT_ROT" }, - { 52, 6, "SCENE_FADE" }, - { 53, 6, "TONE_TRANS" }, - { 54, 1, "SATURATE" }, - { 55, 1, "FADE_MODE" }, - { 56, 2, "AUTO_BLINK" }, - { 57, 3, "PARTS_DISP" }, - { 58, 1, "TARGET_FLYING_TIME" }, - { 59, 2, "CHARA_SIZE" }, - { 60, 2, "CHARA_HEIGHT_ADJUST" }, - { 61, 4, "ITEM_ANIM" }, - { 62, 4, "CHARA_POS_ADJUST" }, - { 63, 1, "SCENE_ROT" }, - { 64, 2, "EDIT_MOT_SMOOTH_LEN" }, - { 65, 1, "PV_BRANCH_MODE" }, - { 66, 2, "DATA_CAMERA_START" }, - { 67, 1, "MOVIE_PLAY" }, - { 68, 1, "MOVIE_DISP" }, - { 69, 3, "WIND" }, - { 70, 3, "OSAGE_STEP" }, - { 71, 3, "OSAGE_MV_CCL" }, - { 72, 2, "CHARA_COLOR" }, - { 73, 1, "SE_EFFECT" }, - { 74, 2, "CHARA_SHADOW_QUALITY" }, - { 75, 2, "STAGE_SHADOW_QUALITY" }, - { 76, 2, "COMMON_LIGHT" }, - { 77, 2, "TONE_MAP" }, - { 78, 2, "IBL_COLOR" }, - { 79, 2, "REFLECTION" }, - { 80, 3, "CHROMATIC_ABERRATION" }, - { 81, 2, "STAGE_SHADOW" }, - { 82, 2, "REFLECTION_QUALITY" }, - { 83, 2, "PV_END_FADEOUT" }, - { 84, 1, "CREDIT_TITLE" }, - { 85, 1, "BAR_POINT" }, - { 86, 1, "BEAT_POINT" }, - { 87, 0, "RESERVE" }, - { 88, 2, "PV_AUTH_LIGHT_PRIORITY" }, - { 89, 3, "PV_CHARA_LIGHT" }, - { 90, 3, "PV_STAGE_LIGHT" }, - { 91, 11, "TARGET_EFFECT" }, - { 92, 3, "FOG" }, - { 93, 2, "BLOOM" }, - { 94, 3, "COLOR_CORRECTION" }, - { 95, 3, "DOF" }, - { 96, 4, "CHARA_ALPHA" }, - { 97, 1, "AUTO_CAPTURE_BEGIN" }, - { 98, 1, "MANUAL_CAPTURE" }, - { 99, 3, "TOON_EDGE" }, - { 100, 3, "SHIMMER" }, - { 101, 4, "ITEM_ALPHA" }, - { 102, 1, "MOVIE_CUT" }, - { 103, 112, "EDIT_CAMERA_BOX" }, - { 104, 1, "EDIT_STAGE_PARAM" }, - { 105, 1, "EDIT_CHANGE_FIELD" }, - { 106, 7, "MIKUDAYO_ADJUST" }, - { 107, 2, "LYRIC_2" }, - { 108, 2, "LYRIC_READ" }, - { 109, 2, "LYRIC_READ_2" }, - { 110, 5, "ANNOTATION" }, - { 111, 2, "STAGE_EFFECT" }, - { 112, 3, "SONG_EFFECT" }, - { 113, 3, "SONG_EFFECT_ATTACH" }, - { 114, 2, "LIGHT_AUTH" }, - { 115, 2, "FADE" }, - { 116, 2, "SET_STAGE_EFFECT_ENV" }, - { 117, 2, "RESERVE" }, - { 118, 2, "COMMON_EFFECT_AET_FRONT" }, - { 119, 2, "COMMON_EFFECT_AET_FRONT_LOW" }, - { 120, 2, "COMMON_EFFECT_PARTICLE" }, - { 121, 3, "SONG_EFFECT_ALPHA_SORT" }, - { 122, 5, "LOOK_CAMERA_FACE_LIMIT" }, - { 123, 3, "ITEM_LIGHT" }, - { 124, 3, "CHARA_EFFECT" }, - { 125, 2, "MARKER" }, - { 126, 3, "CHARA_EFFECT_CHARA_LIGHT" }, - { 127, 2, "ENABLE_COMMON_LIGHT_TO_CHARA" }, - { 128, 2, "ENABLE_FXAA" }, - { 129, 2, "ENABLE_TEMPORAL_AA" }, - { 130, 2, "ENABLE_REFLECTION" }, - { 131, 2, "BANK_BRANCH" }, - { 132, 2, "BANK_END" }, - { 133, 2, "" }, - { 134, 2, "" }, - { 135, 2, "" }, - { 136, 2, "" }, - { 137, 2, "" }, - { 138, 2, "VR_LIVE_CHARA_MONITOR_UPDATE_Y" }, - { 139, 2, "VR_LIVE_POINT_FINGER" }, - { 140, 2, "VR_LIVE_CHARA_MONITOR" }, - { 141, 2, "VR_LIVE_MOVIE" }, - { 142, 2, "VR_CHEER" }, - { 143, 2, "VR_CHARA_PSMOVE" }, - { 144, 2, "VR_MOVE_PATH" }, - { 145, 2, "VR_SET_BASE" }, - { 146, 2, "VR_TECH_DEMO_EFFECT" }, - { 147, 2, "VR_TRANSFORM" }, - { 148, 2, "GAZE" }, - { 149, 2, "TECH_DEMO_GESUTRE" }, - { 150, 2, "VR_CHEMICAL_LIGHT_COLOR" }, - { 151, 5, "VR_LIVE_MOB" }, - { 152, 9, "VR_LIVE_HAIR_OSAGE" }, - { 153, 9, "VR_LIVE_LOOK_CAMERA" }, - { 154, 5, "VR_LIVE_CHEER" }, - { 155, 3, "VR_LIVE_GESTURE" }, - { 156, 7, "VR_LIVE_CLONE" }, - { 157, 7, "VR_LOOP_EFFECT" }, - { 158, 6, "VR_LIVE_ONESHOT_EFFECT" }, - { 159, 9, "VR_LIVE_PRESENT" }, - { 160, 7, "VR_LIVE_TRANSFORM" }, - { 161, 5, "VR_LIVE_FLY" }, - { 162, 2, "VR_LIVE_CHARA_VOICE" }, + { 0, 0, u8"END" }, + { 1, 1, u8"TIME" }, + { 2, 4, u8"MIKU_MOVE" }, + { 3, 2, u8"MIKU_ROT" }, + { 4, 2, u8"MIKU_DISP" }, + { 5, 2, u8"MIKU_SHADOW" }, + { 6, 12, u8"TARGET" }, + { 7, 4, u8"SET_MOTION" }, + { 8, 2, u8"SET_PLAYDATA" }, + { 9, 6, u8"EFFECT" }, + { 10, 2, u8"FADEIN_FIELD" }, + { 11, 1, u8"EFFECT_OFF" }, + { 12, 6, u8"SET_CAMERA" }, + { 13, 2, u8"DATA_CAMERA" }, + { 14, 2, u8"CHANGE_FIELD" }, + { 15, 1, u8"HIDE_FIELD" }, + { 16, 3, u8"MOVE_FIELD" }, + { 17, 2, u8"FADEOUT_FIELD" }, + { 18, 3, u8"EYE_ANIM" }, + { 19, 5, u8"MOUTH_ANIM" }, + { 20, 5, u8"HAND_ANIM" }, + { 21, 4, u8"LOOK_ANIM" }, + { 22, 4, u8"EXPRESSION" }, + { 23, 5, u8"LOOK_CAMERA" }, + { 24, 2, u8"LYRIC" }, + { 25, 0, u8"MUSIC_PLAY" }, + { 26, 2, u8"MODE_SELECT" }, + { 27, 4, u8"EDIT_MOTION" }, + { 28, 2, u8"BAR_TIME_SET" }, + { 29, 2, u8"SHADOWHEIGHT" }, + { 30, 1, u8"EDIT_FACE" }, + { 31, 21, u8"DUMMY" }, + { 32, 0, u8"PV_END" }, + { 33, 3, u8"SHADOWPOS" }, + { 34, 2, u8"EDIT_LYRIC" }, + { 35, 5, u8"EDIT_TARGET" }, + { 36, 1, u8"EDIT_MOUTH" }, + { 37, 1, u8"SET_CHARA" }, + { 38, 7, u8"EDIT_MOVE" }, + { 39, 1, u8"EDIT_SHADOW" }, + { 40, 1, u8"EDIT_EYELID" }, + { 41, 2, u8"EDIT_EYE" }, + { 42, 1, u8"EDIT_ITEM" }, + { 43, 2, u8"EDIT_EFFECT" }, + { 44, 1, u8"EDIT_DISP" }, + { 45, 2, u8"EDIT_HAND_ANIM" }, + { 46, 3, u8"AIM" }, + { 47, 3, u8"HAND_ITEM" }, + { 48, 1, u8"EDIT_BLUSH" }, + { 49, 2, u8"NEAR_CLIP" }, + { 50, 2, u8"CLOTH_WET" }, + { 51, 3, u8"LIGHT_ROT" }, + { 52, 6, u8"SCENE_FADE" }, + { 53, 6, u8"TONE_TRANS" }, + { 54, 1, u8"SATURATE" }, + { 55, 1, u8"FADE_MODE" }, + { 56, 2, u8"AUTO_BLINK" }, + { 57, 3, u8"PARTS_DISP" }, + { 58, 1, u8"TARGET_FLYING_TIME" }, + { 59, 2, u8"CHARA_SIZE" }, + { 60, 2, u8"CHARA_HEIGHT_ADJUST" }, + { 61, 4, u8"ITEM_ANIM" }, + { 62, 4, u8"CHARA_POS_ADJUST" }, + { 63, 1, u8"SCENE_ROT" }, + { 64, 2, u8"EDIT_MOT_SMOOTH_LEN" }, + { 65, 1, u8"PV_BRANCH_MODE" }, + { 66, 2, u8"DATA_CAMERA_START" }, + { 67, 1, u8"MOVIE_PLAY" }, + { 68, 1, u8"MOVIE_DISP" }, + { 69, 3, u8"WIND" }, + { 70, 3, u8"OSAGE_STEP" }, + { 71, 3, u8"OSAGE_MV_CCL" }, + { 72, 2, u8"CHARA_COLOR" }, + { 73, 1, u8"SE_EFFECT" }, + { 74, 2, u8"CHARA_SHADOW_QUALITY" }, + { 75, 2, u8"STAGE_SHADOW_QUALITY" }, + { 76, 2, u8"COMMON_LIGHT" }, + { 77, 2, u8"TONE_MAP" }, + { 78, 2, u8"IBL_COLOR" }, + { 79, 2, u8"REFLECTION" }, + { 80, 3, u8"CHROMATIC_ABERRATION" }, + { 81, 2, u8"STAGE_SHADOW" }, + { 82, 2, u8"REFLECTION_QUALITY" }, + { 83, 2, u8"PV_END_FADEOUT" }, + { 84, 1, u8"CREDIT_TITLE" }, + { 85, 1, u8"BAR_POINT" }, + { 86, 1, u8"BEAT_POINT" }, + { 87, 0, u8"RESERVE" }, + { 88, 2, u8"PV_AUTH_LIGHT_PRIORITY" }, + { 89, 3, u8"PV_CHARA_LIGHT" }, + { 90, 3, u8"PV_STAGE_LIGHT" }, + { 91, 11, u8"TARGET_EFFECT" }, + { 92, 3, u8"FOG" }, + { 93, 2, u8"BLOOM" }, + { 94, 3, u8"COLOR_CORRECTION" }, + { 95, 3, u8"DOF" }, + { 96, 4, u8"CHARA_ALPHA" }, + { 97, 1, u8"AUTO_CAPTURE_BEGIN" }, + { 98, 1, u8"MANUAL_CAPTURE" }, + { 99, 3, u8"TOON_EDGE" }, + { 100, 3, u8"SHIMMER" }, + { 101, 4, u8"ITEM_ALPHA" }, + { 102, 1, u8"MOVIE_CUT" }, + { 103, 112, u8"EDIT_CAMERA_BOX" }, + { 104, 1, u8"EDIT_STAGE_PARAM" }, + { 105, 1, u8"EDIT_CHANGE_FIELD" }, + { 106, 7, u8"MIKUDAYO_ADJUST" }, + { 107, 2, u8"LYRIC_2" }, + { 108, 2, u8"LYRIC_READ" }, + { 109, 2, u8"LYRIC_READ_2" }, + { 110, 5, u8"ANNOTATION" }, + { 111, 2, u8"STAGE_EFFECT" }, + { 112, 3, u8"SONG_EFFECT" }, + { 113, 3, u8"SONG_EFFECT_ATTACH" }, + { 114, 2, u8"LIGHT_AUTH" }, + { 115, 2, u8"FADE" }, + { 116, 2, u8"SET_STAGE_EFFECT_ENV" }, + { 117, 2, u8"RESERVE" }, + { 118, 2, u8"COMMON_EFFECT_AET_FRONT" }, + { 119, 2, u8"COMMON_EFFECT_AET_FRONT_LOW" }, + { 120, 2, u8"COMMON_EFFECT_PARTICLE" }, + { 121, 3, u8"SONG_EFFECT_ALPHA_SORT" }, + { 122, 5, u8"LOOK_CAMERA_FACE_LIMIT" }, + { 123, 3, u8"ITEM_LIGHT" }, + { 124, 3, u8"CHARA_EFFECT" }, + { 125, 2, u8"MARKER" }, + { 126, 3, u8"CHARA_EFFECT_CHARA_LIGHT" }, + { 127, 2, u8"ENABLE_COMMON_LIGHT_TO_CHARA" }, + { 128, 2, u8"ENABLE_FXAA" }, + { 129, 2, u8"ENABLE_TEMPORAL_AA" }, + { 130, 2, u8"ENABLE_REFLECTION" }, + { 131, 2, u8"BANK_BRANCH" }, + { 132, 2, u8"BANK_END" }, + { 133, 2, u8"" }, + { 134, 2, u8"" }, + { 135, 2, u8"" }, + { 136, 2, u8"" }, + { 137, 2, u8"" }, + { 138, 2, u8"VR_LIVE_CHARA_MONITOR_UPDATE_Y" }, + { 139, 2, u8"VR_LIVE_POINT_FINGER" }, + { 140, 2, u8"VR_LIVE_CHARA_MONITOR" }, + { 141, 2, u8"VR_LIVE_MOVIE" }, + { 142, 2, u8"VR_CHEER" }, + { 143, 2, u8"VR_CHARA_PSMOVE" }, + { 144, 2, u8"VR_MOVE_PATH" }, + { 145, 2, u8"VR_SET_BASE" }, + { 146, 2, u8"VR_TECH_DEMO_EFFECT" }, + { 147, 2, u8"VR_TRANSFORM" }, + { 148, 2, u8"GAZE" }, + { 149, 2, u8"TECH_DEMO_GESUTRE" }, + { 150, 2, u8"VR_CHEMICAL_LIGHT_COLOR" }, + { 151, 5, u8"VR_LIVE_MOB" }, + { 152, 9, u8"VR_LIVE_HAIR_OSAGE" }, + { 153, 9, u8"VR_LIVE_LOOK_CAMERA" }, + { 154, 5, u8"VR_LIVE_CHEER" }, + { 155, 3, u8"VR_LIVE_GESTURE" }, + { 156, 7, u8"VR_LIVE_CLONE" }, + { 157, 7, u8"VR_LOOP_EFFECT" }, + { 158, 6, u8"VR_LIVE_ONESHOT_EFFECT" }, + { 159, 9, u8"VR_LIVE_PRESENT" }, + { 160, 7, u8"VR_LIVE_TRANSFORM" }, + { 161, 5, u8"VR_LIVE_FLY" }, + { 162, 2, u8"VR_LIVE_CHARA_VOICE" }, }; #define DSC_AC101_FUNC_COUNT 36 @@ -2746,7 +2747,7 @@ void dsc::merge(int32_t count, ...) { } } -bool dsc::parse(void* data, size_t size, dsc_type type) { +bool dsc::parse(const void* data, size_t size, dsc_type type) { if (!data || !(size / 4) || type < DSC_AC101 || type > DSC_VRFL) return false; @@ -2837,6 +2838,77 @@ bool dsc::parse(void* data, size_t size, dsc_type type) { return true; } +bool dsc::parse_text(const void* data, size_t size, dsc_type type) { + if (!data || !size || type < DSC_AC101 || type > DSC_VRFL) + return false; + + this->type = type; + + dsc_get_func_id get_func_id = dsc_type_get_dsc_get_func_id(type); + dsc_get_func_length get_func_length = get_dsc_get_func_length(); + dsc_get_func_name get_func_name = dsc_type_get_dsc_get_func_name(type); + + char* buf = 0; + char** lines = 0; + size_t count = 0; + if (!str_utils_text_file_parse(data, size, buf, lines, count)) + return false; + + std::vector data_buf; + + char func_buf[0x200]; + this->data.reserve(count); + for (size_t i = 0; i < count; i++) { + const char* line = lines[i]; + const char* ch = strchr(line, '('); + if (!ch) + continue; + + strncpy_s(func_buf, sizeof(func_buf), line, ch - line); + + int32_t func_id = get_func_id(func_buf); + if (func_id == -1) + continue; + + int32_t func_length = get_func_length(func_id); + const char* func_name = get_func_name(func_id); + + line += utf8_length(func_name) + 1; + + data_buf.clear(); + for (int32_t j = func_length; j > 0; j--) { + const char* ch = strchr(line, ','); + if (!ch) { + ch = strchr(line, ')'); + if (!ch) + break; + } + + strncpy_s(func_buf, sizeof(func_buf), line, ch - line); + + int32_t t; + if (sscanf_s(func_buf, "%d", &t) != 1) + break; + + data_buf.push_back((uint32_t)t); + + line += strlen(func_buf) + 1; + + while (*line == ' ') + line++; + } + + if (func_length != data_buf.size()) + break; + + uint32_t* data = add_func(func_name, func_id, func_length); + memcpy(data, data_buf.data(), sizeof(uint32_t) * func_length); + } + + free_def(buf); + return true; +} + void dsc::unparse(void** data, size_t* size) { if (!data || !size) return; @@ -2931,7 +3003,7 @@ int32_t dsc::calculate_target_flying_time(int32_t bpm, int32_t time_signature) { bool dsc::load_file(void* data, const char* path, const char* file, uint32_t hash) { std::string s = path + std::string(file); - stream dsc_s; + file_stream dsc_s; dsc_s.open(s.c_str(), "rb"); void* dsc_data = force_malloc(dsc_s.length); size_t dsc_length = dsc_s.length; @@ -2940,7 +3012,7 @@ bool dsc::load_file(void* data, const char* path, const char* file, uint32_t has dsc* d = (dsc*)data; bool ret = d->parse(dsc_data, dsc_length, d->type); - free(dsc_data); + free_def(dsc_data); return ret; } diff --git a/src/KKdLib/dsc.hpp b/src/KKdLib/dsc.hpp index 55cfeb46..44f676ac 100644 --- a/src/KKdLib/dsc.hpp +++ b/src/KKdLib/dsc.hpp @@ -292,7 +292,8 @@ struct dsc { dsc_get_func_length get_dsc_get_func_length(); uint32_t* get_func_data(dsc_data* data); void merge(int32_t count, ...); - bool parse(void* data, size_t size, dsc_type type); + bool parse(const void* data, size_t size, dsc_type type); + bool parse_text(const void* data, size_t size, dsc_type type); void rebuild(); void unparse(void** data, size_t* size); diff --git a/src/KKdLib/enbaya.cpp b/src/KKdLib/enbaya.cpp index 5907cc58..ca4df1c1 100644 --- a/src/KKdLib/enbaya.cpp +++ b/src/KKdLib/enbaya.cpp @@ -44,7 +44,7 @@ int32_t enb_process(uint8_t* data_in, uint8_t** data_out, code = enb_initialize(data_in, &play_head); if (code) { - free(*data_out); + free_def(*data_out); return code - 0x10; } @@ -105,7 +105,7 @@ int32_t enb_initialize(uint8_t* data, enb_play_head** play_head) { ph->track_data = force_malloc_s(enb_track, head->track_count); if (!ph->track_data) { - free(ph); + free_def(ph); return -4; } @@ -119,8 +119,8 @@ void enb_free(enb_play_head** play_head) { if (!play_head || !*play_head) return; - free((*play_head)->track_data); - free(*play_head); + free_def((*play_head)->track_data); + free_def(*play_head); *play_head = 0; } @@ -670,16 +670,10 @@ static void enb_calc_track_init(enb_play_head* play_head) { // 0x08A086CC in ULJ C010 = track_data->quat; C020 = track_data->trans; - C100.x = C010.x * S030; - C100.y = C010.y * S030; - C100.z = C010.z * S030; - C100.w = C010.w * S030; + C100 = C010 * S030; + C110 = C020 * S030; - C110.x = C020.x * S030; - C110.y = C020.y * S030; - C110.z = C020.z * S030; - - vec4_normalize(C100, C100); + C100 = quat::normalize(C100); track_data->qt[0].quat = C100; track_data->qt[0].trans = C110; @@ -723,16 +717,10 @@ static void enb_calc_track(enb_play_head* play_head, float_t time, bool forward) C120 = track_data->qt[s0].quat; C130 = track_data->qt[s0].trans; - C100.x = C010.x * S030 + C120.x; - C100.y = C010.y * S030 + C120.y; - C100.z = C010.z * S030 + C120.z; - C100.w = C010.w * S030 + C120.w; + C100 = C010 * S030 + C120; + C110 = C020 * S030 + C130; - C110.x = C020.x * S030 + C130.x; - C110.y = C020.y * S030 + C130.y; - C110.z = C020.z * S030 + C130.z; - - vec4_normalize(C100, C100); + C100 = quat::normalize(C100); track_data->qt[s1].quat = C100; track_data->qt[s1].trans = C110; diff --git a/src/KKdLib/f2/header.cpp b/src/KKdLib/f2/header.cpp index 193378ce..9e64841b 100644 --- a/src/KKdLib/f2/header.cpp +++ b/src/KKdLib/f2/header.cpp @@ -8,18 +8,8 @@ void f2_header_read(stream& s, f2_header* h) { memset(h, 0, sizeof(f2_header)); - switch (s.type) { - case STREAM_FILE: - if (!s.io.stream) - return; - break; - case STREAM_MEMORY: - if (!s.io.data.vec.size()) - return; - break; - default: + if (s.check_null()) return; - } s.read(h, 0x20); if (h->length == 0x40) @@ -27,32 +17,16 @@ void f2_header_read(stream& s, f2_header* h) { } void f2_header_write(stream& s, f2_header* h, bool extended) { - switch (s.type) { - case STREAM_FILE: - if (!s.io.stream) - return; - break; - case STREAM_MEMORY: - break; - default: + if (s.check_null()) return; - } h->length = extended ? 0x40 : 0x20; s.write(h, h->length); } void f2_header_write_end_of_container(stream& s, uint32_t depth) { - switch (s.type) { - case STREAM_FILE: - if (!s.io.stream) - return; - break; - case STREAM_MEMORY: - break; - default: + if (s.check_null()) return; - } f2_header h; memset(&h, 0, sizeof(f2_header)); diff --git a/src/KKdLib/f2/struct.cpp b/src/KKdLib/f2/struct.cpp index a52d81e9..a94fa3dd 100644 --- a/src/KKdLib/f2/struct.cpp +++ b/src/KKdLib/f2/struct.cpp @@ -4,8 +4,9 @@ */ #include "struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../divafile.hpp" static void f2_struct_read_data(stream& s, f2_struct* st, f2_header* h); @@ -26,14 +27,15 @@ void f2_struct::read(const char* path) { if (!path) return; - stream s; + file_stream s; s.open(path, "rb"); - if (&s.io.stream) { - divafile::decrypt(s); + if (s.check_not_null()) { + memory_stream ms; + divafile::decrypt(s, ms); f2_header h; - f2_header_read(s, &h); - f2_struct_read_data(s, this, &h); + f2_header_read(ms, &h); + f2_struct_read_data(ms, this, &h); } } @@ -41,14 +43,15 @@ void f2_struct::read(const wchar_t* path) { if (!path) return; - stream s; + file_stream s; s.open(path, L"rb"); - if (&s.io.stream) { - divafile::decrypt(s); + if (s.check_not_null()) { + memory_stream ms; + divafile::decrypt(s, ms); f2_header h; - f2_header_read(s, &h); - f2_struct_read_data(s, this, &h); + f2_header_read(ms, &h); + f2_struct_read_data(ms, this, &h); } } @@ -56,35 +59,37 @@ void f2_struct::read(const void* data, size_t size) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); - if (&s.io.data.data) { - divafile::decrypt(s); + if (s.check_not_null()) { + memory_stream ms; + divafile::decrypt(s, ms); f2_header h; - f2_header_read(s, &h); - f2_struct_read_data(s, this, &h); + f2_header_read(ms, &h); + f2_struct_read_data(ms, this, &h); } } void f2_struct::read(stream& s) { - if (s.io.check_null()) + if (s.check_null()) return; - divafile::decrypt(s); + memory_stream ms; + divafile::decrypt(s, ms); f2_header h; - f2_header_read(s, &h); - f2_struct_read_data(s, this, &h); + f2_header_read(ms, &h); + f2_struct_read_data(ms, this, &h); } void f2_struct::write(const char* path, bool use_depth, bool shift_x) { if (!path) return; - stream s; + file_stream s; s.open(path, "wb"); - if (s.io.stream) { + if (s.check_not_null()) { f2_struct_get_length(this, shift_x); f2_struct_write_inner(s, this, 0, use_depth, shift_x); } @@ -94,9 +99,9 @@ void f2_struct::write(const wchar_t* path, bool use_depth, bool shift_x) { if (!path) return; - stream s; + file_stream s; s.open(path, L"wb"); - if (s.io.stream) { + if (s.check_not_null()) { f2_struct_get_length(this, shift_x); f2_struct_write_inner(s, this, 0, use_depth, shift_x); } @@ -107,7 +112,7 @@ void f2_struct::write(void** data, size_t* size, bool use_depth, bool shift_x) { return; f2_struct_get_length(this, shift_x); - stream s; + memory_stream s; s.open(0, header.data_size + 0x40ULL); f2_struct_write_inner(s, this, 0, use_depth, shift_x); @@ -115,13 +120,13 @@ void f2_struct::write(void** data, size_t* size, bool use_depth, bool shift_x) { } void f2_struct::write(stream& s, bool use_depth, bool shift_x) { - if (s.io.check_null()) + if (s.check_null()) return; - if (s.io.stream || s.type == STREAM_MEMORY) { - f2_struct_get_length(this, shift_x); - f2_struct_write_inner(s, this, 0, use_depth, shift_x); - } + + f2_struct_get_length(this, shift_x); + f2_struct_write_inner(s, this, 0, use_depth, shift_x); + } static void f2_struct_get_length(f2_struct* s, bool shift_x) { diff --git a/src/KKdLib/farc.cpp b/src/KKdLib/farc.cpp index 95aea10a..429a83b1 100644 --- a/src/KKdLib/farc.cpp +++ b/src/KKdLib/farc.cpp @@ -5,6 +5,8 @@ #include "farc.hpp" #include "io/path.hpp" +#include "io/file_stream.hpp" +#include "io/memory_stream.hpp" #include "aes.hpp" #include "deflate.hpp" #include "hash.hpp" @@ -24,12 +26,15 @@ static errno_t farc_get_files(farc* f); static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool get_files); static errno_t farc_read_header(farc* f, stream& s); static void farc_unpack_files(farc* f, stream& s, bool save); +static void farc_unpack_file(farc* f, farc_file* ff); static void farc_unpack_file(farc* f, stream& s, farc_file* ff, bool save = false, char* temp_path = 0, size_t dir_len = 0); +static void farc_write_padding(farc* f, stream& s, size_t size, bool x = false); farc::farc() : flags(), ft() { signature = FARC_FArC; compression_level = 12; + alignment = 0x10; } farc::~farc() { @@ -37,13 +42,13 @@ farc::~farc() { } farc_file::farc_file() : offset(), size(), size_compressed(), -data(), data_compressed(), compressed(), encrypted(), data_changed() { +data(), data_compressed(), flags(), data_changed() { } farc_file::~farc_file() { - free(data); - free(data_compressed); + free_def(data); + free_def(data_compressed); } void farc::add_file(const char* name) { @@ -66,7 +71,7 @@ void farc::add_file(const char* name) { data_temp[i * 2 + 0] = 0; data_temp[i * 2 + 1] = 0; } - free(data_temp); + free_def(data_temp); } void farc::add_file(const wchar_t* name) { @@ -83,7 +88,7 @@ void farc::add_file(const wchar_t* name) { if (name) { char* name_temp = utf16_to_utf8(name); files.back().name = name_temp; - free(name_temp); + free_def(name_temp); } for (size_t i = 0; i < files_count; i++) { @@ -92,7 +97,7 @@ void farc::add_file(const wchar_t* name) { data_temp[i * 2 + 0] = 0; data_temp[i * 2 + 1] = 0; } - free(data_temp); + free_def(data_temp); } const char* farc::get_file_name(uint32_t hash) { @@ -179,7 +184,7 @@ void farc::read(const char* path, bool unpack, bool save) { wchar_t* path_buf = utf8_to_utf16(path); read(path_buf, unpack, save); - free(path_buf); + free_def(path_buf); } void farc::read(const wchar_t* path, bool unpack, bool save) { @@ -201,15 +206,15 @@ void farc::read(const wchar_t* path, bool unpack, bool save) { size_t dir_temp_len = utf8_length(dir_temp); file_path = std::string(dir_temp, dir_temp_len); directory_path = std::string(dir_temp, dir_temp_len); - free(dir_temp); + free_def(dir_temp); const char* dot = strrchr(directory_path.c_str(), '.'); if (dot) directory_path = directory_path.substr(0, dot - directory_path.c_str()); - stream s; + file_stream s; s.open(file_path.c_str(), "rb"); - if (s.io.stream && !farc_read_header(this, s) && unpack) + if (s.check_not_null() && !farc_read_header(this, s) && unpack) farc_unpack_files(this, s, save); } @@ -223,7 +228,7 @@ void farc::read(const void* data, size_t size, bool unpack) { file_path = {}; directory_path = {}; - stream s; + memory_stream s; s.open(data, size); if (!farc_read_header(this, s) && unpack) farc_unpack_files(this, s, false); @@ -234,21 +239,11 @@ farc_file* farc::read_file(const char* name) { return 0; uint32_t name_hash = hash_utf8_murmurhash(name); - for (farc_file& i : files) { - if (hash_string_murmurhash(i.name) != name_hash) - continue; - - if (!i.data && i.data_compressed) - deflate::decompress(i.data_compressed, i.size_compressed, - &i.data, &i.size, deflate::MODE_GZIP); - else if (!i.data) { - stream s; - s.open(file_path.c_str(), "rb"); - if (s.io.stream) - farc_unpack_file(this, s, &i); + for (farc_file& i : files) + if (hash_string_murmurhash(i.name) == name_hash) { + farc_unpack_file(this, &i); + return &i; } - return &i; - } return 0; } @@ -257,21 +252,11 @@ farc_file* farc::read_file(const wchar_t* name) { return 0; uint32_t name_hash = hash_utf16_murmurhash(name); - for (farc_file& i : files) { - if (hash_string_murmurhash(i.name) != name_hash) - continue; - - if (!i.data && i.data_compressed) - deflate::decompress(i.data_compressed, i.size_compressed, - &i.data, &i.size, deflate::MODE_GZIP); - else if (!i.data) { - stream s; - s.open(file_path.c_str(), "rb"); - if (s.io.stream) - farc_unpack_file(this, s, &i); + for (farc_file& i : files) + if (hash_string_murmurhash(i.name) == name_hash) { + farc_unpack_file(this, &i); + return &i; } - return &i; - } return 0; } @@ -286,19 +271,10 @@ farc_file* farc::read_file(uint32_t hash) { if (t) l_len = t - l_str; - if (hash_murmurhash(l_str, l_len) != hash) - continue; - - if (!i.data && i.data_compressed) - deflate::decompress(i.data_compressed, i.size_compressed, - &i.data, &i.size, deflate::MODE_GZIP); - else if (!i.data) { - stream s; - s.open(file_path.c_str(), "rb"); - if (s.io.stream) - farc_unpack_file(this, s, &i); + if (hash_murmurhash(l_str, l_len) == hash) { + farc_unpack_file(this, &i); + return &i; } - return &i; } return 0; } @@ -309,7 +285,7 @@ void farc::write(const char* path, farc_compress_mode mode, bool get_files) { wchar_t* path_buf = utf8_to_utf16(path); write(path_buf, mode, get_files); - free(path_buf); + free_def(path_buf); } void farc::write(const wchar_t* path, farc_compress_mode mode, bool get_files) { @@ -334,12 +310,12 @@ void farc::write(const wchar_t* path, farc_compress_mode mode, bool get_files) { directory_path = std::string(dir_temp, dir_temp_len); file_path = std::string(dir_temp, dir_temp_len); file_path += ".farc", 6; - free(dir_temp); + free_def(dir_temp); if (!get_files || (get_files && !farc_get_files(this))) { - stream s; + file_stream s; s.open(file_path.c_str(), "wb"); - if (s.io.stream) + if (s.check_not_null()) farc_pack_files(this, s, mode, get_files); } } @@ -351,7 +327,7 @@ void farc::write(void** data, size_t* size, farc_compress_mode mode) { directory_path = {}; file_path = {}; - stream s; + memory_stream s; s.open(); farc_pack_files(this, s, mode, false); } @@ -380,8 +356,7 @@ static errno_t farc_get_files(farc* f) { f->files.clear(); f->files.shrink_to_fit(); - std::vector files; - path_get_files(&files, f->directory_path.c_str()); + std::vector files = path_get_files(f->directory_path.c_str()); if (files.size() < 1) return -1; @@ -398,7 +373,7 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge bool is_a3da = str_utils_compare(ext, ".a3da") == 0; bool is_diva = str_utils_compare(ext, ".diva") == 0; bool is_vag = str_utils_compare(ext, ".vag") == 0; - free(ext); + free_def(ext); if (is_a3da || is_diva || is_vag) { plain = true; @@ -449,14 +424,14 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge } size_t align = header_length + 8; - s.set_position(align_val(align, 0x10), SEEK_SET); + s.set_position(align_val(align, f->alignment), SEEK_SET); size_t dir_len = f->directory_path.size(); aes128_ctx ctx; if (mode == FARC_COMPRESS_FARC_AES || mode == FARC_COMPRESS_FARC_GZIP_AES) aes128_init_ctx(&ctx, key); - f->compression_level = clamp(f->compression_level, 0, 12); + f->compression_level = clamp_def(f->compression_level, 0, 12); if (get_files) { char* temp = force_malloc_s(char, dir_len + 2 + MAX_PATH); memcpy(temp, f->directory_path.c_str(), sizeof(char) * dir_len); @@ -469,11 +444,10 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge i.offset = s.get_position(); - stream s_t; + file_stream s_t; s_t.open(temp, "rb"); - if (!s_t.io.stream) { + if (s_t.check_null()) continue; - } s_t.set_position(0, SEEK_END); size_t file_len = s_t.get_position(); @@ -488,20 +462,24 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge void* t1; size_t t1_len; if (mode == FARC_COMPRESS_FARC_GZIP_AES) { - deflate::compress(t, file_len, &t1, &t1_len, - f->compression_level, deflate::MODE_GZIP); - free(t); + if (!i.data_compressed || i.data_changed) { + free_def(i.data_compressed); + deflate::compress_gzip(i.data, file_len, &i.data_compressed, + &i.size_compressed, f->compression_level, i.name.c_str()); + } + t1 = i.data_compressed; + t1_len = i.size_compressed; } else { - t1 = t; - t1_len = file_len; + free_def(i.data_compressed); + t1 = i.data; + t1_len = i.size; } - size_t t2_len = align_val(t1_len, 0x10); + size_t t2_len = align_val(t1_len, f->alignment); size_t a = t2_len - t1_len; void* t2 = force_malloc(t2_len); memcpy(t2, t1, t1_len); - free(t1); for (size_t j = 0; j < a; j++) ((uint8_t*)t2)[t1_len + j] = 0x78; @@ -509,33 +487,27 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge aes128_ecb_encrypt_buffer(&ctx, (uint8_t*)t2, t2_len); s.write(t2, t2_len); - i.size_compressed = t1_len; - t = t2; + free_def(t2); } else if (mode == FARC_COMPRESS_FArC || mode == FARC_COMPRESS_FARC_GZIP) { - void* t1; - size_t t1_len; - deflate::compress(t, file_len, &t1, &t1_len, - f->compression_level, deflate::MODE_GZIP); - free(t); - s.write(t1, t1_len); - size_t a = align_val(t1_len, 0x10) - t1_len; - for (size_t j = 0; j < a; j++) - s.write_uint8_t(0x78); - i.size_compressed = t1_len; - t = t1; + if (!i.data_compressed || i.data_changed) { + free_def(i.data_compressed); + deflate::compress_gzip(i.data, file_len, &i.data_compressed, + &i.size_compressed, f->compression_level, i.name.c_str()); + } + s.write(i.data_compressed, i.size_compressed); + farc_write_padding(f, s, i.size_compressed, mode != FARC_COMPRESS_FArc); } else { - s.write(t, file_len); - size_t a = align_val(file_len, 0x10) - file_len; - for (size_t j = 0; j < a; j++) - s.write_uint8_t(0x00); + free_def(i.data_compressed); + s.write(i.data, file_len); + farc_write_padding(f, s, i.size_compressed); } - free(t); + free_def(t); i.data = 0; i.data_changed = false; } - free(temp); + free_def(temp); } else for (farc_file& i : f->files) { @@ -547,20 +519,20 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge size_t t1_len; if (mode == FARC_COMPRESS_FARC_GZIP_AES) { if (!i.data_compressed || i.data_changed) { - free(i.data_compressed); - deflate::compress(i.data, file_len, &i.data_compressed, - &i.size_compressed, f->compression_level, deflate::MODE_GZIP); + free_def(i.data_compressed); + deflate::compress_gzip(i.data, file_len, &i.data_compressed, + &i.size_compressed, f->compression_level, i.name.c_str()); } t1 = i.data_compressed; t1_len = i.size_compressed; } else { - free(i.data_compressed); + free_def(i.data_compressed); t1 = i.data; t1_len = i.size; } - size_t t2_len = align_val(t1_len, 0x10); + size_t t2_len = align_val(t1_len, f->alignment); size_t a = t2_len - t1_len; void* t2 = force_malloc(t2_len); memcpy(t2, t1, t1_len); @@ -571,25 +543,21 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge aes128_ecb_encrypt_buffer(&ctx, (uint8_t*)t2, t2_len); s.write(t2, t2_len); - free(t2); + free_def(t2); } else if (mode == FARC_COMPRESS_FArC || mode == FARC_COMPRESS_FARC_GZIP) { if (!i.data_compressed || i.data_changed) { - free(i.data_compressed); - deflate::compress(i.data, file_len, &i.data_compressed, - &i.size_compressed, f->compression_level, deflate::MODE_GZIP); + free_def(i.data_compressed); + deflate::compress_gzip(i.data, file_len, &i.data_compressed, + &i.size_compressed, f->compression_level, i.name.c_str()); } s.write(i.data_compressed, i.size_compressed); - size_t a = align_val(i.size_compressed, 0x10) - i.size_compressed; - for (size_t j = 0; j < a; j++) - s.write_uint8_t(0x78); + farc_write_padding(f, s, i.size_compressed, mode != FARC_COMPRESS_FArc); } else { - free(i.data_compressed); + free_def(i.data_compressed); s.write(i.data, file_len); - size_t a = align_val(file_len, 0x10) - file_len; - for (size_t j = 0; j < a; j++) - s.write_uint8_t(0x00); + farc_write_padding(f, s, i.size_compressed); } i.data_changed = false; } @@ -598,26 +566,26 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge switch (mode) { case FARC_COMPRESS_FArc: default: - s.write_int32_t_reverse_endianness(FARC_FArc, true); - s.write_int32_t_reverse_endianness((int32_t)header_length, true); - s.write_int32_t_reverse_endianness(0x01, true); + s.write_uint32_t_reverse_endianness(FARC_FArc, true); + s.write_uint32_t_reverse_endianness((int32_t)header_length, true); + s.write_uint32_t_reverse_endianness(f->alignment, true); break; case FARC_COMPRESS_FArC: - s.write_int32_t_reverse_endianness(FARC_FArC, true); - s.write_int32_t_reverse_endianness((int32_t)header_length, true); - s.write_int32_t_reverse_endianness(0x01, true); + s.write_uint32_t_reverse_endianness(FARC_FArC, true); + s.write_uint32_t_reverse_endianness((int32_t)header_length, true); + s.write_uint32_t_reverse_endianness(f->alignment, true); break; case FARC_COMPRESS_FARC: case FARC_COMPRESS_FARC_GZIP: case FARC_COMPRESS_FARC_AES: case FARC_COMPRESS_FARC_GZIP_AES: - s.write_int32_t_reverse_endianness(FARC_FARC, true); - s.write_int32_t_reverse_endianness((int32_t)header_length, true); - s.write_int32_t_reverse_endianness(f->flags, true); - s.write_int32_t_reverse_endianness(0x00, true); - s.write_int32_t_reverse_endianness(0x40, true); - s.write_int32_t_reverse_endianness(0x00, true); - s.write_int32_t_reverse_endianness(0x00, true); + s.write_uint32_t_reverse_endianness(FARC_FARC, true); + s.write_uint32_t_reverse_endianness((int32_t)header_length, true); + s.write_uint32_t_reverse_endianness(f->flags, true); + s.write_uint32_t_reverse_endianness(0x00, true); + s.write_uint32_t_reverse_endianness(f->alignment, true); + s.write_uint32_t_reverse_endianness(0x00, true); + s.write_uint32_t_reverse_endianness(0x00, true); break; } @@ -641,55 +609,46 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge s.write_int32_t_reverse_endianness((int32_t)i.offset, true); s.write_int32_t_reverse_endianness((int32_t)i.size, true); } + else if (compressed) + for (farc_file& i : f->files) { + s.write_string_null_terminated(i.name); + s.write_int32_t_reverse_endianness((int32_t)i.offset, true); + s.write_int32_t_reverse_endianness((int32_t)i.size_compressed, true); + s.write_int32_t_reverse_endianness((int32_t)i.size, true); + } else for (farc_file& i : f->files) { s.write_string_null_terminated(i.name); s.write_int32_t_reverse_endianness((int32_t)i.offset, true); - s.write_int32_t_reverse_endianness((int32_t)(compressed ? i.size_compressed : i.size), true); - s.write_int32_t_reverse_endianness((int32_t)(compressed ? i.size : 0), true); + s.write_int32_t_reverse_endianness((int32_t)i.size, true); + s.write_int32_t_reverse_endianness((int32_t)0, true); } - align = align_val(align, 0x10) - align; - if (mode == FARC_COMPRESS_FArc) { - uint8_t padding[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - s.write(padding, align); - } - else { - uint8_t padding[] = { - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, - }; - s.write(padding, align); - } + farc_write_padding(f, s, header_length + 0x08, mode != FARC_COMPRESS_FArc); } static errno_t farc_read_header(farc* f, stream& s) { - if (!f || s.io.check_null()) + if (!f || s.check_null()) return -1; s.set_position(0, SEEK_SET); - f->signature = (farc_signature)s.read_int32_t_reverse_endianness(true); + f->signature = (farc_signature)s.read_uint32_t_reverse_endianness(true); if (f->signature != FARC_FArc && f->signature != FARC_FArC && f->signature != FARC_FARC) return -2; f->ft = false; - int32_t header_length = s.read_int32_t_reverse_endianness(true); + uint32_t header_length = s.read_uint32_t_reverse_endianness(true); if (f->signature == FARC_FARC) { - f->flags = (farc_flags)s.read_int32_t_reverse_endianness(true); - s.read_int32_t(); - int32_t alignment = s.read_int32_t_reverse_endianness(true); + f->flags = (farc_flags)s.read_uint32_t_reverse_endianness(true); + s.read_uint32_t(); + uint32_t alignment = s.read_uint32_t_reverse_endianness(true); + bool modern = !!s.read_uint32_t_reverse_endianness(true); - f->ft = (f->flags & FARC_AES) && (alignment & (alignment - 1)); - if (f->ft) { - header_length -= 0x08; - s.set_position(-0x04, SEEK_CUR); - } - else - header_length -= 0x0C; + // If alignment is way too big, then it might be part of IV + f->ft = (f->flags & FARC_AES) && modern && alignment > 0x1000; + s.set_position(0x10, SEEK_SET); + header_length -= 0x08; } f->files.clear(); @@ -710,74 +669,85 @@ static errno_t farc_read_header(farc* f, stream& s) { aes128_cbc_decrypt_buffer(&ctx, dt, header_length); header_length -= ((uint8_t*)dt)[header_length - 1]; // PKCS7 Padding - dt += sizeof(int32_t); } - bool has_per_file_flags = false; + if (f->ft) { + f->alignment = load_reverse_endianness_uint32_t((void*)dt); + uint32_t files_count = load_reverse_endianness_uint32_t((void*)(dt + 8)); + uint32_t entry_size = load_reverse_endianness_uint32_t((void*)(dt + 12)); + dt += sizeof(uint32_t) * 4; + + f->files.clear(); + f->files.reserve(files_count); + while ((dt - d_t < header_length + 0x08LL) && files_count) { + size_t length = 0; + while (dt[length]) + length++; + + farc_file ff; + ff.name = std::string((const char*)dt, length); + dt += length + 1; + ff.offset = (size_t)load_reverse_endianness_uint32_t((void*)dt); + ff.size_compressed = (size_t)load_reverse_endianness_uint32_t((void*)(dt + 4)); + ff.size = (size_t)load_reverse_endianness_uint32_t((void*)(dt + 8)); + ff.flags = (farc_flags)load_reverse_endianness_uint32_t((void*)(dt + 12)); + dt += entry_size; + files_count--; + } + + free_def(d_t); + return 0; + } + + size_t entry_size; if (f->signature == FARC_FARC) { - if (load_reverse_endianness_int32_t((void*)dt) == 1) { - dt += sizeof(int32_t); - length = load_reverse_endianness_int32_t((void*)dt); - has_per_file_flags = true; - } - dt += sizeof(int32_t); - } - dt += sizeof(int32_t); + f->alignment = load_reverse_endianness_uint32_t((void*)dt); + uint32_t entry_offset = load_reverse_endianness_uint32_t((void*)(dt + 4)); + uint32_t header_offset = load_reverse_endianness_uint32_t((void*)(dt + 8)); + dt += sizeof(uint32_t) * 3; - if (length == 0) { - size_t count = 0; - uint8_t* position = dt; - size_t size; - if (has_per_file_flags) - size = sizeof(int32_t) * 4; - else if (f->signature != FARC_FArc) - size = sizeof(int32_t) * 3; - else - size = sizeof(int32_t) * 2; - - while (dt - d_t < header_length) { - while (*dt++); - dt += size; - count++; - } - dt = position; - length = (int32_t)count; + entry_size = sizeof(uint32_t) * 3 + entry_offset; } + else if (f->signature != FARC_FArc) { + f->alignment = load_reverse_endianness_uint32_t((void*)dt); + dt += sizeof(uint32_t); + + entry_size = sizeof(uint32_t) * 3; + } + else { + f->alignment = load_reverse_endianness_uint32_t((void*)dt); + dt += sizeof(uint32_t); + + entry_size = sizeof(uint32_t) * 2; + } + + size_t count = 0; + uint8_t* position = dt; + + while (dt - d_t < header_length) { + while (*dt++); + dt += entry_size; + count++; + } + dt = position; bool encrypted = !!(f->flags & FARC_AES); f->files.clear(); - f->files.resize(length); - if (has_per_file_flags) + f->files.resize(count); + if (f->signature != FARC_FArc) for (farc_file& i : f->files) { size_t length = 0; while (dt[length]) length++; i.name = std::string((const char*)dt, length); dt += length + 1; - i.offset = (size_t)load_reverse_endianness_int32_t((void*)dt); - i.size_compressed = (size_t)load_reverse_endianness_int32_t((void*)(dt + 4)); - i.size = (size_t)load_reverse_endianness_int32_t((void*)(dt + 8)); - farc_flags flags = (farc_flags)load_reverse_endianness_int32_t((void*)(dt + 12)); + i.offset = (size_t)load_reverse_endianness_uint32_t((void*)dt); + i.size_compressed = (size_t)load_reverse_endianness_uint32_t((void*)(dt + 4)); + i.size = (size_t)load_reverse_endianness_uint32_t((void*)(dt + 8)); - i.compressed = !!i.size || !!(flags & FARC_GZIP); - i.encrypted = encrypted || !!(flags & FARC_AES); - dt += sizeof(int32_t) * 4; - } - else if (f->signature != FARC_FArc) - for (farc_file& i : f->files) { - size_t length = 0; - while (dt[length]) - length++; - i.name = std::string((const char*)dt, length); - dt += length + 1; - i.offset = (size_t)load_reverse_endianness_int32_t((void*)dt); - i.size_compressed = (size_t)load_reverse_endianness_int32_t((void*)(dt + 4)); - i.size = (size_t)load_reverse_endianness_int32_t((void*)(dt + 8)); - - i.compressed = !!i.size; - i.encrypted = encrypted; - dt += sizeof(int32_t) * 3; + i.flags = (farc_flags)((encrypted ? FARC_AES : 0) | (!!i.size ? FARC_GZIP : 0)); + dt += entry_size; } else for (farc_file& i : f->files) { @@ -786,20 +756,20 @@ static errno_t farc_read_header(farc* f, stream& s) { length++; i.name = std::string((const char*)dt, length); dt += length + 1; - i.offset = (size_t)load_reverse_endianness_int32_t((void*)dt); - i.size = (size_t)load_reverse_endianness_int32_t((void*)(dt + 4)); + i.offset = (size_t)load_reverse_endianness_uint32_t((void*)dt); + i.size = (size_t)load_reverse_endianness_uint32_t((void*)(dt + 4)); i.size_compressed = 0; - i.compressed = false; - i.encrypted = false; + i.flags = (farc_flags)0; dt += sizeof(int32_t) * 2; } - free(d_t); + + free_def(d_t); return 0; } static void farc_unpack_files(farc* f, stream& s, bool save) { - if (!f || s.io.check_null()) + if (!f || s.check_null()) return; size_t max_path_len = 0; @@ -813,7 +783,7 @@ static void farc_unpack_files(farc* f, stream& s, bool save) { if (save) { wchar_t* dir_temp = utf8_to_utf16(f->directory_path.c_str()); CreateDirectoryW(dir_temp, 0); - free(dir_temp); + free_def(dir_temp); } char* temp_path = force_malloc_s(char, max_path_len + 1); @@ -823,15 +793,30 @@ static void farc_unpack_files(farc* f, stream& s, bool save) { for (farc_file& i : f->files) farc_unpack_file(f, s, &i, save, temp_path, dir_len); - free(temp_path); + free_def(temp_path); +} + +static void farc_unpack_file(farc* f, farc_file* ff) { + if (ff->data) + return; + else if (ff->data_compressed) { + deflate::decompress(ff->data_compressed, ff->size_compressed, + &ff->data, &ff->size, deflate::MODE_GZIP); + return; + } + + file_stream s; + s.open(f->file_path.c_str(), "rb"); + if (s.check_not_null()) + farc_unpack_file(f, s, ff); } static void farc_unpack_file(farc* f, stream& s, farc_file* ff, bool save, char* temp_path, size_t dir_len) { - if (!f || s.io.check_null()) + if (!f || s.check_null()) return; if (ff->data) - free(ff->data); + free_def(ff->data); s.set_position(ff->offset, SEEK_SET); @@ -846,13 +831,14 @@ static void farc_unpack_file(farc* f, stream& s, farc_file* ff, bool save, char* deflate::decompress(ff->data_compressed, ff->size_compressed, &ff->data, &ff->size, deflate::MODE_GZIP); } - else if (ff->encrypted || ff->compressed) { - size_t temp_s = ff->encrypted ? align_val(ff->size_compressed, 0x10) : ff->size_compressed; + else if (ff->flags) { + size_t temp_s = ff->flags & FARC_AES + ? align_val(ff->size_compressed, f->alignment) : ff->size_compressed; void* temp = force_malloc(temp_s); s.read(temp, temp_s); void* t = temp; - if (ff->encrypted) + if (ff->flags & FARC_AES) if (f->ft) { temp_s -= 0x10; t = (void*)((uint64_t)t + 0x10); @@ -869,18 +855,18 @@ static void farc_unpack_file(farc* f, stream& s, farc_file* ff, bool save, char* aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)t, temp_s); } - if (!ff->compressed) { - ff->data_compressed = 0; - ff->data = force_malloc(ff->size); - memcpy(ff->data, t, ff->size); - } - else { + if (ff->flags & FARC_GZIP) { ff->data_compressed = force_malloc(ff->size_compressed); memcpy(ff->data_compressed, t, ff->size_compressed); deflate::decompress(ff->data_compressed, ff->size_compressed, &ff->data, &ff->size, deflate::MODE_GZIP); } - free(temp); + else { + ff->data_compressed = 0; + ff->data = force_malloc(ff->size); + memcpy(ff->data, t, ff->size); + } + free_def(temp); } else { ff->data_compressed = 0; @@ -897,17 +883,35 @@ static void farc_unpack_file(farc* f, stream& s, farc_file* ff, bool save, char* memcpy(temp_path + dir_len + 1, ff->name.c_str(), ff->name.size()); temp_path[dir_len + 1 + ff->name.size()] = '\0'; - stream temp_s; + file_stream temp_s; temp_s.open(temp_path, "wb"); - if (temp_s.io.stream) + if (temp_s.check_not_null()) temp_s.write(ff->data, ff->size); } - free(ff->data); + free_def(ff->data); ff->data = 0; } if (ff->data_compressed) { - free(ff->data_compressed); + free_def(ff->data_compressed); ff->data_compressed = 0; } } + +static void farc_write_padding(farc* f, stream& s, size_t size, bool x) { + size_t align = align_val(size, f->alignment) - size; + if (!x) { + uint8_t padding[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + s.write(padding, align); + } + else { + uint8_t padding[] = { + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + }; + s.write(padding, align); + } +} diff --git a/src/KKdLib/farc.hpp b/src/KKdLib/farc.hpp index be24b91a..e3c5cac7 100644 --- a/src/KKdLib/farc.hpp +++ b/src/KKdLib/farc.hpp @@ -8,7 +8,6 @@ #include #include #include "default.hpp" -#include "io/stream.hpp" enum farc_signature { FARC_FArc = 'FArc', @@ -37,8 +36,7 @@ struct farc_file { size_t size_compressed; void* data; void* data_compressed; - bool compressed; - bool encrypted; + farc_flags flags; bool data_changed; farc_file(); @@ -52,6 +50,7 @@ struct farc { farc_signature signature; farc_flags flags; int32_t compression_level; + uint32_t alignment; bool ft; farc(); @@ -65,14 +64,14 @@ struct farc { bool has_file(const char* name); bool has_file(const wchar_t* name); bool has_file(uint32_t hash); - void read(const char* path, bool unpack, bool save); - void read(const wchar_t* path, bool unpack, bool save); - void read(const void* data, size_t size, bool unpack); + void read(const char* path, bool unpack = true, bool save = false); + void read(const wchar_t* path, bool unpack = true, bool save = false); + void read(const void* data, size_t size, bool unpack = true); farc_file* read_file(const char* name); farc_file* read_file(const wchar_t* name); farc_file* read_file(uint32_t hash); - void write(const char* path, farc_compress_mode mode, bool get_files); - void write(const wchar_t* path, farc_compress_mode mode, bool get_files); + void write(const char* path, farc_compress_mode mode, bool get_files = true); + void write(const wchar_t* path, farc_compress_mode mode, bool get_files = true); void write(void** data, size_t* size, farc_compress_mode mode); static bool load_file(void* data, const char* path, const char* file, uint32_t hash); diff --git a/src/KKdLib/half_t.cpp b/src/KKdLib/half_t.cpp index 8483d5a5..0af93ddf 100644 --- a/src/KKdLib/half_t.cpp +++ b/src/KKdLib/half_t.cpp @@ -8,18 +8,6 @@ extern bool f16c; -inline half_t load_reverse_endianness_half_t(void* ptr) { - return (half_t)_byteswap_ushort(*(uint16_t*)ptr); -} - -inline void store_reverse_endianness_half_t(half_t value, void* ptr) { - *(half_t*)ptr = (half_t)_byteswap_ushort((uint16_t)value); -} - -inline half_t reverse_endianness_half_t(half_t value) { - return (half_t)_byteswap_ushort((uint16_t)value); -} - float_t half_to_float(half_t h) { if (f16c) return _mm_cvtss_f32( _mm_cvtph_ps(_mm_cvtsi32_si128((uint16_t)h))); diff --git a/src/KKdLib/half_t.hpp b/src/KKdLib/half_t.hpp index 23615f27..fe765985 100644 --- a/src/KKdLib/half_t.hpp +++ b/src/KKdLib/half_t.hpp @@ -20,9 +20,18 @@ typedef unsigned short half_t; -extern half_t load_reverse_endianness_half_t(void* ptr); -extern void store_reverse_endianness_half_t(half_t value, void* ptr); -extern half_t reverse_endianness_half_t(half_t value); +inline half_t load_reverse_endianness_half_t(void* ptr) { + return (half_t)_byteswap_ushort(*(uint16_t*)ptr); +} + +inline void store_reverse_endianness_half_t(void* ptr, half_t value) { + *(half_t*)ptr = (half_t)_byteswap_ushort((uint16_t)value); +} + +inline half_t reverse_endianness_half_t(half_t value) { + return (half_t)_byteswap_ushort((uint16_t)value); +} + extern float_t half_to_float(half_t h); extern half_t float_to_half(float_t val); extern double_t half_to_double(half_t h); diff --git a/src/KKdLib/hash.cpp b/src/KKdLib/hash.cpp index d3bbf586..743c2f39 100644 --- a/src/KKdLib/hash.cpp +++ b/src/KKdLib/hash.cpp @@ -50,37 +50,26 @@ const uint32_t hash_murmurhash_null = 0x5A009B23; const uint32_t hash_crc16_ccitt_empty = 0xFFFF; string_hash::string_hash() { - hash = hash_murmurhash_empty; + hash_fnv1a64m = hash_fnv1a64m_empty; + hash_murmurhash = hash_murmurhash_empty; } string_hash::string_hash(const char* str) { - this->str = str; - this->hash = hash_string_murmurhash(this->str); -} - -string_hash::string_hash(const char* str, uint32_t hash) { - this->str = str; - this->hash = hash; + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); } string_hash::string_hash(std::string& str) { - this->str = str; - this->hash = hash_string_murmurhash(this->str); + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); } string_hash::string_hash(std::string&& str) { - this->str = str; - this->hash = hash_string_murmurhash(this->str); -} - -string_hash::string_hash(std::string& str, uint32_t hash) { - this->str = str; - this->hash = hash; -} - -string_hash::string_hash(std::string&& str, uint32_t hash) { - this->str = str; - this->hash = hash; + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); } string_hash::~string_hash() { @@ -93,47 +82,23 @@ const char* string_hash::c_str() { // FNV 1a 64-bit Modified // 0x1403B04D0 in SBZV_7.10 -constexpr uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper) { +uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper) { const uint8_t* d = (const uint8_t*)data; uint64_t hash = 0xCBF29CE484222325; if (data) - if (make_upper) // Modification for only uppercase latin text - for (size_t i = size; i; i--) { - uint8_t a = *d++; - if (a > 0x60 && a < 0x7B) - a -= 0x20; - hash ^= a; - hash *= 0x100000001B3; - } - else - for (size_t i = size; i; i--) { - hash ^= *d++; - hash *= 0x100000001B3; - } + for (size_t i = size; i; i--) { + hash ^= *d++; + hash *= 0x100000001B3; + } return (hash >> 32) ^ hash; // Actual Modification } -constexpr uint64_t hash_utf8_fnv1a64m(const char* data, bool make_upper) { - return hash_fnv1a64m(data, utf8_length(data), make_upper); -} - -inline uint64_t hash_utf16_fnv1a64m(const wchar_t* data, bool make_upper) { - char* temp = utf16_to_utf8(data); - uint64_t hash = hash_fnv1a64m(temp, utf8_length(temp), make_upper); - free(temp); - return hash; -} - -constexpr uint64_t hash_string_fnv1a64m(const std::string& data, bool make_upper) { - return hash_fnv1a64m(data.c_str(), data.size(), make_upper); -} - // MurmurHash // 0x814D7A9C in PCSB00554 // 0x8134C304 in PCSB01007 // 0x0069CEA4 in NPEB02013 -constexpr uint32_t hash_murmurhash(const void* data, size_t size, +uint32_t hash_murmurhash(const void* data, size_t size, uint32_t seed, bool upper, bool big_endian) { const uint8_t* d = (const uint8_t*)data; @@ -264,24 +229,9 @@ constexpr uint32_t hash_murmurhash(const void* data, size_t size, return hash; } -constexpr uint32_t hash_utf8_murmurhash(const char* data, uint32_t seed, bool upper) { - return hash_murmurhash(data, utf8_length(data), seed, upper); -} - -inline uint32_t hash_utf16_murmurhash(const wchar_t* data, uint32_t seed, bool upper) { - char* temp = utf16_to_utf8(data); - uint32_t hash = hash_murmurhash(temp, utf8_length(temp), seed, upper); - free(temp); - return hash; -} - -constexpr uint32_t hash_string_murmurhash(const std::string& data, uint32_t seed, bool upper) { - return hash_murmurhash(data.c_str(), data.size(), seed, upper); -} - // CRC16-CCITT // 0x140011A90 in SBZV_7.10 -constexpr uint16_t hash_crc16_ccitt(const void* data, size_t size, bool make_upper) { +uint16_t hash_crc16_ccitt(const void* data, size_t size, bool make_upper) { const uint8_t* d = (const uint8_t*)data; uint16_t hash = 0xFFFF; @@ -297,18 +247,3 @@ constexpr uint16_t hash_crc16_ccitt(const void* data, size_t size, bool make_upp hash = (uint16_t)(hash_crc16_ccitt_table[(hash >> 8) ^ *d++] ^ (hash << 8)); return hash; } - -constexpr uint16_t hash_utf8_crc16_ccitt(const char* data, bool make_upper) { - return hash_crc16_ccitt(data, utf8_length(data), make_upper); -} - -inline uint16_t hash_utf16_crc16_ccitt(const wchar_t* data, bool make_upper) { - char* temp = utf16_to_utf8(data); - uint32_t hash = hash_crc16_ccitt(temp, utf8_length(temp), make_upper); - free(temp); - return hash; -} - -constexpr uint16_t hash_string_crc16_ccitt(const std::string& data, bool make_upper) { - return hash_crc16_ccitt(data.c_str(), data.size(), make_upper); -} diff --git a/src/KKdLib/hash.hpp b/src/KKdLib/hash.hpp index b7be8dec..6f4ea430 100644 --- a/src/KKdLib/hash.hpp +++ b/src/KKdLib/hash.hpp @@ -19,30 +19,64 @@ extern const uint32_t hash_crc16_ccitt_empty; struct string_hash { std::string str; - uint32_t hash; + uint64_t hash_fnv1a64m; + uint32_t hash_murmurhash; string_hash(); string_hash(const char* str); - string_hash(const char* str, uint32_t hash); string_hash(std::string& str); string_hash(std::string&& str); - string_hash(std::string& str, uint32_t hash); - string_hash(std::string&& str, uint32_t hash); ~string_hash(); const char* c_str(); }; -extern constexpr uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper = false); -extern constexpr uint64_t hash_utf8_fnv1a64m(const char* data, bool make_upper = false); -extern inline uint64_t hash_utf16_fnv1a64m(const wchar_t* data, bool make_upper = false); -extern constexpr uint64_t hash_string_fnv1a64m(const std::string& data, bool make_upper = false); -extern constexpr uint32_t hash_murmurhash(const void* data, size_t size, +extern uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper = false); +extern uint32_t hash_murmurhash(const void* data, size_t size, uint32_t seed = 0, bool upper = false, bool big_endian = false); -extern constexpr uint32_t hash_utf8_murmurhash(const char* data, uint32_t seed = 0, bool upper = false); -extern inline uint32_t hash_utf16_murmurhash(const wchar_t* data, uint32_t seed = 0, bool upper = false); -extern constexpr uint32_t hash_string_murmurhash(const std::string& data, uint32_t seed = 0, bool upper = false); -extern constexpr uint16_t hash_crc16_ccitt(const void* data, size_t size, bool make_upper = false); -extern constexpr uint16_t hash_utf8_crc16_ccitt(const char* data, bool make_upper = false); -extern inline uint16_t hash_utf16_crc16_ccitt(const wchar_t* data, bool make_upper = false); -extern constexpr uint16_t hash_string_crc16_ccitt(const std::string& data, bool make_upper = false); +extern uint16_t hash_crc16_ccitt(const void* data, size_t size, bool make_upper = false); + +inline uint64_t hash_utf8_fnv1a64m(const char* data, bool make_upper = false) { + return hash_fnv1a64m(data, utf8_length(data), make_upper); +} + +inline uint64_t hash_utf16_fnv1a64m(const wchar_t* data, bool make_upper = false) { + char* temp = utf16_to_utf8(data); + uint64_t hash = hash_fnv1a64m(temp, utf8_length(temp), make_upper); + free_def(temp); + return hash; +} + +inline uint64_t hash_string_fnv1a64m(const std::string& data, bool make_upper = false) { + return hash_fnv1a64m(data.c_str(), data.size(), make_upper); +} + +inline uint32_t hash_utf8_murmurhash(const char* data, uint32_t seed = 0, bool upper = false) { + return hash_murmurhash(data, utf8_length(data), seed, upper); +} + +inline uint32_t hash_utf16_murmurhash(const wchar_t* data, uint32_t seed = 0, bool upper = false) { + char* temp = utf16_to_utf8(data); + uint32_t hash = hash_murmurhash(temp, utf8_length(temp), seed, upper); + free_def(temp); + return hash; +} + +inline uint32_t hash_string_murmurhash(const std::string& data, uint32_t seed = 0, bool upper = false) { + return hash_murmurhash(data.c_str(), data.size(), seed, upper); +} + +inline uint16_t hash_utf8_crc16_ccitt(const char* data, bool make_upper = false) { + return hash_crc16_ccitt(data, utf8_length(data), make_upper); +} + +inline uint16_t hash_utf16_crc16_ccitt(const wchar_t* data, bool make_upper = false) { + char* temp = utf16_to_utf8(data); + uint32_t hash = hash_crc16_ccitt(temp, utf8_length(temp), make_upper); + free_def(temp); + return hash; +} + +inline uint16_t hash_string_crc16_ccitt(const std::string& data, bool make_upper = false) { + return hash_crc16_ccitt(data.c_str(), data.size(), make_upper); +} diff --git a/src/KKdLib/image.cpp b/src/KKdLib/image.cpp index e8b13d03..f9075725 100644 --- a/src/KKdLib/image.cpp +++ b/src/KKdLib/image.cpp @@ -4,12 +4,16 @@ */ #include "image.hpp" -; + static rgb565 rgb565_apply_color_tone(rgb565 col, color_tone* col_tone); static void rgb_to_ycc(vec3& rgb, vec3& ycc); static void ycc_apply_col_tone_hue(vec3& ycc, color_tone* col_tone); static void ycc_to_rgb(vec3& ycc, vec3& rgb); +color_tone::color_tone() : hue(), saturation(), value(), contrast(), inverse() { + +} + void dxt1_image_apply_color_tone(int32_t width, int32_t height, int32_t size, dxt1_block* data, color_tone* col_tone) { if (size <= 0) @@ -71,24 +75,20 @@ static rgb565 rgb565_apply_color_tone(rgb565 col, color_tone* col_tone) { rgb.z = (float_t)col.b; } - vec3_mult(rgb, inv_scale, rgb); - vec3_mult(rgb, col_tone->blend, rgb); - vec3_add(rgb, col_tone->offset, rgb); - vec3_clamp_scalar(rgb, 0.0f, 1.0f, rgb); + rgb = vec3::clamp(rgb * inv_scale * col_tone->blend + col_tone->offset, 0.0f, 1.0f); vec3 ycc; rgb_to_ycc(rgb, ycc); - vec2_mult_scalar(*(vec2*)&ycc.y, col_tone->saturation, *(vec2*)&ycc.y); + *(vec2*)&ycc.y = *(vec2*)&ycc.y * col_tone->saturation; ycc_apply_col_tone_hue(ycc, col_tone); ycc.x = (ycc.x + col_tone->value - 0.5f) * col_tone->contrast + 0.5f; - ycc.x = clamp(ycc.x, 0.0f, 1.0f); - vec2_clamp_scalar(*(vec2*)&ycc.y, -0.5f, 0.5f, *(vec2*)&ycc.y); + ycc.x = clamp_def(ycc.x, 0.0f, 1.0f); + *(vec2*)&ycc.y = vec2::clamp(*(vec2*)&ycc.y, -0.5f, 0.5f); ycc_to_rgb(ycc, rgb); - vec3_clamp_scalar(rgb, 0.0f, 1.0f, rgb); - vec3_mult(rgb, scale, rgb); + rgb = vec3::clamp(rgb, 0.0f, 1.0f) * scale; col.r = (uint8_t)rgb.x; col.g = (uint8_t)rgb.y; @@ -101,9 +101,9 @@ inline static void rgb_to_ycc(vec3& rgb, vec3& ycc) { const vec3 _cb_coef_601 = { -0.16874f, -0.33126f, 0.5f }; const vec3 _cr_coef_601 = { 0.5f, -0.41869f, -0.08131f }; - vec3_dot(rgb, _y_coef_601, ycc.x); - vec3_dot(rgb, _cb_coef_601, ycc.y); - vec3_dot(rgb, _cr_coef_601, ycc.z); + ycc.x = vec3::dot(rgb, _y_coef_601); + ycc.y = vec3::dot(rgb, _cb_coef_601); + ycc.z = vec3::dot(rgb, _cr_coef_601); } inline static void ycc_apply_col_tone_hue(vec3& ycc, color_tone* col_tone) { @@ -119,7 +119,7 @@ inline static void ycc_to_rgb(vec3& ycc, vec3& rgb) { const vec3 _grn_coef_601 = { 1.0f, -0.34414f, -0.71414f }; const vec3 _blu_coef_601 = { 1.0f, 1.772f, 0.0f }; - vec3_dot(ycc, _red_coef_601, rgb.x); - vec3_dot(ycc, _grn_coef_601, rgb.y); - vec3_dot(ycc, _blu_coef_601, rgb.z); + rgb.x = vec3::dot(ycc, _red_coef_601); + rgb.y = vec3::dot(ycc, _grn_coef_601); + rgb.z = vec3::dot(ycc, _blu_coef_601); } \ No newline at end of file diff --git a/src/KKdLib/image.hpp b/src/KKdLib/image.hpp index 9d9734e9..16fb1e0c 100644 --- a/src/KKdLib/image.hpp +++ b/src/KKdLib/image.hpp @@ -16,6 +16,8 @@ struct color_tone { float_t value; float_t contrast; bool inverse; + + color_tone(); }; struct rgb565 { diff --git a/src/KKdLib/interpolation.cpp b/src/KKdLib/interpolation.cpp index da4b3af0..c495e8bb 100644 --- a/src/KKdLib/interpolation.cpp +++ b/src/KKdLib/interpolation.cpp @@ -5,199 +5,10 @@ #include "interpolation.hpp" -inline float_t interpolate_linear_value(float_t p1, float_t p2, float_t f1, float_t f2, float_t f) { - float_t t = (f - f1) / (f2 - f1); - return (1.0f - t) * p1 + t * p2; -} - -inline void interpolate_linear_value_vec2(vec2* p1, vec2* p2, vec2* f1, vec2* f2, vec2* f, vec2* value) { - __m128 _p1; - __m128 _p2; - __m128 _f1; - __m128 _f2; - __m128 _f; - *(vec2*)&_p1 = *p1; - *(vec2*)&_p2 = *p2; - *(vec2*)&_f1 = *f1; - *(vec2*)&_f2 = *f2; - *(vec2*)&_f = *f; - - const __m128 _1 = _mm_set_ps1(1.0f); - - __m128 df = _mm_sub_ps(_f2, _f1); - __m128 t = _mm_div_ps(_mm_sub_ps(_f, _f1), df); - __m128 t1 = _mm_sub_ps(_1, t); - __m128 val = _mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t)); - *value = *(vec2*)&val; -} - -inline void interpolate_linear_value_vec3(vec3* p1, vec3* p2, vec3* f1, vec3* f2, vec3* f, vec3* value) { - __m128 _p1; - __m128 _p2; - __m128 _f1; - __m128 _f2; - __m128 _f; - *(vec3*)&_p1 = *p1; - *(vec3*)&_p2 = *p2; - *(vec3*)&_f1 = *f1; - *(vec3*)&_f2 = *f2; - *(vec3*)&_f = *f; - - const __m128 _1 = _mm_set_ps1(1.0f); - - __m128 df = _mm_sub_ps(_f2, _f1); - __m128 t = _mm_div_ps(_mm_sub_ps(_f, _f1), df); - __m128 t1 = _mm_sub_ps(_1, t); - __m128 val = _mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t)); - *value = *(vec3*)&val; -} - -inline void interpolate_linear_value_vec4(vec4* p1, vec4* p2, vec4* f1, vec4* f2, vec4* f, vec4* value) { - __m128 _p1; - __m128 _p2; - __m128 _f1; - __m128 _f2; - __m128 _f; - _p1 = _mm_loadu_ps((float*)p1); - _p2 = _mm_loadu_ps((float*)p2); - _f1 = _mm_loadu_ps((float*)f1); - _f2 = _mm_loadu_ps((float*)f2); - _f = _mm_loadu_ps((float*)f); - - const __m128 _1 = _mm_set_ps1(1.0f); - - __m128 df = _mm_sub_ps(_f2, _f1); - __m128 t = _mm_div_ps(_mm_sub_ps(_f, _f1), df); - __m128 t1 = _mm_sub_ps(_1, t); - _mm_storeu_ps((float*)value, _mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t))); -} - -inline void interpolate_linear(float_t p1, float_t p2, - size_t f1, size_t f2, float_t** arr, size_t* length) { - *length = f2 - f1 + 1; - *arr = force_malloc_s(float_t, *length); - - float_t* a = *arr; - float_t l = (float_t)*length; - for (size_t i = 0; i < l; i++, a++) - *a = interpolate_linear_value(p1, p2, - (float_t)f1, (float_t)f2, (float_t)(f1 + i)); -} - -inline float_t interpolate_chs_value(float_t p1, float_t p2, - float_t t1, float_t t2, float_t f1, float_t f2, float_t f) { - float_t df = f - f1; - float_t t = df / (f2 - f1); - float_t t_1 = t - 1.0f; - return p1 + t * t * (3.0f - 2.0f * t) * (p2 - p1) + (t_1 * t1 + t * t2) * df * t_1; -} - -inline void interpolate_chs_value_vec2(vec2* p1, vec2* p2, - vec2* t1, vec2* t2, vec2* f1, vec2* f2, vec2* f, vec2* value) { - __m128 _p1; - __m128 _p2; - __m128 _t1; - __m128 _t2; - __m128 _f1; - __m128 _f2; - __m128 _f; - *(vec2*)&_p1 = *p1; - *(vec2*)&_p2 = *p2; - *(vec2*)&_t1 = *t1; - *(vec2*)&_t2 = *t2; - *(vec2*)&_f1 = *f1; - *(vec2*)&_f2 = *f2; - *(vec2*)&_f = *f; - - const __m128 _1 = _mm_set_ps1(1.0f); - const __m128 _2 = _mm_set_ps1(2.0f); - const __m128 _3 = _mm_set_ps1(3.0f); - - __m128 df = _mm_sub_ps(_f, _f1); - __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); - __m128 t_1 = _mm_sub_ps(t, _1); - - __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); - __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); - __m128 val = _mm_add_ps(_mm_add_ps(_p1, delta), tangent); - *value = *(vec2*)&val; -} - -inline void interpolate_chs_value_vec3(vec3* p1, vec3* p2, vec3* t1, - vec3* t2, vec3* f1, vec3* f2, vec3* f, vec3* value) { - __m128 _p1; - __m128 _p2; - __m128 _t1; - __m128 _t2; - __m128 _f1; - __m128 _f2; - __m128 _f; - *(vec3*)&_p1 = *p1; - *(vec3*)&_p2 = *p2; - *(vec3*)&_t1 = *t1; - *(vec3*)&_t2 = *t2; - *(vec3*)&_f1 = *f1; - *(vec3*)&_f2 = *f2; - *(vec3*)&_f = *f; - - const __m128 _1 = _mm_set_ps1(1.0f); - const __m128 _2 = _mm_set_ps1(2.0f); - const __m128 _3 = _mm_set_ps1(3.0f); - - __m128 df = _mm_sub_ps(_f, _f1); - __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); - __m128 t_1 = _mm_sub_ps(t, _1); - - __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); - __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); - __m128 val = _mm_add_ps(_mm_add_ps(_p1, delta), tangent); - *value = *(vec3*)&val; -} - -inline void interpolate_chs_value_vec4(vec4* p1, vec4* p2, - vec4* t1, vec4* t2, vec4* f1, vec4* f2, vec4* f, vec4* value) { - __m128 _p1; - __m128 _p2; - __m128 _t1; - __m128 _t2; - __m128 _f1; - __m128 _f2; - __m128 _f; - _p1 = _mm_loadu_ps((float*)p1); - _p2 = _mm_loadu_ps((float*)p2); - _t1 = _mm_loadu_ps((float*)t1); - _t2 = _mm_loadu_ps((float*)t2); - _f1 = _mm_loadu_ps((float*)f1); - _f2 = _mm_loadu_ps((float*)f2); - _f = _mm_loadu_ps((float*)f); - - const __m128 _1 = _mm_set_ps1(1.0f); - const __m128 _2 = _mm_set_ps1(2.0f); - const __m128 _3 = _mm_set_ps1(3.0f); - - __m128 df = _mm_sub_ps(_f, _f1); - __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); - __m128 t_1 = _mm_sub_ps(t, _1); - - __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); - __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); - _mm_storeu_ps((float*)value, _mm_add_ps(_mm_add_ps(_p1, delta), tangent)); -} - -inline void interpolate_chs(float_t p1, float_t p2, - float_t t1, float_t t2, size_t f1, size_t f2, float_t** arr, size_t* length) { - *length = f2 - f1 + 1; - *arr = force_malloc_s(float_t, *length); - - float_t* a = *arr; - float_t l = (float_t)*length; - for (size_t i = 0; i < l; i++, a++) - *a = interpolate_chs_value(p1, p2, t1, t2, (float_t)f1, (float_t)f2, (float_t)(f1 + i)); -} - void interpolate_chs_reverse_value(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2, size_t f) { - *t1 = *t2 = 0.0f; + float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f) { + t1 = 0.0f; + t2 = 0.0f; if (!arr || length < 2 || f - f1 + 1 >= length || f < 1 || f < f1 || f + 2 > f2) return; @@ -214,13 +25,15 @@ void interpolate_chs_reverse_value(float_t* arr, size_t length, t1_t2_1 /= df_1 * t1_1; t1_t2_2 /= df_2 * t2_1; - *t1 = (t1_t2_1 * _t2 - t1_t2_2 * _t1) / (_t1 - _t2); - *t2 = (-t1_t2_1 * t2_1 + t1_t2_2 * t1_1) / (_t1 - _t2); + t1 = (t1_t2_1 * _t2 - t1_t2_2 * _t1) / (_t1 - _t2); + t2 = (-t1_t2_1 * t2_1 + t1_t2_2 * t1_1) / (_t1 - _t2); } void interpolate_chs_reverse(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2) { - *t1 = *t2 = 0.0f; + float_t& t1, float_t& t2, size_t f1, size_t f2) { + t1 = 0.0f; + t2 = 0.0f; + if (f2 - f1 - 2 < 1) return; @@ -229,17 +42,18 @@ void interpolate_chs_reverse(float_t* arr, size_t length, double_t tt1 = 0.0; double_t tt2 = 0.0; for (size_t i = f1 + 1; i < f2 - 1; i++) { - interpolate_chs_reverse_value(arr, length, &_t1, &_t2, f1, f2, i); + interpolate_chs_reverse_value(arr, length, _t1, _t2, f1, f2, i); tt1 += _t1; tt2 += _t2; } - *t1 = (float_t)(tt1 / (double_t)(f2 - f1 - 2)); - *t2 = (float_t)(tt2 / (double_t)(f2 - f1 - 2)); + t1 = (float_t)(tt1 / (double_t)(f2 - f1 - 2)); + t2 = (float_t)(tt2 / (double_t)(f2 - f1 - 2)); } void interpolate_chs_reverse_step_value(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2, size_t f, uint8_t step) { - *t1 = *t2 = 0.0f; + float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f, uint8_t step) { + t1 = 0.0f; + t2 = 0.0f; if (!arr || length < 2 || f - f1 + 1 >= length || f < 1 || f < f1 || f + 2 > f2) return; @@ -256,13 +70,15 @@ void interpolate_chs_reverse_step_value(float_t* arr, size_t length, t1_t2_1 /= df_1 * t1_1; t1_t2_2 /= df_2 * t2_1; - *t1 = (t1_t2_1 * _t2 - t1_t2_2 * _t1) / (_t1 - _t2); - *t2 = (-t1_t2_1 * t2_1 + t1_t2_2 * t1_1) / (_t1 - _t2); + t1 = (t1_t2_1 * _t2 - t1_t2_2 * _t1) / (_t1 - _t2); + t2 = (-t1_t2_1 * t2_1 + t1_t2_2 * t1_1) / (_t1 - _t2); } void interpolate_chs_reverse_step(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2, uint8_t step) { - *t1 = *t2 = 0.0f; + float_t& t1, float_t& t2, size_t f1, size_t f2, uint8_t step) { + t1 = 0.0f; + t2 = 0.0f; + if (f2 - f1 - 2 < 1) return; @@ -271,12 +87,12 @@ void interpolate_chs_reverse_step(float_t* arr, size_t length, double_t tt1 = 0.0; double_t tt2 = 0.0; for (size_t i = f1 + 1; i < f2 - 1; i++) { - interpolate_chs_reverse_step_value(arr, length, &_t1, &_t2, f1, f2, i, step); + interpolate_chs_reverse_step_value(arr, length, _t1, _t2, f1, f2, i, step); tt1 += _t1; tt2 += _t2; } - *t1 = (float_t)(tt1 / (double_t)(f2 - f1 - 2)); - *t2 = (float_t)(tt2 / (double_t)(f2 - f1 - 2)); + t1 = (float_t)(tt1 / (double_t)(f2 - f1 - 2)); + t2 = (float_t)(tt2 / (double_t)(f2 - f1 - 2)); } int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std::vector& values) { @@ -350,7 +166,7 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: for (size_t j = 1; j < i; j++) { float_t _t1 = 0.0f; float_t _t2 = 0.0f; - interpolate_chs_reverse_value(a, left_count, &_t1, &_t2, 0, i, j); + interpolate_chs_reverse_value(a, left_count, _t1, _t2, 0, i, j); tt1 += _t1; tt2 += _t2; } @@ -366,7 +182,7 @@ int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std:: } } - if (fabsf(t1) > 1.0f || fabsf(t2) > 1.0f) + if (fabsf(t1) > 0.5f || fabsf(t2) > 0.5f) has_error = true; if (!has_error) { diff --git a/src/KKdLib/interpolation.hpp b/src/KKdLib/interpolation.hpp index 49fdde09..e5f64b03 100644 --- a/src/KKdLib/interpolation.hpp +++ b/src/KKdLib/interpolation.hpp @@ -10,27 +10,200 @@ #include "vec.hpp" #include -extern float_t interpolate_linear_value(float_t p1, float_t p2, float_t f1, float_t f2, float_t f); -extern void interpolate_linear_value_vec2(vec2* p1, vec2* p2, vec2* f1, vec2* f2, vec2* f, vec2* value); -extern void interpolate_linear_value_vec3(vec3* p1, vec3* p2, vec3* f1, vec3* f2, vec3* f, vec3* value); -extern void interpolate_linear_value_vec4(vec4* p1, vec4* p2, vec4* f1, vec4* f2, vec4* f, vec4* value); -extern void interpolate_linear(float_t p1, float_t p2, size_t f1, size_t f2, float_t** arr, size_t* length); -extern float_t interpolate_chs_value(float_t p1, float_t p2, - float_t t1, float_t t2, float_t f1, float_t f2, float_t f); -extern void interpolate_chs_value_vec2(vec2* p1, vec2* p2, - vec2* t1, vec2* t2, vec2* f1, vec2* f2, vec2* f, vec2* value); -extern void interpolate_chs_value_vec3(vec3* p1, vec3* p2, - vec3* t1, vec3* t2, vec3* f1, vec3* f2, vec3* f, vec3* value); -extern void interpolate_chs_value_vec4(vec4* p1, vec4* p2, - vec4* t1, vec4* t2, vec4* f1, vec4* f2, vec4* f, vec4* value); -extern void interpolate_chs(float_t p1, float_t p2, - float_t t1, float_t t2, size_t f1, size_t f2, float_t** arr, size_t* length); +inline float_t interpolate_linear_value(const float_t p1, const float_t p2, + const float_t f1, const float_t f2, const float_t f) { + float_t t = (f - f1) / (f2 - f1); + return (1.0f - t) * p1 + t * p2; +} + +inline vec2 interpolate_linear_value(const vec2 p1, const vec2 p2, + const vec2 f1, const vec2 f2, const vec2 f) { + __m128 _p1; + __m128 _p2; + __m128 _f1; + __m128 _f2; + __m128 _f; + _p1 = vec2::load_xmm(p1); + _p2 = vec2::load_xmm(p2); + _f1 = vec2::load_xmm(f1); + _f2 = vec2::load_xmm(f2); + _f = vec2::load_xmm(f); + + const __m128 _1 = vec4::load_xmm(1.0f); + + __m128 df = _mm_sub_ps(_f2, _f1); + __m128 t = _mm_div_ps(_mm_sub_ps(_f, _f1), df); + __m128 t1 = _mm_sub_ps(_1, t); + return vec2::store_xmm(_mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t))); +} + +inline vec3 interpolate_linear_value(const vec3 p1, const vec3 p2, + const vec3 f1, const vec3 f2, const vec3 f) { + __m128 _p1; + __m128 _p2; + __m128 _f1; + __m128 _f2; + __m128 _f; + _p1 = vec3::load_xmm(p1); + _p2 = vec3::load_xmm(p2); + _f1 = vec3::load_xmm(f1); + _f2 = vec3::load_xmm(f2); + _f = vec3::load_xmm(f); + + const __m128 _1 = vec4::load_xmm(1.0f); + + __m128 df = _mm_sub_ps(_f2, _f1); + __m128 t = _mm_div_ps(_mm_sub_ps(_f, _f1), df); + __m128 t1 = _mm_sub_ps(_1, t); + return vec3::store_xmm(_mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t))); +} + +inline vec4 interpolate_linear_value(const vec4 p1, const vec4 p2, + const vec4 f1, const vec4 f2, const vec4 f) { + __m128 _p1; + __m128 _p2; + __m128 _f1; + __m128 _f2; + __m128 _f; + _p1 = vec4::load_xmm(p1); + _p2 = vec4::load_xmm(p2); + _f1 = vec4::load_xmm(f1); + _f2 = vec4::load_xmm(f2); + _f = vec4::load_xmm(f); + + const __m128 _1 = vec4::load_xmm(1.0f); + + __m128 df = _mm_sub_ps(_f2, _f1); + __m128 t = _mm_div_ps(_mm_sub_ps(_f, _f1), df); + __m128 t1 = _mm_sub_ps(_1, t); + return vec4::store_xmm(_mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t))); +} + +inline std::vector interpolate_linear(float_t p1, float_t p2, size_t f1, size_t f2) { + size_t length = f2 - f1 + 1; + std::vector arr(length); + float_t* a = arr.data(); + for (size_t i = 0, j = length; j; i++, j--, a++) + *a = interpolate_linear_value(p1, p2, + (float_t)f1, (float_t)f2, (float_t)(f1 + i)); + return arr; +} + +inline float_t interpolate_chs_value(const float_t p1, const float_t p2, + const float_t t1, const float_t t2, const float_t f1, const float_t f2, const float_t f) { + float_t df = f - f1; + float_t t = df / (f2 - f1); + float_t t_1 = t - 1.0f; + return p1 + t * t * (3.0f - 2.0f * t) * (p2 - p1) + (t_1 * t1 + t * t2) * df * t_1; +} + +inline vec2 interpolate_chs_value(const vec2 p1, const vec2 p2, + const vec2 t1, const vec2 t2, const vec2 f1, const vec2 f2, const vec2 f) { + __m128 _p1; + __m128 _p2; + __m128 _t1; + __m128 _t2; + __m128 _f1; + __m128 _f2; + __m128 _f; + _p1 = vec2::load_xmm(p1); + _p2 = vec2::load_xmm(p2); + _t1 = vec2::load_xmm(t1); + _t2 = vec2::load_xmm(t2); + _f1 = vec2::load_xmm(f1); + _f2 = vec2::load_xmm(f2); + _f = vec2::load_xmm(f); + + const __m128 _1 = vec4::load_xmm(1.0f); + const __m128 _2 = vec4::load_xmm(2.0f); + const __m128 _3 = vec4::load_xmm(3.0f); + + __m128 df = _mm_sub_ps(_f, _f1); + __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); + __m128 t_1 = _mm_sub_ps(t, _1); + + __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); + __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); + return vec2::store_xmm(_mm_add_ps(_mm_add_ps(_p1, delta), tangent)); +} + +inline vec3 interpolate_chs_value(const vec3 p1, const vec3 p2, + const vec3 t1, const vec3 t2, const vec3 f1, const vec3 f2, const vec3 f) { + __m128 _p1; + __m128 _p2; + __m128 _t1; + __m128 _t2; + __m128 _f1; + __m128 _f2; + __m128 _f; + _p1 = vec3::load_xmm(p1); + _p2 = vec3::load_xmm(p2); + _t1 = vec3::load_xmm(t1); + _t2 = vec3::load_xmm(t2); + _f1 = vec3::load_xmm(f1); + _f2 = vec3::load_xmm(f2); + _f = vec3::load_xmm(f); + + const __m128 _1 = vec4::load_xmm(1.0f); + const __m128 _2 = vec4::load_xmm(2.0f); + const __m128 _3 = vec4::load_xmm(3.0f); + + __m128 df = _mm_sub_ps(_f, _f1); + __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); + __m128 t_1 = _mm_sub_ps(t, _1); + + __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); + __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); + return vec3::store_xmm(_mm_add_ps(_mm_add_ps(_p1, delta), tangent)); +} + +inline vec4 interpolate_chs_value(const vec4 p1, const vec4 p2, + const vec4 t1, const vec4 t2, const vec4 f1, const vec4 f2, const vec4 f) { + __m128 _p1; + __m128 _p2; + __m128 _t1; + __m128 _t2; + __m128 _f1; + __m128 _f2; + __m128 _f; + _p1 = vec4::load_xmm(p1); + _p2 = vec4::load_xmm(p2); + _t1 = vec4::load_xmm(t1); + _t2 = vec4::load_xmm(t2); + _f1 = vec4::load_xmm(f1); + _f2 = vec4::load_xmm(f2); + _f = vec4::load_xmm(f); + + const __m128 _1 = vec4::load_xmm(1.0f); + const __m128 _2 = vec4::load_xmm(2.0f); + const __m128 _3 = vec4::load_xmm(3.0f); + + __m128 df = _mm_sub_ps(_f, _f1); + __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); + __m128 t_1 = _mm_sub_ps(t, _1); + + __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); + __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); + return vec4::store_xmm(_mm_add_ps(_mm_add_ps(_p1, delta), tangent)); +} + +inline std::vector interpolate_chs(const float_t p1, const float_t p2, + const float_t t1, const float_t t2, const size_t f1, const size_t f2) { + size_t length = f2 - f1 + 1; + std::vector arr(length); + float_t* a = arr.data(); + for (size_t i = 0, j = length; j; i++, j--, a++) + *a = interpolate_chs_value(p1, p2, t1, t2, + (float_t)f1, (float_t)f2, (float_t)(f1 + i)); + return arr; +} + extern void interpolate_chs_reverse_value(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2, size_t f); + float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f); extern void interpolate_chs_reverse(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2); + float_t& t1, float_t& t2, size_t f1, size_t f2); extern void interpolate_chs_reverse_step_value(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2, size_t f, uint8_t step); + float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f, uint8_t step); extern void interpolate_chs_reverse_step(float_t* arr, size_t length, - float_t* t1, float_t* t2, size_t f1, size_t f2, uint8_t step); + float_t& t1, float_t& t2, size_t f1, size_t f2, uint8_t step); extern int32_t interpolate_chs_reverse_sequence(std::vector& values_src, std::vector& values); diff --git a/src/KKdLib/io/file_stream.cpp b/src/KKdLib/io/file_stream.cpp new file mode 100644 index 00000000..6fac13d7 --- /dev/null +++ b/src/KKdLib/io/file_stream.cpp @@ -0,0 +1,176 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "file_stream.hpp" +#include + +file_stream::file_stream() : stream() { + +} + +file_stream::~file_stream() { + close(); +} + +int file_stream::flush() { + return fflush(stream); +} + +void file_stream::close() { + if (!this) + return; + + if (stream) { + fflush(stream); + fclose(stream); + stream = 0; + } + stream::close(); +} + +bool file_stream::check_null() { + return !stream; +} + +bool file_stream::check_not_null() { + return !!stream; +} + +void file_stream::align_read(size_t align) { + int64_t position = _ftelli64(stream); + size_t temp_align = align - position % align; + if (align != temp_align) + _fseeki64(stream, position + temp_align, 0); +} + +void file_stream::align_write(size_t align) { + int64_t position = _ftelli64(stream); + size_t temp_align = align - position % align; + if (align != temp_align) { + memset(buf, 0, min_def(sizeof(buf), temp_align)); + size_t i = temp_align; + while (i >= sizeof(buf)) { + fwrite(buf, 1, sizeof(buf), stream); + i -= sizeof(buf); + } + + if (i > 0) + fwrite(buf, 1, i, stream); + } +} + +size_t file_stream::read(size_t count) { + return read((void*)0, count); +} + +size_t file_stream::read(void* buf, size_t count) { + if (!buf) { + int64_t act_count = 0; + while (count > 0) { + act_count += fread(this->buf, 1, min_def(count, sizeof(this->buf)), stream); + count -= sizeof(this->buf); + } + return act_count; + } + else + return fread(buf, 1, count, stream); +} + +size_t file_stream::read(void* buf, size_t size, size_t count) { + if (!buf) { + int64_t act_count = 0; + while (count > 0) { + act_count += fread(this->buf, size, min_def(count, sizeof(this->buf) / size), stream); + count -= sizeof(this->buf); + } + return act_count; + } + else + return fread(buf, size, count, stream); +} + +size_t file_stream::write(size_t count) { + return write((void*)0, count); +} + +size_t file_stream::write(const void* buf, size_t count) { + if (!buf) { + memset(this->buf, 0, sizeof(this->buf)); + int64_t act_count = 0; + while (count > 0) { + act_count += fwrite(this->buf, 1, min_def(count, sizeof(this->buf)), stream); + count -= sizeof(this->buf); + } + return act_count; + } + else + return fwrite(buf, 1, count, stream); +} + +size_t file_stream::write(const void* buf, size_t size, size_t count) { + if (!buf) { + memset(this->buf, 0, sizeof(this->buf)); + int64_t act_count = 0; + while (count > 0) { + act_count += fwrite(this->buf, 1, min_def(count, sizeof(this->buf) / size), stream); + count -= sizeof(this->buf) / size; + } + return act_count; + } + else + return fwrite(buf, size, count, stream); +} + +int32_t file_stream::read_char() { + return fgetc(stream); +} + +int32_t file_stream::write_char(char c) { + return fputc(c, stream); +} + +int64_t file_stream::get_length() { + if (stream) { + size_t temp = _ftelli64(stream); + _fseeki64(stream, 0, SEEK_END); + length = _ftelli64(stream); + _fseeki64(stream, temp, SEEK_SET); + } + else + length = 0; + return length; +} + +int64_t file_stream::get_position() { + return _ftelli64(stream); +} + +int32_t file_stream::set_position(int64_t pos, int32_t seek) { + return _fseeki64(stream, pos, seek); +} + +void file_stream::open(const char* path, const char* mode) { + close(); + + if (!path || !mode) + return; + + wchar_t* temp_path = utf8_to_utf16(path); + wchar_t* temp_mode = utf8_to_utf16(mode); + stream = _wfsopen(temp_path, temp_mode, _SH_DENYNO); + get_length(); + free_def(temp_path); + free_def(temp_mode); +} + +void file_stream::open(const wchar_t* path, const wchar_t* mode) { + close(); + + if (!path || !mode) + return; + + stream = _wfsopen(path, mode, _SH_DENYNO); + get_length(); +} diff --git a/src/KKdLib/io/file_stream.hpp b/src/KKdLib/io/file_stream.hpp new file mode 100644 index 00000000..e95b344f --- /dev/null +++ b/src/KKdLib/io/file_stream.hpp @@ -0,0 +1,39 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "stream.hpp" + +class file_stream : public stream { +private: + FILE* stream; + +public: + file_stream(); + virtual ~file_stream(); + + virtual int flush() override; + virtual void close() override; + virtual bool check_null() override; + virtual bool check_not_null() override; + + virtual void align_read(size_t align) override; + virtual void align_write(size_t align) override; + virtual size_t read(size_t count) override; + virtual size_t read(void* buf, size_t count) override; + virtual size_t read(void* buf, size_t size, size_t count) override; + virtual size_t write(size_t count) override; + virtual size_t write(const void* buf, size_t count) override; + virtual size_t write(const void* buf, size_t size, size_t count) override; + virtual int32_t read_char() override; + virtual int32_t write_char(char c) override; + virtual int64_t get_length() override; + virtual int64_t get_position() override; + virtual int32_t set_position(int64_t pos, int32_t seek) override; + + void open(const char* path, const char* mode); + void open(const wchar_t* path, const wchar_t* mode); +}; diff --git a/src/KKdLib/io/json.cpp b/src/KKdLib/io/json.cpp index 69ba4b9f..68585f37 100644 --- a/src/KKdLib/io/json.cpp +++ b/src/KKdLib/io/json.cpp @@ -16,16 +16,16 @@ struct io_json_read_buffer { static int32_t io_json_read_char(stream& s, io_json_read_buffer* buf); static void io_json_seek(stream& s, io_json_read_buffer* buf, int64_t offset); static void io_json_seek_one(stream& s, io_json_read_buffer* buf); -static void io_json_read_inner(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c); +static void io_json_read_inner(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); static void io_json_read_digit(stream& s, io_json_read_buffer* buf, int32_t* c, char** dig_buf, char* dig_buf_end); -static void io_json_read_float(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c); +static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); static uint8_t io_json_read_string_hex(int32_t c); static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); -static void io_json_read_string(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c); -static void io_json_read_map(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c); -static void io_json_read_array(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c); -static void io_json_read_bool(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c); -static void io_json_read_null(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c); +static void io_json_read_string(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); +static void io_json_read_map(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); +static void io_json_read_array(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); +static void io_json_read_bool(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); +static void io_json_read_null(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); static void io_json_write_inner(stream& s, msgpack* msg, size_t tabs); static void io_json_write_null(stream& s); static void io_json_write_bool(stream& s, bool val); @@ -39,10 +39,10 @@ static void io_json_write_int64_t(stream& s, int64_t val); static void io_json_write_uint64_t(stream& s, uint64_t val); static void io_json_write_float_t(stream& s, float_t val); static void io_json_write_double_t(stream& s, double_t val); -static void io_json_write_string(stream& s, std::string* val); +static void io_json_write_string(stream& s, std::string& val); void io_json_read(stream& s, msgpack* msg) { - if (!msg || !s.io.stream) + if (!msg || s.check_null()) return; io_json_read_buffer buf; @@ -51,12 +51,19 @@ void io_json_read(stream& s, msgpack* msg) { buf.data[0] = 0; buf.data[IO_JSON_READ_BUF_SIZE - 1] = 0; int32_t c = io_json_read_char(s, &buf); - io_json_read_inner(s, &buf, 0, msg, &c); + io_json_read_inner(s, &buf, msg, &c); +} + +void io_json_write(stream& s, msgpack* msg) { + if (s.check_null() || !msg) + return; + + io_json_write_inner(s, msg, 0); } #define CHECK_WHITESPACE(c) (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) -static int32_t io_json_read_char(stream& s, io_json_read_buffer* buf) { +inline static int32_t io_json_read_char(stream& s, io_json_read_buffer* buf) { if (buf->length == 0) { buf->first = 1; buf->data[0] = buf->data[IO_JSON_READ_BUF_SIZE - 1]; @@ -72,7 +79,7 @@ static int32_t io_json_read_char(stream& s, io_json_read_buffer* buf) { return c; } -static void io_json_seek(stream& s, io_json_read_buffer* buf, int64_t offset) { +inline static void io_json_seek(stream& s, io_json_read_buffer* buf, int64_t offset) { if (buf->first < offset || offset >= buf->length - 1LL) { int64_t pos = s.get_position() - buf->length - offset; int64_t off = pos % IO_JSON_READ_BUF_SIZE; @@ -101,38 +108,38 @@ inline static void io_json_seek_one(stream& s, io_json_read_buffer* buf) { buf->length++; } -static void io_json_read_inner(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c) { - *msg = msgpack(name); +static void io_json_read_inner(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { + *msg = {}; while (*c != EOF) { if (CHECK_WHITESPACE(*c)) *c = io_json_read_char(s, buf); - if (isdigit(*c)) { - io_json_read_float(s, buf, name, msg, c); + if (*c >= '0' && *c <= '9') { + io_json_read_float(s, buf, msg, c); return; } switch (*c) { case '\"': - io_json_read_string(s, buf, name, msg, c); + io_json_read_string(s, buf, msg, c); break; case '{': - io_json_read_map(s, buf, name, msg, c); + io_json_read_map(s, buf, msg, c); break; case '[': - io_json_read_array(s, buf, name, msg, c); + io_json_read_array(s, buf, msg, c); break; case '-': - io_json_read_float(s, buf, name, msg, c); + io_json_read_float(s, buf, msg, c); break; case 't': - io_json_read_bool(s, buf, name, msg, c); + io_json_read_bool(s, buf, msg, c); break; case 'f': - io_json_read_bool(s, buf, name, msg, c); + io_json_read_bool(s, buf, msg, c); break; case 'n': - io_json_read_null(s, buf, name, msg, c); + io_json_read_null(s, buf, msg, c); break; } return; @@ -141,7 +148,7 @@ static void io_json_read_inner(stream& s, io_json_read_buffer* buf, const char* inline static void io_json_read_digit(stream& s, io_json_read_buffer* buf, int32_t* c, char** dig_buf, char* dig_buf_end) { char* b = *dig_buf; - while (isdigit(*c) && b < dig_buf_end) { + while (*c >= '0' && *c <= '9' && b < dig_buf_end) { *b++ = *c; if ((*c = io_json_read_char(s, buf)) == EOF) break; @@ -149,7 +156,7 @@ inline static void io_json_read_digit(stream& s, io_json_read_buffer* buf, int32 *dig_buf = b; } -static void io_json_read_float(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c) { +static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { char dig_buf[0x100]; char* t_buf = dig_buf; char* buf_end = dig_buf + 0x100; @@ -186,9 +193,9 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, const char* if (zero && !fraction) { if (negate) - *msg = msgpack(name, -0.0f); + *msg = -0.0f; else - *msg = msgpack(name, 0); + *msg = 0; io_json_seek_one(s, buf); return; } @@ -198,19 +205,19 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, const char* return; if (val >= 0x00 && val < 0xFF) - *msg = msgpack(name, (uint8_t)val); + *msg = (uint8_t)val; else if (val >= (int8_t)0x80 && val <= (int8_t)0x7F) - *msg = msgpack(name, (int8_t)val); + *msg = (int8_t)val; else if (val >= 0x0000 && val < 0xFFFF) - *msg = msgpack(name, (uint16_t)val); + *msg = (uint16_t)val; else if (val >= (int16_t)0x8000 && val <= (int16_t)0x7FFF) - *msg = msgpack(name, (int16_t)val); + *msg = (int16_t)val; else if (val >= 0x00000000 && val <= 0xFFFFFFFF) - *msg = msgpack(name, (uint32_t)val); + *msg = (uint32_t)val; else if (val >= (int32_t)0x80000000 && val <= (int32_t)0x7FFFFFFF) - *msg = msgpack(name, (int32_t)val); + *msg = (int32_t)val; else - *msg = msgpack(name, val); + *msg = val; io_json_seek_one(s, buf); return; } @@ -233,9 +240,9 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, const char* return; if ((float_t)val == val) - *msg = msgpack(name, (float_t)val); + *msg = (float_t)val; else - *msg = msgpack(name, val); + *msg = val; io_json_seek_one(s, buf); } @@ -374,10 +381,10 @@ static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgp return temp; } -inline static void io_json_read_string(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c) { +inline static void io_json_read_string(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { char* temp = io_json_read_string_inner(s, buf, msg, c); - *msg = msgpack(name, temp); - free(temp); + *msg = temp; + free_def(temp); } inline static void io_json_read_skip_whitespace(stream& s, io_json_read_buffer* buf, int32_t* c) { @@ -388,10 +395,10 @@ inline static void io_json_read_skip_whitespace(stream& s, io_json_read_buffer* } } -static void io_json_read_map(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c) { +static void io_json_read_map(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { size_t i = 0; msgpack m; - msgpack_array map; + msgpack_map map; if (*c != '}') { while (true) { io_json_read_skip_whitespace(s, buf, c); @@ -405,14 +412,14 @@ static void io_json_read_map(stream& s, io_json_read_buffer* buf, const char* na io_json_read_skip_whitespace(s, buf, c); if (*c != ':') { - free(key); + free_def(key); return; } io_json_read_skip_whitespace(s, buf, c); - map.push_back({}); - io_json_read_inner(s, buf, key, &map.back(), c); - free(key); + map.push_back({ key, {} }); + io_json_read_inner(s, buf, &map.back().second, c); + free_def(key); io_json_read_skip_whitespace(s, buf, c); @@ -423,10 +430,10 @@ static void io_json_read_map(stream& s, io_json_read_buffer* buf, const char* na } } - *msg = msgpack(name, false, map); + *msg = map; } -static void io_json_read_array(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c) { +static void io_json_read_array(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { size_t i = 0; msgpack m; msgpack_array array; @@ -438,7 +445,7 @@ static void io_json_read_array(stream& s, io_json_read_buffer* buf, const char* break; array.push_back({}); - io_json_read_inner(s, buf, 0, &array.back(), c); + io_json_read_inner(s, buf, &array.back(), c); io_json_read_skip_whitespace(s, buf, c); @@ -449,10 +456,10 @@ static void io_json_read_array(stream& s, io_json_read_buffer* buf, const char* } } - *msg = msgpack(name, true, array); + *msg = array; } -inline static void io_json_read_bool(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c) { +inline static void io_json_read_bool(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { if (*c != 't') { if ((*c = io_json_read_char(s, buf)) == EOF || *c != 'a') return; @@ -462,7 +469,7 @@ inline static void io_json_read_bool(stream& s, io_json_read_buffer* buf, const return; if ((*c = io_json_read_char(s, buf)) == EOF || *c != 'e') return; - *msg = msgpack(name, false); + *msg = false; } else { if ((*c = io_json_read_char(s, buf)) == EOF || *c != 'r') @@ -471,11 +478,11 @@ inline static void io_json_read_bool(stream& s, io_json_read_buffer* buf, const return; if ((*c = io_json_read_char(s, buf)) == EOF || *c != 'e') return; - *msg = msgpack(name, true); + *msg = true; } } -inline static void io_json_read_null(stream& s, io_json_read_buffer* buf, const char* name, msgpack* msg, int32_t* c) { +inline static void io_json_read_null(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { if ((*c = io_json_read_char(s, buf)) == EOF || *c != 'u') return; if ((*c = io_json_read_char(s, buf)) == EOF || *c != 'l') @@ -483,70 +490,62 @@ inline static void io_json_read_null(stream& s, io_json_read_buffer* buf, const if ((*c = io_json_read_char(s, buf)) == EOF || *c != 'l') return; - *msg = msgpack(name); + *msg = {}; } -void io_json_write(stream& s, msgpack* msg) { - if (!s.io.stream || !msg) - return; - - io_json_write_inner(s, msg, 0); -} - -void io_json_write_inner(stream& s, msgpack* msg, size_t tabs) { - for (size_t i = 0; i < tabs; i++) - s.write(" ", 2); - - if (msg->name.size()) { - io_json_write_string(s, &msg->name); - s.write(": ", 2); - } - +inline static void io_json_write_inner(stream& s, msgpack* msg, size_t tabs) { switch (msg->type) { case MSGPACK_NULL: io_json_write_null(s); break; case MSGPACK_BOOL: - io_json_write_bool(s, *MSGPACK_SELECT_PTR(bool, msg)); + io_json_write_bool(s, msg->data.b); break; case MSGPACK_INT8: { - io_json_write_int8_t(s, *MSGPACK_SELECT_PTR(int8_t, msg)); + io_json_write_int8_t(s, msg->data.i8); } break; case MSGPACK_UINT8: - io_json_write_uint8_t(s, *MSGPACK_SELECT_PTR(uint8_t, msg)); + io_json_write_uint8_t(s, msg->data.u8); break; case MSGPACK_INT16: - io_json_write_int16_t(s, *MSGPACK_SELECT_PTR(int16_t, msg)); + io_json_write_int16_t(s, msg->data.i16); break; case MSGPACK_UINT16: - io_json_write_uint16_t(s, *MSGPACK_SELECT_PTR(uint16_t, msg)); + io_json_write_uint16_t(s, msg->data.u16); break; case MSGPACK_INT32: - io_json_write_int32_t(s, *MSGPACK_SELECT_PTR(int32_t, msg)); + io_json_write_int32_t(s, msg->data.i32); break; case MSGPACK_UINT32: - io_json_write_uint32_t(s, *MSGPACK_SELECT_PTR(uint32_t, msg)); + io_json_write_uint32_t(s, msg->data.u32); break; case MSGPACK_INT64: - io_json_write_int64_t(s, *MSGPACK_SELECT_PTR(int64_t, msg)); + io_json_write_int64_t(s, msg->data.i64); break; case MSGPACK_UINT64: - io_json_write_uint64_t(s, *MSGPACK_SELECT_PTR(uint64_t, msg)); + io_json_write_uint64_t(s, msg->data.u64); break; case MSGPACK_FLOAT: - io_json_write_float_t(s, *MSGPACK_SELECT_PTR(float_t, msg)); + io_json_write_float_t(s, msg->data.f32); break; case MSGPACK_DOUBLE: - io_json_write_double_t(s, *MSGPACK_SELECT_PTR(double_t, msg)); + io_json_write_double_t(s, msg->data.f64); break; case MSGPACK_STRING: - io_json_write_string(s, MSGPACK_SELECT_PTR(std::string, msg)); + io_json_write_string(s, *msg->data.str); break; case MSGPACK_ARRAY: { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, msg); + msgpack_array* ptr = msg->data.arr; + if (!ptr->size()) { + s.write("[]", 2); + break; + } + s.write("[\n", 2); for (msgpack& i : *ptr) { + for (size_t i = 0; i <= tabs; i++) + s.write(" ", 2); io_json_write_inner(s, &i, tabs + 1); if (&i + 1 != ptr->data() + ptr->size()) s.write_char(','); @@ -558,11 +557,20 @@ void io_json_write_inner(stream& s, msgpack* msg, size_t tabs) { s.write_char(']'); } break; case MSGPACK_MAP: { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, msg); + msgpack_map* ptr = msg->data.map; + if (!ptr->size()) { + s.write("{}", 2); + break; + } + s.write("{\n", 2); - for (msgpack& i : *ptr) { - io_json_write_inner(s, &i, tabs + 1); + for (msgpack_key_value& i : *ptr) { + for (size_t i = 0; i <= tabs; i++) + s.write(" ", 2); + io_json_write_string(s, i.first); + s.write(": ", 2); + io_json_write_inner(s, &i.second, tabs + 1); if (&i + 1 != ptr->data() + ptr->size()) s.write_char(','); s.write_char('\n'); @@ -646,10 +654,10 @@ inline static void io_json_write_double_t(stream& s, double_t val) { s.write(temp, len); } -inline static void io_json_write_string(stream& s, std::string* val) { +inline static void io_json_write_string(stream& s, std::string& val) { s.write_char('\"'); - const char* str = val->c_str(); - size_t len = val->size(); + const char* str = val.c_str(); + size_t len = val.size(); for (size_t i = len; i; i--, str++) switch (*str) { case 0x00: diff --git a/src/KKdLib/io/memory_stream.cpp b/src/KKdLib/io/memory_stream.cpp new file mode 100644 index 00000000..737f100e --- /dev/null +++ b/src/KKdLib/io/memory_stream.cpp @@ -0,0 +1,255 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "memory_stream.hpp" + +memory_stream::memory_stream() { + +} + +memory_stream::~memory_stream() { + close(); +} + +int memory_stream::flush() { + return 0; +} + +void memory_stream::close() { + if (!this) + return; + + data.vec.clear(); + data.vec.shrink_to_fit(); + data.data = data.vec.begin(); + stream::close(); +} + +bool memory_stream::check_null() { + return !data.vec.size(); +} + +bool memory_stream::check_not_null() { + return !!data.vec.size(); +} + +void memory_stream::align_read(size_t align) { + size_t position = data.data - data.vec.begin(); + size_t temp_align = align - position % align; + if (align != temp_align) { + size_t pos = data.data - data.vec.begin(); + if (data.vec.size() < (size_t)(pos + temp_align)) { + size_t size = data.vec.size(); + data.vec.resize(pos + temp_align); + data.data = data.vec.begin() + pos; + memset(data.data._Ptr, 0, temp_align); + } + data.data += temp_align; + } +} + +void memory_stream::align_write(size_t align) { + size_t position = data.data - data.vec.begin(); + size_t temp_align = align - position % align; + if (align != temp_align) { + size_t pos = data.data - data.vec.begin(); + if (data.vec.size() < (size_t)(pos + temp_align)) { + size_t size = data.vec.size(); + data.vec.resize(pos + temp_align); + data.data = data.vec.begin() + pos; + memset(data.data._Ptr, 0, temp_align); + } + data.data += temp_align; + } +} + +size_t memory_stream::read(size_t count) { + return read((void*)0, count); +} + +size_t memory_stream::read(void* buf, size_t count) { + if (data.data >= data.vec.end()) + return EOF; + + size_t _count = data.vec.end() - data.data; + if (_count >= count) + _count = count; + if (buf) + memcpy(buf, data.data._Ptr, _count); + data.data += _count; + return _count; +} + +size_t memory_stream::read(void* buf, size_t size, size_t count) { + if (data.data >= data.vec.end()) + return EOF; + + size_t _count = data.vec.end() - data.data; + if (_count >= size * count) + _count = size * count; + if (buf) + memcpy(buf, data.data._Ptr, _count); + data.data += _count; + return _count; +} + +size_t memory_stream::write(size_t count) { + return write((void*)0, count); +} + +size_t memory_stream::write(const void* buf, size_t count) { + size_t pos = data.data - data.vec.begin(); + if (data.vec.size() < pos + count) { + data.vec.resize(pos + count); + data.data = data.vec.begin() + pos; + } + if (buf) + memcpy(data.data._Ptr, buf, count); + else + memset(data.data._Ptr, 0, count); + data.data += count; + return count; +} + +size_t memory_stream::write(const void* buf, size_t size, size_t count) { + size_t pos = data.data - data.vec.begin(); + size_t _count = size * count; + if (data.vec.size() < (size_t)(pos + _count)) { + data.vec.resize(pos + _count); + data.data = data.vec.begin() + pos; + } + if (buf) + memcpy(data.data._Ptr, buf, _count); + else + memset(data.data._Ptr, 0, _count); + data.data += _count; + return _count; +} + +int32_t memory_stream::read_char() { + if (data.data >= data.vec.end()) + return EOF; + return *(data.data++); +} + +int32_t memory_stream::write_char(char c) { + size_t pos = data.data - data.vec.begin(); + if (data.vec.size() < (size_t)(pos + 1)) { + size_t size = data.vec.size(); + data.vec.resize(pos + 1); + data.data = data.vec.begin() + pos; + } + *(data.data++) = c; + return 0; +} + +int64_t memory_stream::get_length() { + length = data.vec.size(); + return length; +} + +int64_t memory_stream::get_position() { + return data.data - data.vec.begin(); +} + +int32_t memory_stream::set_position(int64_t pos, int32_t seek) { + switch (seek) { + case SEEK_SET: { + if (pos < 0) + return EOF; + + if (data.vec.size() < (size_t)pos) { + size_t size = data.vec.size(); + data.vec.resize(pos); + memset(data.vec.data() + size, 0, pos - size); + } + data.data = data.vec.begin() + pos; + } return 0; + case SEEK_CUR: { + if (pos > 0) { + size_t _pos = data.data - data.vec.begin(); + if (data.vec.size() < (size_t)(_pos + pos)) { + size_t size = data.vec.size(); + data.vec.resize(_pos + pos); + memset(data.vec.data() + size, 0, _pos + pos - size); + data.data = data.vec.begin() + _pos; + } + data.data += pos; + } + else if (pos < 0) { + if (data.data - data.vec.begin() < -pos) + return EOF; + else + data.data += pos; + } + } return 0; + case SEEK_END: { + if (pos < 0) + break; + + if (data.vec.size() < (size_t)pos) + break; + + data.data = data.vec.end() - pos; + } return 0; + } + return EOF; +} + +void memory_stream::open() { + close(); + + length = 0; +} + +void memory_stream::open(const void* data, size_t size) { + close(); + + if (!size) { + length = 0; + return; + } + + this->data.vec.clear(); + this->data.vec.resize(size); + if (this->data.vec.data()) + if (data) + memcpy(this->data.vec.data(), data, size); + else + memset(this->data.vec.data(), 0, size); + this->data.data = this->data.vec.begin(); + length = size; +} + +void memory_stream::open(std::vector& data) { + close(); + + if (!data.size()) { + length = 0; + return; + } + + this->data.vec = data; + this->data.data = this->data.vec.begin(); + length = data.size(); +} + +void memory_stream::copy(void** data, size_t* size) { + if (!this || !data || !size) + return; + + *size = this->data.vec.size(); + *data = force_malloc(*size); + memcpy(*data, this->data.vec.data(), *size); +} + +void memory_stream::copy(std::vector& data) { + if (!this) + return; + + size_t length = this->data.vec.size(); + data.resize(length); + memcpy(data.data(), this->data.vec.data(), length); +} diff --git a/src/KKdLib/io/memory_stream.hpp b/src/KKdLib/io/memory_stream.hpp new file mode 100644 index 00000000..5a638cf9 --- /dev/null +++ b/src/KKdLib/io/memory_stream.hpp @@ -0,0 +1,45 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "stream.hpp" + +class memory_stream : public stream { +private: + struct data { + std::vector::iterator data; + std::vector vec; + } data; + +public: + memory_stream(); + virtual ~memory_stream(); + + virtual int flush() override; + virtual void close() override; + virtual bool check_null() override; + virtual bool check_not_null() override; + + virtual void align_read(size_t align) override; + virtual void align_write(size_t align) override; + virtual size_t read(size_t count) override; + virtual size_t read(void* buf, size_t count) override; + virtual size_t read(void* buf, size_t size, size_t count) override; + virtual size_t write(size_t count) override; + virtual size_t write(const void* buf, size_t count) override; + virtual size_t write(const void* buf, size_t size, size_t count) override; + virtual int32_t read_char() override; + virtual int32_t write_char(char c) override; + virtual int64_t get_length() override; + virtual int64_t get_position() override; + virtual int32_t set_position(int64_t pos, int32_t seek) override; + + void open(); + void open(const void* data, size_t size); + void open(std::vector& data); + void copy(void** data, size_t* size); + void copy(std::vector& data); +}; diff --git a/src/KKdLib/io/msgpack.cpp b/src/KKdLib/io/msgpack.cpp index 3c4c868b..54c1a528 100644 --- a/src/KKdLib/io/msgpack.cpp +++ b/src/KKdLib/io/msgpack.cpp @@ -5,10 +5,10 @@ #include "msgpack.hpp" -static void io_msgpack_read_inner(stream& s, const char* name, msgpack* msg); -static void io_msgpack_read_string(stream& s, const char* name, msgpack* msg, size_t length); -static void io_msgpack_read_array(stream& s, const char* name, msgpack* msg, size_t length); -static void io_msgpack_read_map(stream& s, const char* name, msgpack* msg, size_t length); +static void io_msgpack_read_inner(stream& s, msgpack* msg); +static void io_msgpack_read_string(stream& s, msgpack* msg, size_t length); +static void io_msgpack_read_array(stream& s, msgpack* msg, size_t length); +static void io_msgpack_read_map(stream& s, msgpack* msg, size_t length); static void io_msgpack_write_inner(stream& s, msgpack* msg); static void io_msgpack_write_null(stream& s); static void io_msgpack_write_bool(stream& s, bool val); @@ -27,13 +27,23 @@ static void io_msgpack_write_array(stream& s, size_t val); static void io_msgpack_write_map(stream& s, size_t val); void io_msgpack_read(stream& s, msgpack* msg) { - io_msgpack_read_inner(s, 0, msg); + if (s.check_null() || !msg) + return; + + io_msgpack_read_inner(s, msg); } -static void io_msgpack_read_inner(stream& s, const char* name, msgpack* msg) { +void io_msgpack_write(stream& s, msgpack* msg) { + if (s.check_null() || !msg) + return; + + io_msgpack_write_inner(s, msg); +} + +inline static void io_msgpack_read_inner(stream& s, msgpack* msg) { uint8_t type = s.read_uint8_t(); - *msg = msgpack(name); + *msg = {}; switch (type >> 4) { case 0x0: case 0x1: @@ -46,17 +56,17 @@ static void io_msgpack_read_inner(stream& s, const char* name, msgpack* msg) { case 0xE: case 0xF: default: - *msg = msgpack(name, (int8_t)type); + *msg = (int8_t)type; return; case 0x8: - io_msgpack_read_map(s, name, msg, type & 0x0F); + io_msgpack_read_map(s, msg, type & 0x0F); return; case 0x9: - io_msgpack_read_array(s, name, msg, type & 0x0F); + io_msgpack_read_array(s, msg, type & 0x0F); return; case 0xA: case 0xB: - io_msgpack_read_string(s, name, msg, type & 0x1F); + io_msgpack_read_string(s, msg, type & 0x1F); return; case 0xC: case 0xD: @@ -65,10 +75,10 @@ static void io_msgpack_read_inner(stream& s, const char* name, msgpack* msg) { switch (type) { case 0xC2: - *msg = msgpack(name, false); + *msg = false; break; case 0xC3: - *msg = msgpack(name, true); + *msg = true; break; case 0xC4: s.set_position(s.read_uint8_t(), SEEK_CUR); @@ -89,34 +99,34 @@ static void io_msgpack_read_inner(stream& s, const char* name, msgpack* msg) { s.set_position(s.read_uint32_t_reverse_endianness(true) + 1ULL, SEEK_CUR); break; case 0xCA: - *msg = msgpack(name, s.read_float_t_reverse_endianness(true)); + *msg = s.read_float_t_reverse_endianness(true); break; case 0xCB: - *msg = msgpack(name, s.read_double_t_reverse_endianness(true)); + *msg = s.read_double_t_reverse_endianness(true); break; case 0xCC: - *msg = msgpack(name, s.read_uint8_t()); + *msg = s.read_uint8_t(); break; case 0xCD: - *msg = msgpack(name, s.read_uint16_t_reverse_endianness(true)); + *msg = s.read_uint16_t_reverse_endianness(true); break; case 0xCE: - *msg = msgpack(name, s.read_uint32_t_reverse_endianness(true)); + *msg = s.read_uint32_t_reverse_endianness(true); break; case 0xCF: - *msg = msgpack(name, s.read_uint64_t_reverse_endianness(true)); + *msg = s.read_uint64_t_reverse_endianness(true); break; case 0xD0: - *msg = msgpack(name, s.read_int8_t()); + *msg = s.read_int8_t(); break; case 0xD1: - *msg = msgpack(name, s.read_int16_t_reverse_endianness(true)); + *msg = s.read_int16_t_reverse_endianness(true); break; case 0xD2: - *msg = msgpack(name, s.read_int32_t_reverse_endianness(true)); + *msg = s.read_int32_t_reverse_endianness(true); break; case 0xD3: - *msg = msgpack(name, s.read_int64_t_reverse_endianness(true)); + *msg = s.read_int64_t_reverse_endianness(true); break; case 0xD4: s.set_position(2, SEEK_CUR); @@ -134,119 +144,110 @@ static void io_msgpack_read_inner(stream& s, const char* name, msgpack* msg) { s.set_position(17, SEEK_CUR); break; case 0xD9: - io_msgpack_read_string(s, name, msg, s.read_uint8_t()); + io_msgpack_read_string(s, msg, s.read_uint8_t()); break; case 0xDA: - io_msgpack_read_string(s, name, msg, s.read_uint16_t_reverse_endianness(true)); + io_msgpack_read_string(s, msg, s.read_uint16_t_reverse_endianness(true)); break; case 0xDB: - io_msgpack_read_string(s, name, msg, s.read_uint32_t_reverse_endianness(true)); + io_msgpack_read_string(s, msg, s.read_uint32_t_reverse_endianness(true)); break; case 0xDC: - io_msgpack_read_array(s, name, msg, s.read_uint16_t_reverse_endianness(true)); + io_msgpack_read_array(s, msg, s.read_uint16_t_reverse_endianness(true)); break; case 0xDD: - io_msgpack_read_array(s, name, msg, s.read_uint32_t_reverse_endianness(true)); + io_msgpack_read_array(s, msg, s.read_uint32_t_reverse_endianness(true)); break; case 0xDE: - io_msgpack_read_map(s, name, msg, s.read_uint16_t_reverse_endianness(true)); + io_msgpack_read_map(s, msg, s.read_uint16_t_reverse_endianness(true)); break; case 0xDF: - io_msgpack_read_map(s, name, msg, s.read_uint16_t_reverse_endianness(true)); + io_msgpack_read_map(s, msg, s.read_uint16_t_reverse_endianness(true)); break; } } -inline static void io_msgpack_read_string(stream& s, const char* name, msgpack* msg, size_t length) { - std::string str; - str = s.read_string(length); - *msg = msgpack(name, &str); +inline static void io_msgpack_read_string(stream& s, msgpack* msg, size_t length) { + *msg = s.read_string(length); } -inline static void io_msgpack_read_array(stream& s, const char* name, msgpack* msg, size_t length) { - *msg = msgpack(name, true, length); - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, msg); +inline static void io_msgpack_read_array(stream& s, msgpack* msg, size_t length) { + *msg = msgpack_array(); + msgpack_array* ptr = msg->data.arr; + ptr->resize(length); for (size_t i = 0; i < length; i++) - io_msgpack_read_inner(s, 0, &ptr->data()[i]); + io_msgpack_read_inner(s, &ptr->data()[i]); } -inline static void io_msgpack_read_map(stream& s, const char* name, msgpack* msg, size_t length) { - *msg = msgpack(name, false, length); - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, msg); +inline static void io_msgpack_read_map(stream& s, msgpack* msg, size_t length) { + *msg = msgpack_map(); + msgpack_map* ptr = msg->data.map; + ptr->resize(length); for (size_t i = 0; i < length; i++) { msgpack t_m = msgpack(); - io_msgpack_read_inner(s, 0, &t_m); + io_msgpack_read_inner(s, &t_m); - const char* n = 0; if (t_m.type == MSGPACK_STRING) - n = MSGPACK_SELECT(std::string, t_m)->c_str(); + ptr->data()[i].first = t_m.data.str->c_str(); - io_msgpack_read_inner(s, n, &ptr->data()[i]); + io_msgpack_read_inner(s, &ptr->data()[i].second); } } -void io_msgpack_write(stream& s, msgpack* msg) { - if (!s.io.stream || !msg) - return; - - io_msgpack_write_inner(s, msg); -} - -static void io_msgpack_write_inner(stream& s, msgpack* msg) { - if (msg->name.size()) - io_msgpack_write_string(s, msg->name); - +inline static void io_msgpack_write_inner(stream& s, msgpack* msg) { switch (msg->type) { case MSGPACK_NULL: io_msgpack_write_null(s); break; case MSGPACK_BOOL: - io_msgpack_write_bool(s, *MSGPACK_SELECT_PTR(bool, msg)); + io_msgpack_write_bool(s, msg->data.b); break; case MSGPACK_INT8: { - io_msgpack_write_int8_t(s, *MSGPACK_SELECT_PTR(int8_t, msg)); + io_msgpack_write_int8_t(s, msg->data.i8); } break; case MSGPACK_UINT8: - io_msgpack_write_uint8_t(s, *MSGPACK_SELECT_PTR(uint8_t, msg)); + io_msgpack_write_uint8_t(s, msg->data.u8); break; case MSGPACK_INT16: - io_msgpack_write_int16_t(s, *MSGPACK_SELECT_PTR(int16_t, msg)); + io_msgpack_write_int16_t(s, msg->data.i16); break; case MSGPACK_UINT16: - io_msgpack_write_uint16_t(s, *MSGPACK_SELECT_PTR(uint16_t, msg)); + io_msgpack_write_uint16_t(s, msg->data.u16); break; case MSGPACK_INT32: - io_msgpack_write_int32_t(s, *MSGPACK_SELECT_PTR(int32_t, msg)); + io_msgpack_write_int32_t(s, msg->data.i32); break; case MSGPACK_UINT32: - io_msgpack_write_uint32_t(s, *MSGPACK_SELECT_PTR(uint32_t, msg)); + io_msgpack_write_uint32_t(s, msg->data.u32); break; case MSGPACK_INT64: - io_msgpack_write_int64_t(s, *MSGPACK_SELECT_PTR(int64_t, msg)); + io_msgpack_write_int64_t(s, msg->data.i64); break; case MSGPACK_UINT64: - io_msgpack_write_uint64_t(s, *MSGPACK_SELECT_PTR(uint64_t, msg)); + io_msgpack_write_uint64_t(s, msg->data.u64); break; case MSGPACK_FLOAT: - io_msgpack_write_float_t(s, *MSGPACK_SELECT_PTR(float_t, msg)); + io_msgpack_write_float_t(s, msg->data.f32); break; case MSGPACK_DOUBLE: - io_msgpack_write_double_t(s, *MSGPACK_SELECT_PTR(double_t, msg)); + io_msgpack_write_double_t(s, msg->data.f64); break; case MSGPACK_STRING: - io_msgpack_write_string(s, *MSGPACK_SELECT_PTR(std::string, msg)); + io_msgpack_write_string(s, *msg->data.str); break; case MSGPACK_ARRAY: { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, msg); + msgpack_array* ptr = msg->data.arr; io_msgpack_write_array(s, ptr->size()); for (msgpack& i : *ptr) io_msgpack_write_inner(s, &i); } break; case MSGPACK_MAP: { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, msg); + msgpack_map* ptr = msg->data.map; io_msgpack_write_map(s, ptr->size()); - for (msgpack& i : *ptr) - io_msgpack_write_inner(s, &i); + for (msgpack_key_value& i : *ptr) { + io_msgpack_write_string(s, i.first); + io_msgpack_write_inner(s, &i.second); + } } break; } } diff --git a/src/KKdLib/io/path.cpp b/src/KKdLib/io/path.cpp index 3bacb1f1..35afbfda 100644 --- a/src/KKdLib/io/path.cpp +++ b/src/KKdLib/io/path.cpp @@ -9,7 +9,7 @@ bool path_check_path_exists(const char* path) { wchar_t* path_temp = utf8_to_utf16(path); DWORD ftyp = GetFileAttributesW(path_temp); - free(path_temp); + free_def(path_temp); if (ftyp == INVALID_FILE_ATTRIBUTES) return false; else @@ -27,7 +27,7 @@ bool path_check_path_exists(const wchar_t* path) { bool path_check_file_exists(const char* path) { wchar_t* path_temp = utf8_to_utf16(path); DWORD ftyp = GetFileAttributesW(path_temp); - free(path_temp); + free_def(path_temp); if (ftyp == INVALID_FILE_ATTRIBUTES) return false; else @@ -45,7 +45,7 @@ bool path_check_file_exists(const wchar_t* path) { bool path_check_directory_exists(const char* path) { wchar_t* path_temp = utf8_to_utf16(path); DWORD ftyp = GetFileAttributesW(path_temp); - free(path_temp); + free_def(path_temp); if (ftyp == INVALID_FILE_ATTRIBUTES) return false; else @@ -60,136 +60,89 @@ bool path_check_directory_exists(const wchar_t* path) { return ftyp & FILE_ATTRIBUTE_DIRECTORY ? true : false; } -void path_get_files(std::vector* files, const char* path) { - files->clear(); - files->shrink_to_fit(); - +std::vector path_get_files(const char* path) { wchar_t* dir_temp = utf8_to_utf16(path); size_t dir_len = utf16_length(dir_temp); if (!dir_temp) - return; + return {}; - wchar_t* dir; - if (dir_temp[dir_len - 1] != L'\\') { - dir = force_malloc_s(wchar_t, dir_len + 3); - memcpy(dir, dir_temp, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'\\'; - dir[dir_len + 1] = L'*'; - dir[dir_len + 2] = 0; - } - else { - dir = force_malloc_s(wchar_t, dir_len + 2); - memcpy(dir, dir_temp, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'*'; - dir[dir_len + 1] = 0; - } - free(dir_temp); + std::wstring dir; + dir.assign(dir_temp, dir_len); + if (dir.size() && dir.back() != L'\\') + dir.push_back(L'\\'); + dir.push_back(L'*'); + free_def(dir_temp); WIN32_FIND_DATAW fdata; memset(&fdata, 0, sizeof(WIN32_FIND_DATAW)); - HANDLE h = FindFirstFileW(dir, &fdata); - if (h == INVALID_HANDLE_VALUE) { - free(dir); - return; - } + HANDLE h = FindFirstFileW(dir.c_str(), &fdata); + if (h == INVALID_HANDLE_VALUE) + return {}; + std::vector files; do { if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; char* file_temp = utf16_to_utf8(fdata.cFileName); - if (file_temp) - files->push_back(file_temp); - free(file_temp); + if (file_temp) { + files.push_back(file_temp); + free(file_temp); + } } while (FindNextFileW(h, &fdata)); FindClose(h); - free(dir); + return files; } -void path_get_files(std::vector* files, const wchar_t* path) { - files->clear(); - files->shrink_to_fit(); - +std::vector path_get_files(const wchar_t* path) { size_t dir_len = utf16_length(path); - wchar_t* dir; - if (path[dir_len - 1] != L'\\') { - dir = force_malloc_s(wchar_t, dir_len + 3); - memcpy(dir, path, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'\\'; - dir[dir_len + 1] = L'*'; - dir[dir_len + 2] = 0; - } - else { - dir = force_malloc_s(wchar_t, dir_len + 2); - memcpy(dir, path, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'*'; - dir[dir_len + 1] = 0; - } + std::wstring dir; + dir.assign(path, dir_len); + if (dir.size() && dir.back() != L'\\') + dir.push_back(L'\\'); + dir.push_back(L'*'); WIN32_FIND_DATAW fdata; memset(&fdata, 0, sizeof(WIN32_FIND_DATAW)); - HANDLE h = FindFirstFileW(dir, &fdata); - if (h == INVALID_HANDLE_VALUE) { - free(dir); - return; - } + HANDLE h = FindFirstFileW(dir.c_str(), &fdata); + if (h == INVALID_HANDLE_VALUE) + return {}; + std::vector files; do { if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - std::wstring file = std::wstring(fdata.cFileName); - files->push_back(file); + files.push_back(fdata.cFileName); } while (FindNextFileW(h, &fdata)); FindClose(h); - free(dir); + return files; } -void path_get_directories(std::vector* directories, - const char* path, char** exclude_list, size_t exclude_count) { - directories->clear(); - directories->shrink_to_fit(); - +std::vector path_get_directories( + const char* path, const char** exclude_list, size_t exclude_count) { wchar_t* dir_temp = utf8_to_utf16(path); size_t dir_len = utf16_length(dir_temp); if (!dir_temp) - return; + return {}; - wchar_t* dir; - wchar_t* temp; - if (dir_temp[dir_len - 1] != L'\\') { - dir = force_malloc_s(wchar_t, dir_len + 3); - memcpy(dir, dir_temp, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'\\'; - dir[dir_len + 1] = L'*'; - dir[dir_len + 2] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 2 + MAX_PATH); - memcpy(temp, dir_temp, sizeof(wchar_t) * dir_len); - temp[dir_len] = L'\\'; - dir_len++; - } - else { - dir = force_malloc_s(wchar_t, dir_len + 2); - memcpy(dir, dir_temp, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'*'; - dir[dir_len + 1] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 1 + MAX_PATH); - memcpy(temp, dir_temp, sizeof(wchar_t) * dir_len); - } - free(dir_temp); + std::wstring dir; + std::wstring temp; + dir.assign(dir_temp, dir_len); + if (dir.size() && dir.back() != L'\\') + dir.push_back(L'\\'); + temp.assign(dir); + dir.push_back(L'*'); + free_def(dir_temp); WIN32_FIND_DATAW fdata; memset(&fdata, 0, sizeof(WIN32_FIND_DATAW)); - HANDLE h = FindFirstFileW(dir, &fdata); - if (h == INVALID_HANDLE_VALUE) { - free(dir); - free(temp); - return; - } + HANDLE h = FindFirstFileW(dir.c_str(), &fdata); + if (h == INVALID_HANDLE_VALUE) + return {}; + std::vector directories; do { if (~fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; @@ -199,17 +152,16 @@ void path_get_directories(std::vector* directories, if (exclude_list && exclude_count) { size_t len = utf16_length(fdata.cFileName); - memcpy(temp + dir_len, fdata.cFileName, sizeof(wchar_t) * len); - temp[dir_len + len] = L'\0'; + temp.append(fdata.cFileName, len); + std::string temp_utf8 = utf16_to_utf8(temp); bool exclude = false; - char* temp_utf8 = utf16_to_utf8(temp); for (size_t i = 0; i < exclude_count; i++) - if (!str_utils_compare(exclude_list[i], temp_utf8)) { + if (!temp_utf8.compare(exclude_list[i])) { exclude = true; break; } - free(temp_utf8); + temp.resize(temp.size() - len); if (exclude) continue; @@ -217,54 +169,32 @@ void path_get_directories(std::vector* directories, char* directory_temp = utf16_to_utf8(fdata.cFileName); if (directory_temp) - directories->push_back(directory_temp); - free(directory_temp); + directories.push_back(directory_temp); + free_def(directory_temp); } while (FindNextFileW(h, &fdata)); FindClose(h); - free(temp); - free(dir); + return directories; } -void path_get_directories(std::vector* directories, +std::vector path_get_directories( const wchar_t* path, wchar_t** exclude_list, size_t exclude_count) { - directories->clear(); - directories->shrink_to_fit(); - size_t dir_len = utf16_length(path); - wchar_t* dir; - wchar_t* temp; - if (path[dir_len - 1] != L'\\') { - dir = force_malloc_s(wchar_t, dir_len + 3); - memcpy(dir, path, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'\\'; - dir[dir_len + 1] = L'*'; - dir[dir_len + 2] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 2 + MAX_PATH); - memcpy(temp, path, sizeof(wchar_t) * dir_len); - temp[dir_len] = L'\\'; - dir_len++; - } - else { - dir = force_malloc_s(wchar_t, dir_len + 2); - memcpy(dir, path, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'*'; - dir[dir_len + 1] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 1 + MAX_PATH); - memcpy(temp, path, sizeof(wchar_t) * dir_len); - } + std::wstring dir; + std::wstring temp; + dir.assign(path, dir_len); + if (dir.size() && dir.back() != L'\\') + dir.push_back(L'\\'); + temp.assign(dir); + dir.push_back(L'*'); WIN32_FIND_DATAW fdata; memset(&fdata, 0, sizeof(WIN32_FIND_DATAW)); - HANDLE h = FindFirstFileW(dir, &fdata); - if (h == INVALID_HANDLE_VALUE) { - free(dir); - free(temp); - return; - } + HANDLE h = FindFirstFileW(dir.c_str(), &fdata); + if (h == INVALID_HANDLE_VALUE) + return {}; + std::vector directories; do { if (~fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; @@ -274,71 +204,47 @@ void path_get_directories(std::vector* directories, if (exclude_list && exclude_count) { size_t len = utf16_length(fdata.cFileName); - memcpy(temp + dir_len + 1, fdata.cFileName, sizeof(wchar_t) * len); - temp[dir_len + 1 + len] = L'\0'; + temp.append(fdata.cFileName, len); bool exclude = false; for (size_t i = 0; i < exclude_count; i++) - if (!str_utils_compare(exclude_list[i], temp)) { + if (!temp.compare(exclude_list[i])) { exclude = true; break; } + temp.resize(temp.size() - len); if (exclude) continue; } - std::wstring directory = std::wstring(fdata.cFileName); - directories->push_back(directory); + directories.push_back(fdata.cFileName); } while (FindNextFileW(h, &fdata)); FindClose(h); - free(temp); - free(dir); + return directories; } -void path_get_directories_recursive(std::vector* directories, - const char* path, char** exclude_list, size_t exclude_count) { - directories->clear(); - directories->shrink_to_fit(); - +std::vector path_get_directories_recursive( + const char* path, const char** exclude_list, size_t exclude_count) { wchar_t* dir_temp = utf8_to_utf16(path); size_t dir_len = utf16_length(dir_temp); if (!dir_temp) - return; + return {}; - wchar_t* dir; - wchar_t* temp; - if (dir_temp[dir_len - 1] != L'\\') { - dir = force_malloc_s(wchar_t, dir_len + 3); - memcpy(dir, dir_temp, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'\\'; - dir[dir_len + 1] = L'*'; - dir[dir_len + 2] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 2 + MAX_PATH); - memcpy(temp, dir_temp, sizeof(wchar_t) * dir_len); - temp[dir_len] = L'\\'; - dir_len++; - } - else { - dir = force_malloc_s(wchar_t, dir_len + 2); - memcpy(dir, dir_temp, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'*'; - dir[dir_len + 1] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 1 + MAX_PATH); - memcpy(temp, dir_temp, sizeof(wchar_t) * dir_len); - } - free(dir_temp); + std::wstring dir; + std::wstring temp; + dir.assign(dir_temp, dir_len); + if (dir.size() && dir.back() != L'\\') + dir.push_back(L'\\'); + temp.assign(dir); + dir.push_back(L'*'); + free_def(dir_temp); WIN32_FIND_DATAW fdata; memset(&fdata, 0, sizeof(WIN32_FIND_DATAW)); - HANDLE h = FindFirstFileW(dir, &fdata); - if (h == INVALID_HANDLE_VALUE) { - free(dir); - free(temp); - return; - } + HANDLE h = FindFirstFileW(dir.c_str(), &fdata); + if (h == INVALID_HANDLE_VALUE) + return {}; std::vector temp_vec; do { @@ -350,17 +256,16 @@ void path_get_directories_recursive(std::vector* directories, if (exclude_list && exclude_count) { size_t len = utf16_length(fdata.cFileName); - memcpy(temp + dir_len + 1, fdata.cFileName, sizeof(wchar_t) * len); - temp[dir_len + 1 + len] = L'\0'; + temp.append(fdata.cFileName, len); + std::string temp_utf8 = utf16_to_utf8(temp); bool exclude = false; - char* temp_utf8 = utf16_to_utf8(temp); for (size_t i = 0; i < exclude_count; i++) - if (!str_utils_compare(exclude_list[i], temp_utf8)) { + if (!temp_utf8.compare(exclude_list[i])) { exclude = true; break; } - free(temp_utf8); + temp.resize(temp.size() - len); if (exclude) continue; @@ -368,11 +273,9 @@ void path_get_directories_recursive(std::vector* directories, char* directory_temp = utf16_to_utf8(fdata.cFileName); temp_vec.push_back(directory_temp); - free(directory_temp); + free_def(directory_temp); } while (FindNextFileW(h, &fdata)); FindClose(h); - free(temp); - free(dir); size_t max_len = 0; for (std::string& i : temp_vec) { @@ -381,17 +284,17 @@ void path_get_directories_recursive(std::vector* directories, max_len = len; } - size_t path_length = utf8_length(path); - char* path_temp = force_malloc_s(char, path_length + max_len + 2); - memcpy(path_temp, path, path_length); - path_temp[path_length] = '\\'; + std::vector directories; + std::string path_temp; + path_temp.assign(path); + path_temp += '\\'; for (std::string& i : temp_vec) { - memcpy(&path_temp[path_length + 1], i.c_str(), i.size() + 1); + path_temp.append(i); + std::vector temp = path_get_directories_recursive( + path_temp.c_str(), exclude_list, exclude_count); + path_temp.resize(path_temp.size() - i.size()); - std::vector temp; - path_get_directories_recursive(&temp, path_temp, exclude_list, exclude_count); - - directories->push_back(i); + directories.push_back(i); if (temp.size() < 1) continue; @@ -403,62 +306,34 @@ void path_get_directories_recursive(std::vector* directories, max_len = len; } - size_t sub_path_length = i.size(); - char* sub_path_temp = force_malloc_s(char, sub_path_length + max_len + 1); - if (sub_path_temp) { - memcpy(sub_path_temp, i.c_str(), sub_path_length); - sub_path_temp[sub_path_length] = '\\'; - for (std::string& j : temp) { - memcpy(&sub_path_temp[sub_path_length + 1], j.c_str(), j.size()); - - std::string directory = std::string(sub_path_temp, sub_path_length + 1 + j.size()); - temp_vec.push_back(directory); - } + if (i.size()) { + std::string sub_path_temp; + sub_path_temp.assign(i); + sub_path_temp += '\\'; + for (std::string& j : temp) + directories.push_back(sub_path_temp + j); } - free(sub_path_temp); } - free(path_temp); + return directories; } -void path_get_directories_recursive(std::vector* directories, - const wchar_t* path, wchar_t** exclude_list, size_t exclude_count) { - directories->clear(); - directories->shrink_to_fit(); - +std::vector path_get_directories_recursive( + const wchar_t* path, const wchar_t** exclude_list, size_t exclude_count) { size_t dir_len = utf16_length(path); - wchar_t* dir; - wchar_t* temp; - if (path[dir_len - 1] != L'\\') { - dir = force_malloc_s(wchar_t, dir_len + 3); - memcpy(dir, path, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'\\'; - dir[dir_len + 1] = L'*'; - dir[dir_len + 2] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 2 + MAX_PATH); - memcpy(temp, path, sizeof(wchar_t) * dir_len); - temp[dir_len] = L'\\'; - dir_len++; - } - else { - dir = force_malloc_s(wchar_t, dir_len + 2); - memcpy(dir, path, sizeof(wchar_t) * dir_len); - dir[dir_len] = L'*'; - dir[dir_len + 1] = 0; - - temp = force_malloc_s(wchar_t, dir_len + 1 + MAX_PATH); - memcpy(temp, path, sizeof(wchar_t) * dir_len); - } + std::wstring dir; + std::wstring temp; + dir.assign(path, dir_len); + if (dir.size() && dir.back() != L'\\') + dir.push_back(L'\\'); + temp.assign(dir); + dir.push_back(L'*'); WIN32_FIND_DATAW fdata; memset(&fdata, 0, sizeof(WIN32_FIND_DATAW)); - HANDLE h = FindFirstFileW(dir, &fdata); - if (h == INVALID_HANDLE_VALUE) { - free(dir); - free(temp); - return; - } + HANDLE h = FindFirstFileW(dir.c_str(), &fdata); + if (h == INVALID_HANDLE_VALUE) + return {}; std::vector temp_vec; do { @@ -470,15 +345,15 @@ void path_get_directories_recursive(std::vector* directories, if (exclude_list && exclude_count) { size_t len = utf16_length(fdata.cFileName); - memcpy(temp + dir_len + 1, fdata.cFileName, sizeof(wchar_t) * len); - temp[dir_len + 1 + len] = L'\0'; + temp.append(fdata.cFileName, len); bool exclude = false; for (size_t i = 0; i < exclude_count; i++) - if (!str_utils_compare(exclude_list[i], temp)) { + if (!temp.compare(exclude_list[i])) { exclude = true; break; } + temp.resize(temp.size() - len); if (exclude) continue; @@ -488,8 +363,6 @@ void path_get_directories_recursive(std::vector* directories, temp_vec.push_back(directory); } while (FindNextFileW(h, &fdata)); FindClose(h); - free(temp); - free(dir); size_t max_len = 0; for (std::wstring& i : temp_vec) { @@ -498,17 +371,17 @@ void path_get_directories_recursive(std::vector* directories, max_len = len; } - size_t path_length = utf16_length(path); - wchar_t* path_temp = force_malloc_s(wchar_t, path_length + max_len + 2); - memcpy(path_temp, path, sizeof(wchar_t) * path_length); - path_temp[path_length] = '\\'; + std::vector directories; + std::wstring path_temp; + path_temp.assign(path); + path_temp.push_back(L'\\'); for (std::wstring& i : temp_vec) { - memcpy(&path_temp[path_length + 1], i.c_str(), sizeof(wchar_t) * (i.size() + 1)); + path_temp.append(i); + std::vector temp = path_get_directories_recursive( + path_temp.c_str(), exclude_list, exclude_count); + path_temp.resize(path_temp.size() - i.size()); - std::vector temp; - path_get_directories_recursive(&temp, path_temp, exclude_list, exclude_count); - - directories->push_back(i); + directories.push_back(i); if (temp.size() < 1) continue; @@ -520,19 +393,13 @@ void path_get_directories_recursive(std::vector* directories, max_len = len; } - size_t sub_path_length = i.size(); - wchar_t* sub_path_temp = force_malloc_s(wchar_t, sub_path_length + max_len + 1); - if (sub_path_temp) { - memcpy(sub_path_temp, i.c_str(), sizeof(wchar_t) * sub_path_length); - sub_path_temp[sub_path_length] = '\\'; - for (std::wstring& j : temp) { - memcpy(&sub_path_temp[sub_path_length + 1], j.c_str(), sizeof(wchar_t) * j.size()); - - std::wstring directory = std::wstring(sub_path_temp, sub_path_length + 1 + j.size()); - directories->push_back(directory); - } + if (i.size()) { + std::wstring sub_path_temp; + sub_path_temp.assign(i); + sub_path_temp.push_back(L'\\'); + for (std::wstring& j : temp) + directories.push_back(sub_path_temp + j); } - free(sub_path_temp); } - free(path_temp); + return directories; } diff --git a/src/KKdLib/io/path.hpp b/src/KKdLib/io/path.hpp index 4e61ccc3..970ed3bd 100644 --- a/src/KKdLib/io/path.hpp +++ b/src/KKdLib/io/path.hpp @@ -15,13 +15,13 @@ extern bool path_check_file_exists(const char* path); extern bool path_check_file_exists(const wchar_t* path); extern bool path_check_directory_exists(const char* path); extern bool path_check_directory_exists(const wchar_t* path); -extern void path_get_files(std::vector* files, const char* path); -extern void path_get_files(std::vector* files, const wchar_t* path); -extern void path_get_directories(std::vector* directories, - const char* path, char** exclude_list, size_t exclude_count); -extern void path_get_directories(std::vector* directories, - const wchar_t* path, wchar_t** exclude_list, size_t exclude_count); -extern void path_get_directories_recursive(std::vector* directories, - const char* path, char** exclude_list, size_t exclude_count); -extern void path_get_directories_recursive(std::vector* directories, - const wchar_t* path, wchar_t** exclude_list, size_t exclude_count); \ No newline at end of file +extern std::vector path_get_files(const char* path); +extern std::vector path_get_files(const wchar_t* path); +extern std::vector path_get_directories( + const char* path, const char** exclude_list, size_t exclude_count); +extern std::vector path_get_directories( + const wchar_t* path, const wchar_t** exclude_list, size_t exclude_count); +extern std::vector path_get_directories_recursive( + const char* path, const char** exclude_list, size_t exclude_count); +extern std::vector path_get_directories_recursive( + const wchar_t* path, const wchar_t** exclude_list, size_t exclude_count); \ No newline at end of file diff --git a/src/KKdLib/io/stream.cpp b/src/KKdLib/io/stream.cpp index f5a93eac..f21c92f8 100644 --- a/src/KKdLib/io/stream.cpp +++ b/src/KKdLib/io/stream.cpp @@ -4,37 +4,8 @@ */ #include "stream.hpp" -#include -stream::io::io() : stream(), data() { - -} - -stream::io::~io() { - -} - -bool stream::io::check_null() { - return !stream && !data.vec.size(); -} - -bool stream::io::check_not_null() { - return stream || data.vec.size(); -} - -void stream::io::close() { - if (stream) { - fflush(stream); - fclose(stream); - stream = 0; - } - - data.vec.clear(); - data.vec.shrink_to_fit(); - data.data = data.vec.begin(); -} - -stream::stream() : buf(), length(), type(), is_big_endian() { +stream::stream() : buf(), length(), big_endian() { } @@ -42,196 +13,17 @@ stream::~stream() { close(); } -void stream::open() { - close(); - - type = STREAM_MEMORY; - length = 0; -} - -void stream::open(const char* path, const char* mode) { - close(); - - if (!path || !mode) - return; - - wchar_t* temp_path = utf8_to_utf16(path); - wchar_t* temp_mode = utf8_to_utf16((char*)mode); - io.stream = _wfsopen(temp_path, temp_mode, _SH_DENYNO); - type = io.stream && !ferror(io.stream) ? STREAM_FILE : STREAM_NONE; - get_length(); - free(temp_path); - free(temp_mode); -} - -void stream::open(const wchar_t* path, const wchar_t* mode) { - close(); - - if (!path || !mode) - return; - - io.stream = _wfsopen(path, mode, _SH_DENYNO); - type = io.stream && !ferror(io.stream) ? STREAM_FILE : STREAM_NONE; - get_length(); -} - -void stream::open(const void* data, size_t size) { - close(); - - if (!data || !size) { - type = STREAM_MEMORY; - length = 0; - return; - } - - io.data.vec = {}; - io.data.vec.resize(size); - if (io.data.vec.data() && data) - memcpy(io.data.vec.data(), data, size); - io.data.data = io.data.vec.begin(); - type = STREAM_MEMORY; - length = size; -} - -void stream::open(std::vector& data) { - close(); - - if (!data.size()) { - type = STREAM_MEMORY; - length = 0; - return; - } - - io.data.vec = data; - io.data.data = io.data.vec.begin(); - type = STREAM_MEMORY; - length = data.size(); -} - -void stream::copy(void** data, size_t* size) { - if (!this || !data || !size || type != STREAM_MEMORY) - return; - - *size = io.data.vec.size(); - *data = force_malloc(*size); - memcpy(*data, io.data.vec.data(), *size); -} - -void stream::copy(std::vector& data) { - if (!this || type != STREAM_MEMORY) - return; - - size_t length = io.data.vec.size(); - data.resize(length); - memcpy(data.data(), io.data.vec.data(), length); -} - -int stream::flush() { - switch (type) { - case STREAM_FILE: - return fflush(io.stream); - case STREAM_MEMORY: - return 0; - default: - return 0; - } -} - void stream::close() { if (!this) return; memset(buf, 0, sizeof(buf)); - io.close(); length = 0; - type = STREAM_NONE; - is_big_endian = false; + big_endian = false; position_stack.clear(); position_stack.shrink_to_fit(); } -int64_t stream::get_length() { - switch (type) { - case STREAM_FILE: - if (io.stream) { - size_t temp = _ftelli64(io.stream); - _fseeki64(io.stream, 0, SEEK_END); - length = _ftelli64(io.stream); - _fseeki64(io.stream, temp, SEEK_SET); - } - else - length = 0; - break; - case STREAM_MEMORY: - length = io.data.vec.size(); - break; - default: - length = 0; - break; - } - return length; -} - -int64_t stream::get_position() { - switch (type) { - case STREAM_FILE: - return _ftelli64(io.stream); - case STREAM_MEMORY: - return io.data.data - io.data.vec.begin(); - default: - return EOF; - } -} - -int32_t stream::set_position(int64_t pos, int32_t seek) { - switch (type) { - case STREAM_FILE: - return _fseeki64(io.stream, pos, seek); - case STREAM_MEMORY: - switch (seek) { - case SEEK_SET: { - if (pos < 0) - return EOF; - - if (io.data.vec.size() < (size_t)pos) { - size_t size = io.data.vec.size(); - io.data.vec.resize(pos); - memset(io.data.vec.data() + size, 0, pos - size); - } - io.data.data = io.data.vec.begin() + pos; - } return 0; - case SEEK_CUR: { - if (pos > 0) { - size_t _pos = io.data.data - io.data.vec.begin(); - if (io.data.vec.size() < (size_t)(_pos + pos)) { - size_t size = io.data.vec.size(); - io.data.vec.resize(_pos + pos); - memset(io.data.vec.data() + size, 0, _pos + pos - size); - io.data.data = io.data.vec.begin() + _pos; - } - io.data.data += pos; - } - else if (pos < 0) { - if (io.data.data - io.data.vec.begin() < -pos) - return EOF; - else - io.data.data += pos; - } - } return 0; - case SEEK_END: { - if (pos < 0) - break; - - if (io.data.vec.size() < (size_t)pos) - break; - - io.data.data = io.data.vec.end() - pos; - } return 0; - } - } - return EOF; -} - int32_t stream::position_push(int64_t pos, int32_t seek) { position_stack.push_back(get_position()); return set_position(pos, seek); @@ -247,181 +39,6 @@ void stream::position_pop() { flush(); } -void stream::align_read(int64_t align) { - int64_t position; - switch (type) { - case STREAM_FILE: - position = _ftelli64(io.stream); - break; - case STREAM_MEMORY: - position = io.data.data - io.data.vec.begin(); - break; - default: - return; - } - - size_t temp_align = align - position % align; - if (align != temp_align) - switch (type) { - case STREAM_FILE: - _fseeki64(io.stream, position + temp_align, 0); - break; - case STREAM_MEMORY: { - size_t pos = io.data.data - io.data.vec.begin(); - if (io.data.vec.size() < (size_t)(pos + temp_align)) { - size_t size = io.data.vec.size(); - io.data.vec.resize(pos + temp_align); - io.data.data = io.data.vec.begin() + pos; - memset(io.data.data._Ptr, 0, temp_align); - } - io.data.data += temp_align; - } break; - } -} - -void stream::align_write(int64_t align) { - int64_t position; - switch (type) { - case STREAM_FILE: - position = _ftelli64(io.stream); - break; - case STREAM_MEMORY: - position = io.data.data - io.data.vec.begin(); - break; - default: - return; - } - - size_t temp_align = align - position % align; - if (align != temp_align) - switch (type) { - case STREAM_FILE: { - memset(buf, 0, min(sizeof(buf), temp_align)); - size_t i = temp_align; - while (i >= sizeof(buf)) { - fwrite(buf, 1, sizeof(buf), io.stream); - i -= sizeof(buf); - } - - if (i > 0) - fwrite(buf, 1, i, io.stream); - } break; - case STREAM_MEMORY: { - size_t pos = io.data.data - io.data.vec.begin(); - if (io.data.vec.size() < (size_t)(pos + temp_align)) { - size_t size = io.data.vec.size(); - io.data.vec.resize(pos + temp_align); - io.data.data = io.data.vec.begin() + pos; - memset(io.data.data._Ptr, 0, temp_align); - } - io.data.data += temp_align; - } break; - } -} - -int64_t stream::read(int64_t count) { - return read((void*)0, count); -} - -int64_t stream::read(void* buf, int64_t count) { - switch (type) { - case STREAM_FILE: - if (!buf) { - int64_t act_count = 0; - while (count > 0) { - act_count += fread(this->buf, 1, min(count, sizeof(this->buf)), io.stream); - count -= sizeof(this->buf); - } - return act_count; - } - else - return fread(buf, 1, count, io.stream); - case STREAM_MEMORY: { - if (io.data.data >= io.data.vec.end()) - return EOF; - - size_t _count = io.data.vec.end() - io.data.data; - if (_count >= (size_t)count) - _count = count; - if (buf) - memcpy(buf, io.data.data._Ptr, _count); - io.data.data += _count; - return _count; - } - default: - return EOF; - } -} - -int64_t stream::write(int64_t count) { - return write(0, count); -} - -int64_t stream::write(const void* buf, int64_t count) { - switch (type) { - case STREAM_FILE: - if (!buf) { - memset(this->buf, 0, sizeof(this->buf)); - int64_t act_count = 0; - while (count > 0) { - act_count += fwrite(this->buf, 1, min(count, sizeof(this->buf)), io.stream); - count -= sizeof(this->buf); - } - return act_count; - } - else - return fwrite(buf, 1, count, io.stream); - case STREAM_MEMORY: { - size_t pos = io.data.data - io.data.vec.begin(); - if (io.data.vec.size() < (size_t)(pos + count)) { - size_t size = io.data.vec.size(); - io.data.vec.resize(pos + count); - io.data.data = io.data.vec.begin() + pos; - } - if (buf) - memcpy(io.data.data._Ptr, buf, count); - else - memset(io.data.data._Ptr, 0, count); - io.data.data += count; - return count; - } - default: - return EOF; - } -} - -int32_t stream::read_char() { - switch (type) { - case STREAM_FILE: - return fgetc(io.stream); - case STREAM_MEMORY: - if (io.data.data >= io.data.vec.end()) - return EOF; - return *(io.data.data++); - default: - return EOF; - } -} - -int32_t stream::write_char(char c) { - switch (type) { - case STREAM_FILE: - return fputc(c, io.stream); - case STREAM_MEMORY: { - size_t pos = io.data.data - io.data.vec.begin(); - if (io.data.vec.size() < (size_t)(pos + 1)) { - size_t size = io.data.vec.size(); - io.data.vec.resize(pos + 1); - io.data.data = io.data.vec.begin() + pos; - } - *(io.data.data++) = c; - return 0; - } - default: - return EOF; - } -} - int8_t stream::read_int8_t() { int32_t c = read_char(); if (c != EOF) @@ -437,11 +54,11 @@ uint8_t stream::read_uint8_t() { } void stream::write_int8_t(int8_t val) { - stream::write_char((char)val); + write_char((char)val); } void stream::write_uint8_t(uint8_t val) { - stream::write_char((char)val); + write_char((char)val); } std::string stream::read_string(size_t length) { @@ -449,7 +66,7 @@ std::string stream::read_string(size_t length) { read(temp, length); temp[length] = 0; std::string str = std::string(temp, length); - free(temp); + free_def(temp); return str; } @@ -458,7 +75,7 @@ std::wstring stream::read_wstring(size_t length) { read(temp, sizeof(wchar_t) * length); temp[length] = 0; std::wstring str = std::wstring(temp, length); - free(temp); + free_def(temp); return str; } @@ -467,7 +84,7 @@ std::string stream::read_string_null_terminated() { int64_t length = 0; char* temp = read_utf8_string_null_terminated_offset_length(offset, &length); std::string str = std::string(temp, length); - free(temp); + free_def(temp); return str; } @@ -476,7 +93,7 @@ std::wstring stream::read_wstring_null_terminated() { int64_t length = 0; wchar_t* temp = read_utf16_string_null_terminated_offset_length(offset, &length); std::wstring str = std::wstring(temp, length); - free(temp); + free_def(temp); return str; } @@ -485,7 +102,7 @@ std::string stream::read_string_null_terminated_offset(int64_t offset) { int64_t length = 0; char* temp = read_utf8_string_null_terminated_offset_length(offset, &length); std::string str = std::string(temp, length); - free(temp); + free_def(temp); return str; } else { @@ -499,7 +116,7 @@ std::wstring stream::read_wstring_null_terminated_offset(int64_t offset) { int64_t length = 0; wchar_t* temp = read_utf16_string_null_terminated_offset_length(offset, &length); std::wstring str = std::wstring(temp, length); - free(temp); + free_def(temp); return str; } else { @@ -597,7 +214,7 @@ int16_t stream::read_int16_t() { int16_t stream::read_int16_t_reverse_endianness() { read(buf, sizeof(int16_t)); int16_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_int16_t(buf); else val = *(int16_t*)buf; @@ -620,8 +237,8 @@ void stream::write_int16_t(int16_t val) { } void stream::write_int16_t_reverse_endianness(int16_t val) { - if (is_big_endian) - store_reverse_endianness_int16_t(val, buf); + if (big_endian) + store_reverse_endianness_int16_t(buf, val); else *(int16_t*)buf = val; write(buf, sizeof(int16_t)); @@ -629,7 +246,7 @@ void stream::write_int16_t_reverse_endianness(int16_t val) { void stream::write_int16_t_reverse_endianness(int16_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_int16_t(val, buf); + store_reverse_endianness_int16_t(buf, val); else *(int16_t*)buf = val; write(buf, sizeof(int16_t)); @@ -643,7 +260,7 @@ uint16_t stream::read_uint16_t() { uint16_t stream::read_uint16_t_reverse_endianness() { read(buf, sizeof(uint16_t)); uint16_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_uint16_t(buf); else val = *(uint16_t*)buf; @@ -666,8 +283,8 @@ void stream::write_uint16_t(uint16_t val) { } void stream::write_uint16_t_reverse_endianness(uint16_t val) { - if (is_big_endian) - store_reverse_endianness_uint16_t(val, buf); + if (big_endian) + store_reverse_endianness_uint16_t(buf, val); else *(uint16_t*)buf = val; write(buf, sizeof(uint16_t)); @@ -675,7 +292,7 @@ void stream::write_uint16_t_reverse_endianness(uint16_t val) { void stream::write_uint16_t_reverse_endianness(uint16_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_uint16_t(val, buf); + store_reverse_endianness_uint16_t(buf, val); else *(uint16_t*)buf = val; write(buf, sizeof(uint16_t)); @@ -689,7 +306,7 @@ int32_t stream::read_int32_t() { int32_t stream::read_int32_t_reverse_endianness() { read(buf, sizeof(int32_t)); int32_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_int32_t(buf); else val = *(int32_t*)buf; @@ -712,8 +329,8 @@ void stream::write_int32_t(int32_t val) { } void stream::write_int32_t_reverse_endianness(int32_t val) { - if (is_big_endian) - store_reverse_endianness_int32_t(val, buf); + if (big_endian) + store_reverse_endianness_int32_t(buf, val); else *(int32_t*)buf = val; write(buf, sizeof(int32_t)); @@ -721,7 +338,7 @@ void stream::write_int32_t_reverse_endianness(int32_t val) { void stream::write_int32_t_reverse_endianness(int32_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_int32_t(val, buf); + store_reverse_endianness_int32_t(buf, val); else *(int32_t*)buf = val; write(buf, sizeof(int32_t)); @@ -735,7 +352,7 @@ uint32_t stream::read_uint32_t() { uint32_t stream::read_uint32_t_reverse_endianness() { read(buf, sizeof(uint32_t)); uint32_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_uint32_t(buf); else val = *(uint32_t*)buf; @@ -758,8 +375,8 @@ void stream::write_uint32_t(uint32_t val) { } void stream::write_uint32_t_reverse_endianness(uint32_t val) { - if (is_big_endian) - store_reverse_endianness_uint32_t(val, buf); + if (big_endian) + store_reverse_endianness_uint32_t(buf, val); else *(uint32_t*)buf = val; write(buf, sizeof(uint32_t)); @@ -767,7 +384,7 @@ void stream::write_uint32_t_reverse_endianness(uint32_t val) { void stream::write_uint32_t_reverse_endianness(uint32_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_uint32_t(val, buf); + store_reverse_endianness_uint32_t(buf, val); else *(uint32_t*)buf = val; write(buf, sizeof(uint32_t)); @@ -781,7 +398,7 @@ int64_t stream::read_int64_t() { int64_t stream::read_int64_t_reverse_endianness() { read(buf, sizeof(int64_t)); int64_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_int64_t(buf); else val = *(int64_t*)buf; @@ -804,8 +421,8 @@ void stream::write_int64_t(int64_t val) { } void stream::write_int64_t_reverse_endianness(int64_t val) { - if (is_big_endian) - store_reverse_endianness_int64_t(val, buf); + if (big_endian) + store_reverse_endianness_int64_t(buf, val); else *(int64_t*)buf = val; write(buf, sizeof(int64_t)); @@ -813,7 +430,7 @@ void stream::write_int64_t_reverse_endianness(int64_t val) { void stream::write_int64_t_reverse_endianness(int64_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_int64_t(val, buf); + store_reverse_endianness_int64_t(buf, val); else *(int64_t*)buf = val; write(buf, sizeof(int64_t)); @@ -827,7 +444,7 @@ uint64_t stream::read_uint64_t() { uint64_t stream::read_uint64_t_reverse_endianness() { read(buf, sizeof(uint64_t)); uint64_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_uint64_t(buf); else val = *(uint64_t*)buf; @@ -850,8 +467,8 @@ void stream::write_uint64_t(uint64_t val) { } void stream::write_uint64_t_reverse_endianness(uint64_t val) { - if (is_big_endian) - store_reverse_endianness_uint64_t(val, buf); + if (big_endian) + store_reverse_endianness_uint64_t(buf, val); else *(uint64_t*)buf = val; write(buf, sizeof(uint64_t)); @@ -859,7 +476,7 @@ void stream::write_uint64_t_reverse_endianness(uint64_t val) { void stream::write_uint64_t_reverse_endianness(uint64_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_uint64_t(val, buf); + store_reverse_endianness_uint64_t(buf, val); else *(uint64_t*)buf = val; write(buf, sizeof(uint64_t)); @@ -873,7 +490,7 @@ half_t stream::read_half_t() { half_t stream::read_half_t_reverse_endianness() { read(buf, sizeof(half_t)); half_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_half_t(buf); else val = *(half_t*)buf; @@ -896,8 +513,8 @@ void stream::write_half_t(half_t val) { } void stream::write_half_t_reverse_endianness(half_t val) { - if (is_big_endian) - store_reverse_endianness_half_t(val, buf); + if (big_endian) + store_reverse_endianness_half_t(buf, val); else *(half_t*)buf = val; write(buf, sizeof(half_t)); @@ -905,7 +522,7 @@ void stream::write_half_t_reverse_endianness(half_t val) { void stream::write_half_t_reverse_endianness(half_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_half_t(val, buf); + store_reverse_endianness_half_t(buf, val); else *(half_t*)buf = val; write(buf, sizeof(half_t)); @@ -919,7 +536,7 @@ float_t stream::read_float_t() { float_t stream::read_float_t_reverse_endianness() { read(buf, sizeof(float_t)); float_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_float_t(buf); else val = *(float_t*)buf; @@ -942,8 +559,8 @@ void stream::write_float_t(float_t val) { } void stream::write_float_t_reverse_endianness(float_t val) { - if (is_big_endian) - store_reverse_endianness_float_t(val, buf); + if (big_endian) + store_reverse_endianness_float_t(buf, val); else *(float_t*)buf = val; write(buf, sizeof(float_t)); @@ -951,7 +568,7 @@ void stream::write_float_t_reverse_endianness(float_t val) { void stream::write_float_t_reverse_endianness(float_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_float_t(val, buf); + store_reverse_endianness_float_t(buf, val); else *(float_t*)buf = val; write(buf, sizeof(float_t)); @@ -965,7 +582,7 @@ double_t stream::read_double_t() { double_t stream::read_double_t_reverse_endianness() { read(buf, sizeof(double_t)); double_t val; - if (is_big_endian) + if (big_endian) val = load_reverse_endianness_double_t(buf); else val = *(double_t*)buf; @@ -988,8 +605,8 @@ void stream::write_double_t(double_t val) { } void stream::write_double_t_reverse_endianness(double_t val) { - if (is_big_endian) - store_reverse_endianness_double_t(val, buf); + if (big_endian) + store_reverse_endianness_double_t(buf, val); else *(double_t*)buf = val; write(buf, sizeof(double_t)); @@ -997,7 +614,7 @@ void stream::write_double_t_reverse_endianness(double_t val) { void stream::write_double_t_reverse_endianness(double_t val, bool big_endian) { if (big_endian) - store_reverse_endianness_double_t(val, buf); + store_reverse_endianness_double_t(buf, val); else *(double_t*)buf = val; write(buf, sizeof(double_t)); diff --git a/src/KKdLib/io/stream.hpp b/src/KKdLib/io/stream.hpp index bf2c4108..d545797a 100644 --- a/src/KKdLib/io/stream.hpp +++ b/src/KKdLib/io/stream.hpp @@ -10,62 +10,38 @@ #include "../default.hpp" #include "../half_t.hpp" -enum stream_type { - STREAM_NONE = 0, - STREAM_FILE, - STREAM_MEMORY, -}; - -struct stream { - +class stream { +public: uint8_t buf[0x100]; - struct io { - FILE* stream; - struct data { - std::vector::iterator data; - std::vector vec; - } data; - - io(); - ~io(); - - bool check_null(); - bool check_not_null(); - void close(); - } io; int64_t length; - stream_type type; - bool is_big_endian; + bool big_endian; std::vector position_stack; stream(); - ~stream(); + virtual ~stream(); - void open(); - void open(const char* path, const char* mode); - void open(const wchar_t* path, const wchar_t* mode); - void open(const void* data, size_t size); - void open(std::vector& data); - void copy(void** data, size_t* size); - void copy(std::vector& data); - int flush(); - void close(); + virtual int flush() = 0; + virtual void close(); + virtual bool check_null() = 0; + virtual bool check_not_null() = 0; + + virtual void align_read(size_t align) = 0; + virtual void align_write(size_t align) = 0; + virtual size_t read(size_t count) = 0; + virtual size_t read(void* buf, size_t count) = 0; + virtual size_t read(void* buf, size_t size, size_t count) = 0; + virtual size_t write(size_t count) = 0; + virtual size_t write(const void* buf, size_t count) = 0; + virtual size_t write(const void* buf, size_t size, size_t count) = 0; + virtual int32_t read_char() = 0; + virtual int32_t write_char(char c) = 0; + virtual int64_t get_length() = 0; + virtual int64_t get_position() = 0; + virtual int32_t set_position(int64_t pos, int32_t seek) = 0; - int64_t get_length(); - int64_t get_position(); - int32_t set_position(int64_t pos, int32_t seek); int32_t position_push(int64_t pos, int32_t seek); void position_pop(); - void align_read(int64_t align); - void align_write(int64_t align); - int64_t read(int64_t count); - int64_t read(void* buf, int64_t count); - int64_t write(int64_t count); - int64_t write(const void* buf, int64_t count); - int32_t read_char(); - int32_t write_char(char c); - int8_t read_int8_t(); uint8_t read_uint8_t(); void write_int8_t(int8_t val); diff --git a/src/KKdLib/key_val.cpp b/src/KKdLib/key_val.cpp index c5758a03..9c668a18 100644 --- a/src/KKdLib/key_val.cpp +++ b/src/KKdLib/key_val.cpp @@ -4,6 +4,7 @@ */ #include "key_val.hpp" +#include "io/file_stream.hpp" #include "io/path.hpp" #include "hash.hpp" #include "str_utils.hpp" @@ -47,7 +48,7 @@ key_val::key_val() : curr_scope(), buf(), scope_size() { } key_val::~key_val() { - free(buf); + free_def(buf); } void key_val::close_scope() { @@ -67,13 +68,13 @@ void key_val::file_read(const char* path) { if (!path || !path_check_file_exists(path)) return; - stream s; + file_stream s; s.open(path, "rb"); - if (s.io.stream) { + if (s.check_not_null()) { char* d = force_malloc_s(char, s.length); s.read(d, s.length); parse((uint8_t*)d, s.length); - free(d); + free_def(d); } } @@ -81,13 +82,13 @@ void key_val::file_read(const wchar_t* path) { if (!path || !path_check_file_exists(path)) return; - stream s; + file_stream s; s.open(path, L"rb"); - if (s.io.stream) { + if (s.check_not_null()) { char* d = force_malloc_s(char, s.length); s.read(d, s.length); parse((uint8_t*)d, s.length); - free(d); + free_def(d); } } @@ -120,8 +121,8 @@ bool key_val::has_key(std::string& str) { bool key_val::open_scope(const char* str) { if (!str || !*str) { scope_size++; - if ((size_t)scope_size > scope.size()) - scope.resize(scope_size + (scope_size >> 1) + 1);; + if ((size_t)scope_size >= scope.size()) + scope.resize(scope_size + (scope_size >> 1) + 1); curr_scope = &scope[scope_size]; key_val_scope* prev_scope = curr_scope - 1; @@ -153,7 +154,7 @@ bool key_val::open_scope(const char* str) { scope_size++; if ((size_t)scope_size >= scope.size()) - scope.resize(scope_size + (scope_size >> 1) + 1);; + scope.resize(scope_size + (scope_size >> 1) + 1); curr_scope = &scope[scope_size]; if (curr_scope[-1].key.size()) { @@ -178,7 +179,7 @@ bool key_val::open_scope(std::string& str) { if (!str.size()) { scope_size++; if ((size_t)scope_size >= scope.size()) - scope.resize(scope_size + (scope_size >> 1) + 1);; + scope.resize(scope_size + (scope_size >> 1) + 1); curr_scope = &scope[scope_size]; key_val_scope* prev_scope = curr_scope - 1; @@ -210,7 +211,7 @@ bool key_val::open_scope(std::string& str) { scope_size++; if ((size_t)scope_size >= scope.size()) - scope.resize(scope_size + (scope_size >> 1) + 1);; + scope.resize(scope_size + (scope_size >> 1) + 1); curr_scope = &scope[scope_size]; if (curr_scope[-1].key.size()) { @@ -261,7 +262,7 @@ void key_val::parse(const void* data, size_t size) { char** lines; size_t count; - if (!str_utils_text_file_parse(data, size, &buf, &lines, &count)) + if (!str_utils_text_file_parse(data, size, buf, lines, count)) return; key.reserve(count); @@ -299,7 +300,7 @@ void key_val::parse(const void* data, size_t size) { curr_scope->count = key.size(); key_val_sort(this); - free(lines) + free_def(lines) } bool key_val::read(bool& value) { @@ -1080,10 +1081,14 @@ static int64_t key_val_find_first_key(key_val* kv, int64_t low, int64_t high, key_val_pair* l = &k[mid = (low + high) / 2]; if (l->length > offset && s_len <= l->length - offset) { res = memcmp(s, l->str + offset, s_len); + if (!res && l->str[offset + s_len] && l->str[offset + s_len] != '.') + res = -1; full = true; } else { res = str_utils_compare_length(s, s_len, l->str + offset, l->length - offset); + if (!res && s[l->length - offset]) + res = 1; full = false; } @@ -1112,10 +1117,14 @@ static int64_t key_val_find_last_key(key_val* kv, int64_t low, int64_t high, key_val_pair* l = &k[mid = (low + high) / 2]; if (l->length > offset && s_len <= l->length - offset) { res = memcmp(s, l->str + offset, s_len); + if (!res && l->str[offset + s_len] && l->str[offset + s_len] != '.') + res = -1; full = true; } else { res = str_utils_compare_length(s, s_len, l->str + offset, l->length - offset); + if (!res && s[l->length - offset]) + res = 1; full = false; } diff --git a/src/KKdLib/light_param/face.cpp b/src/KKdLib/light_param/face.cpp index 1d8cc3b8..e26e17e4 100644 --- a/src/KKdLib/light_param/face.cpp +++ b/src/KKdLib/light_param/face.cpp @@ -4,8 +4,9 @@ */ #include "face.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../str_utils.hpp" static void light_param_face_read_inner(light_param_face* face, stream& s); @@ -25,27 +26,27 @@ light_param_face::~light_param_face() { void light_param_face::read(const char* path) { char* path_txt = str_utils_add(path, ".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, "rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_face_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_face::read(const wchar_t* path) { wchar_t* path_txt = str_utils_add(path, L".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, L"rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_face_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_face::read(const void* data, size_t size) { - stream s; + memory_stream s; s.open(data, size); light_param_face_read_inner(this, s); } @@ -55,11 +56,11 @@ void light_param_face::write(const char* path) { return; char* path_txt = str_utils_add(path, ".txt"); - stream s; + file_stream s; s.open(path_txt, "wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_face_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_face::write(const wchar_t* path) { @@ -67,18 +68,18 @@ void light_param_face::write(const wchar_t* path) { return; wchar_t* path_txt = str_utils_add(path, L".txt"); - stream s; + file_stream s; s.open(path_txt, L"wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_face_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_face::write(void** data, size_t* size) { if (!data || !ready) return; - stream s; + memory_stream s; s.open(); light_param_face_write_inner(this, s); s.copy(data, size); @@ -130,12 +131,12 @@ static void light_param_face_read_inner(light_param_face* face, stream& s) { } } - free(data); + free_def(data); face->ready = true; return; End: - free(data); + free_def(data); } static void light_param_face_write_inner(light_param_face* face, stream& s) { diff --git a/src/KKdLib/light_param/fog.cpp b/src/KKdLib/light_param/fog.cpp index 8b156196..76032ed6 100644 --- a/src/KKdLib/light_param/fog.cpp +++ b/src/KKdLib/light_param/fog.cpp @@ -4,8 +4,9 @@ */ #include "fog.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../str_utils.hpp" static void light_param_fog_read_inner(light_param_fog* fog, stream& s); @@ -25,27 +26,27 @@ light_param_fog::~light_param_fog() { void light_param_fog::read(const char* path) { char* path_txt = str_utils_add(path, ".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, "rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_fog_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_fog::read(const wchar_t* path) { wchar_t* path_txt = str_utils_add(path, L".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, L"rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_fog_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_fog::read(const void* data, size_t size) { - stream s; + memory_stream s; s.open(data, size); light_param_fog_read_inner(this, s); } @@ -55,11 +56,11 @@ void light_param_fog::write(const char* path) { return; char* path_txt = str_utils_add(path, ".txt"); - stream s; + file_stream s; s.open(path_txt, "wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_fog_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_fog::write(const wchar_t* path) { @@ -67,18 +68,18 @@ void light_param_fog::write(const wchar_t* path) { return; wchar_t* path_txt = str_utils_add(path, L".txt"); - stream s; + file_stream s; s.open(path_txt, L"wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_fog_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_fog::write(void** data, size_t* size) { if (!data || !ready) return; - stream s; + memory_stream s; s.open(); light_param_fog_write_inner(this, s); s.copy(data, size); @@ -177,12 +178,12 @@ static void light_param_fog_read_inner(light_param_fog* fog, stream& s) { } } - free(data); + free_def(data); fog->ready = true; return; End: - free(data); + free_def(data); } static void light_param_fog_write_inner(light_param_fog* fog, stream& s) { diff --git a/src/KKdLib/light_param/glow.cpp b/src/KKdLib/light_param/glow.cpp index 7948adf4..9fbb31b2 100644 --- a/src/KKdLib/light_param/glow.cpp +++ b/src/KKdLib/light_param/glow.cpp @@ -4,8 +4,9 @@ */ #include "glow.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../str_utils.hpp" static void light_param_glow_read_inner(light_param_glow* glow, stream& s); @@ -29,27 +30,27 @@ light_param_glow::~light_param_glow() { void light_param_glow::read(const char* path) { char* path_txt = str_utils_add(path, ".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, "rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_glow_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_glow::read(const wchar_t* path) { wchar_t* path_txt = str_utils_add(path, L".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, L"rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_glow_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_glow::read(const void* data, size_t size) { - stream s; + memory_stream s; s.open(data, size); light_param_glow_read_inner(this, s); } @@ -59,11 +60,11 @@ void light_param_glow::write(const char* path) { return; char* path_txt = str_utils_add(path, ".txt"); - stream s; + file_stream s; s.open(path_txt, "wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_glow_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_glow::write(const wchar_t* path) { @@ -71,18 +72,18 @@ void light_param_glow::write(const wchar_t* path) { return; wchar_t* path_txt = str_utils_add(path, L".txt"); - stream s; + file_stream s; s.open(path_txt, L"wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_glow_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_glow::write(void** data, size_t* size) { if (!data || !ready) return; - stream s; + memory_stream s; s.open(); light_param_glow_write_inner(this, s); s.copy(data, size); @@ -194,12 +195,12 @@ static void light_param_glow_read_inner(light_param_glow* glow, stream& s) { } } - free(data); + free_def(data); glow->ready = true; return; End: - free(data); + free_def(data); } static void light_param_glow_write_inner(light_param_glow* glow, stream& s) { diff --git a/src/KKdLib/light_param/ibl.cpp b/src/KKdLib/light_param/ibl.cpp index d63a68c6..cd33eaa4 100644 --- a/src/KKdLib/light_param/ibl.cpp +++ b/src/KKdLib/light_param/ibl.cpp @@ -4,8 +4,9 @@ */ #include "ibl.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../str_utils.hpp" static void light_param_ibl_read_inner(light_param_ibl* ibl, stream& s); @@ -24,27 +25,27 @@ light_param_ibl::~light_param_ibl() { void light_param_ibl::read(const char* path) { char* path_ibl = str_utils_add(path, ".ibl"); if (path_check_file_exists(path_ibl)) { - stream s; + file_stream s; s.open(path_ibl, "rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_ibl_read_inner(this, s); } - free(path_ibl); + free_def(path_ibl); } void light_param_ibl::read(const wchar_t* path) { wchar_t* path_ibl = str_utils_add(path, L".ibl"); if (path_check_file_exists(path_ibl)) { - stream s; + file_stream s; s.open(path_ibl, L"rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_ibl_read_inner(this, s); } - free(path_ibl); + free_def(path_ibl); } void light_param_ibl::read(const void* data, size_t size) { - stream s; + memory_stream s; s.open(data, size); light_param_ibl_read_inner(this, s); } @@ -220,12 +221,12 @@ static void light_param_ibl_read_inner(light_param_ibl* ibl, stream& s) { goto End; } - free(data); + free_def(data); ibl->ready = true; return; End: - free(data); + free_def(data); } static const char* light_param_ibl_read_line(char* buf, int32_t size, const char* src) { @@ -284,8 +285,8 @@ static void light_param_ibl_specular_generate_mipmaps(light_param_ibl_specular* for (size_t j = 0; j < data_size_2; j++) data[j] = float_to_half(temp[j]); } - free(data_f32[0]); - free(data_f32[1]); + free_def(data_f32[0]); + free_def(data_f32[1]); } static void light_param_ibl_specular_generate_mipmap(float_t* src, float_t* dst, size_t size) { diff --git a/src/KKdLib/light_param/light.cpp b/src/KKdLib/light_param/light.cpp index 63bed58c..c50bdb6f 100644 --- a/src/KKdLib/light_param/light.cpp +++ b/src/KKdLib/light_param/light.cpp @@ -4,8 +4,9 @@ */ #include "light.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../str_utils.hpp" static void light_param_light_read_inner(light_param_light* light, stream& s); @@ -25,27 +26,27 @@ light_param_light::~light_param_light() { void light_param_light::read(const char* path) { char* path_txt = str_utils_add(path, ".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, "rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_light_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_light::read(const wchar_t* path) { wchar_t* path_txt = str_utils_add(path, L".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, L"rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_light_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_light::read(const void* data, size_t size) { - stream s; + memory_stream s; s.open(data, size); light_param_light_read_inner(this, s); } @@ -55,11 +56,11 @@ void light_param_light::write(const char* path) { return; char* path_txt = str_utils_add(path, ".txt"); - stream s; + file_stream s; s.open(path_txt, "wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_light_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_light::write(const wchar_t* path) { @@ -67,18 +68,18 @@ void light_param_light::write(const wchar_t* path) { return; wchar_t* path_txt = str_utils_add(path, L".txt"); - stream s; + file_stream s; s.open(path_txt, L"wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_light_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_light::write(void** data, size_t* size) { if (!data || !ready) return; - stream s; + memory_stream s; s.open(); light_param_light_write_inner(this, s); s.copy(data, size); @@ -245,9 +246,9 @@ static void light_param_light_read_inner(light_param_light* light, stream& s) { light->has_spot_cutoff = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "attenuation", 11)) { - vec3& attenuation = light->attenuation; + light_attenuation& attenuation = light->attenuation; if (buf[11] != ' ' || sscanf_s(buf + 12, "%f %f %f", - &attenuation.x, &attenuation.y, &attenuation.z) != 3) + &attenuation.constant, &attenuation.linear, &attenuation.quadratic) != 3) goto End; light->has_attenuation = true; @@ -258,28 +259,28 @@ static void light_param_light_read_inner(light_param_light* light, stream& s) { &clip_plane[0], &clip_plane[1], &clip_plane[2], &clip_plane[3]) != 4) goto End; - light->clip_plane[0] = clip_plane[0] ? true : false; - light->clip_plane[1] = clip_plane[1] ? true : false; - light->clip_plane[2] = clip_plane[2] ? true : false; - light->clip_plane[3] = clip_plane[3] ? true : false; + light->clip_plane.data[0] = clip_plane[0] ? true : false; + light->clip_plane.data[1] = clip_plane[1] ? true : false; + light->clip_plane.data[2] = clip_plane[2] ? true : false; + light->clip_plane.data[3] = clip_plane[3] ? true : false; light->has_clip_plane = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "tonecurve", 9)) { - vec3& tone_curve = light->tone_curve; + light_tone_curve& tone_curve = light->tone_curve; if (buf[9] != ' ' || sscanf_s(buf + 10, "%f %f %f", - &tone_curve.x, &tone_curve.y, &tone_curve.z) != 3) + &tone_curve.start_point, &tone_curve.end_point, &tone_curve.coefficient) != 3) goto End; light->has_tone_curve = true; } } - free(data); + free_def(data); light->ready = true; return; End: - free(data); + free_def(data); } static void light_param_light_write_inner(light_param_light* light, stream& s) { @@ -367,30 +368,30 @@ static void light_param_light_write_inner(light_param_light* light, stream& s) { } if (light->has_attenuation) { - vec3& attenuation = light->attenuation; + light_attenuation& attenuation = light->attenuation; s.write("attenuation", 11); - light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.x); - light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.y); - light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.z); + light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.constant); + light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.linear); + light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.quadratic); s.write_char('\n'); } if (light->has_clip_plane) { - bool* clip_plane = light->clip_plane; + light_clip_plane& clip_plane = light->clip_plane; s.write("clipplane", 10); - light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane[0] ? 1 : 0); - light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane[1] ? 1 : 0); - light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane[2] ? 1 : 0); - light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane[3] ? 1 : 0); + light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane.data[0] ? 1 : 0); + light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane.data[1] ? 1 : 0); + light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane.data[2] ? 1 : 0); + light_param_light_write_int32_t(s, buf, sizeof(buf), clip_plane.data[3] ? 1 : 0); s.write_char('\n'); } if (light->has_tone_curve) { - vec3& tone_curve = light->tone_curve; + light_tone_curve& tone_curve = light->tone_curve; s.write("tonecurve", 10); - light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.x); - light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.y); - light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.z); + light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.start_point); + light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.end_point); + light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.coefficient); s.write_char('\n'); } diff --git a/src/KKdLib/light_param/light.hpp b/src/KKdLib/light_param/light.hpp index 2676ecb1..208e90b8 100644 --- a/src/KKdLib/light_param/light.hpp +++ b/src/KKdLib/light_param/light.hpp @@ -32,6 +32,22 @@ enum light_type { LIGHT_SPOT = 0x03, }; +struct light_attenuation { + float_t constant; + float_t linear; + float_t quadratic; +}; + +struct light_clip_plane { + bool data[4]; +}; + +struct light_tone_curve { + float_t start_point; + float_t end_point; + float_t coefficient; +}; + struct light_param_light_data { bool has_type; light_type type; @@ -50,11 +66,11 @@ struct light_param_light_data { vec3 spot_direction; float_t spot_exponent; float_t spot_cutoff; - vec3 attenuation; + light_attenuation attenuation; bool has_clip_plane; - bool clip_plane[4]; + light_clip_plane clip_plane; bool has_tone_curve; - vec3 tone_curve; + light_tone_curve tone_curve; light_param_light_data(); ~light_param_light_data(); diff --git a/src/KKdLib/light_param/wind.cpp b/src/KKdLib/light_param/wind.cpp index e027beb3..2e1f55fa 100644 --- a/src/KKdLib/light_param/wind.cpp +++ b/src/KKdLib/light_param/wind.cpp @@ -4,8 +4,9 @@ */ #include "wind.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../str_utils.hpp" static void light_param_wind_read_inner(light_param_wind* wind, stream& s); @@ -26,27 +27,27 @@ light_param_wind::~light_param_wind() { void light_param_wind::read(const char* path) { char* path_txt = str_utils_add(path, ".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, "rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_wind_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_wind::read(const wchar_t* path) { wchar_t* path_txt = str_utils_add(path, L".txt"); if (path_check_file_exists(path_txt)) { - stream s; + file_stream s; s.open(path_txt, L"rb"); - if (s.io.stream) + if (s.check_not_null()) light_param_wind_read_inner(this, s); } - free(path_txt); + free_def(path_txt); } void light_param_wind::read(const void* data, size_t size) { - stream s; + memory_stream s; s.open(data, size); light_param_wind_read_inner(this, s); } @@ -56,11 +57,11 @@ void light_param_wind::write(const char* path) { return; char* path_txt = str_utils_add(path, ".txt"); - stream s; + file_stream s; s.open(path_txt, "wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_wind_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_wind::write(const wchar_t* path) { @@ -68,18 +69,18 @@ void light_param_wind::write(const wchar_t* path) { return; wchar_t* path_txt = str_utils_add(path, L".txt"); - stream s; + file_stream s; s.open(path_txt, L"wb"); - if (s.io.stream) + if (s.check_not_null()) light_param_wind_write_inner(this, s); - free(path_txt); + free_def(path_txt); } void light_param_wind::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); light_param_wind_write_inner(this, s); s.copy(data, size); @@ -156,12 +157,12 @@ static void light_param_wind_read_inner(light_param_wind* wind, stream& s) { } } - free(data); + free_def(data); wind->ready = true; return; End: - free(data); + free_def(data); } static void light_param_wind_write_inner(light_param_wind* wind, stream& s) { diff --git a/src/KKdLib/mat.cpp b/src/KKdLib/mat.cpp index 62abe618..3c5c6bed 100644 --- a/src/KKdLib/mat.cpp +++ b/src/KKdLib/mat.cpp @@ -655,7 +655,7 @@ inline void mat3_from_quat(const quat* quat, mat3* mat) { y = quat->y; z = quat->z; w = quat->w; - vec4_length_squared(*quat, len); + len = quat::length_squared(*quat); len = len > 0.0f ? 2.0f / len : 0.0f; xx = x * x * len; xy = x * y * len; @@ -719,9 +719,9 @@ inline void mat3_get_rotation(const mat3* x, vec3* z) { } inline void mat3_get_scale(const mat3* x, vec3* z) { - vec3_length(x->row0, z->x); - vec3_length(x->row1, z->y); - vec3_length(x->row2, z->z); + z->x = vec3::length(x->row0); + z->y = vec3::length(x->row1); + z->z = vec3::length(x->row2); } inline float_t mat3_get_max_scale(const mat3* x) { @@ -730,13 +730,13 @@ inline float_t mat3_get_max_scale(const mat3* x) { float_t length; float_t max = 0.0f; - vec3_length(mat.row0, length); + length = vec3::length(mat.row0); if (max < length) max = length; - vec3_length(mat.row1, length); + length = vec3::length(mat.row1); if (max < length) max = length; - vec3_length(mat.row2, length); + length = vec3::length(mat.row2); if (max < length) max = length; return max; @@ -1030,12 +1030,12 @@ inline void mat4_inverse_normalized(const mat4* x, mat4* z) { mat3 yt; mat3_from_mat4(x, &yt); vec3 row3; - vec3_dot(*(vec3*)&x->row0, *(vec3*)&x->row3, row3.x); - vec3_dot(*(vec3*)&x->row1, *(vec3*)&x->row3, row3.y); - vec3_dot(*(vec3*)&x->row2, *(vec3*)&x->row3, row3.z); + row3.x = vec3::dot(*(vec3*)&x->row0, *(vec3*)&x->row3); + row3.y = vec3::dot(*(vec3*)&x->row1, *(vec3*)&x->row3); + row3.z = vec3::dot(*(vec3*)&x->row2, *(vec3*)&x->row3); mat3_transpose(&yt, &yt); mat4_from_mat3(&yt, z); - vec3_negate(row3, *(vec3*)&z->row3); + *(vec3*)&z->row3 = -row3; z->row0.w = 0.0f; z->row1.w = 0.0f; z->row2.w = 0.0f; @@ -1686,7 +1686,7 @@ inline void mat4_from_quat(const quat* quat, mat4* mat) { y = quat->y; z = quat->z; w = quat->w; - vec4_length_squared(*quat, len); + len = quat::length_squared(*quat); len = len > 0.0f ? 2.0f / len : 0.0f; xx = x * x * len; xy = x * y * len; @@ -1713,12 +1713,9 @@ inline void mat4_from_quat(const quat* quat, mat4* mat) { } float_t vec3_angle_between_two_vectors(const vec3* x, const vec3* y) { - vec3 z_t; - vec3_cross(*x, *y, z_t); - float_t v2; - vec3_length(z_t, v2); - float_t v3; - vec3_dot(*x, *y, v3); + vec3 z_t = vec3::cross(*x, *y); + float_t v2 = vec3::length(z_t); + float_t v3 = vec3::dot(*x, *y); return fabsf(atan2f(v2, v3)); } @@ -1727,19 +1724,15 @@ void mat4_from_two_vectors(const vec3* x, const vec3* y, mat4* mat) { if (x->x == y->x && y->y == x->y && y->z == x->z) return; - float_t v5; - vec3_dot(*x, *y, v5); - if (fabsf(1.0f - v5) <= 0.000001f) + if (fabsf(1.0f - vec3::dot(*x, *y)) <= 0.000001f) return; - vec3 axis; - vec3_cross(*x, *y, axis); - float_t axis_length; - vec3_length(axis, axis_length); + vec3 axis = vec3::cross(*x, *y); + float_t axis_length = vec3::length(axis); if (axis_length > 0.000001f) { float_t angle = vec3_angle_between_two_vectors(x, y); if (axis_length != 0.0) - vec3_mult_scalar(axis, 1.0f / axis_length, axis); + axis *= 1.0f / axis_length; mat4_from_axis_angle(&axis, angle, mat); } } @@ -1756,18 +1749,18 @@ inline void mat4_from_axis_angle(const vec3* axis, float_t angle, mat4* mat) { angle_cos = cosf(angle); angle_cos_1 = 1.0f - angle_cos; - vec3_normalize(*axis, _axis); + _axis = vec3::normalize(*axis); - vec3_mult_scalar(_axis, angle_sin, _axis_sin); - vec3_mult_scalar(_axis, _axis.x * angle_cos_1, temp); + _axis_sin = _axis * angle_sin; + temp = _axis * (_axis.x * angle_cos_1); mat->row0.x = temp.x + angle_cos; mat->row1.x = temp.y - _axis_sin.z; mat->row2.x = temp.z + _axis_sin.y; - vec3_mult_scalar(_axis, _axis.y * angle_cos_1, temp); + temp = _axis * (_axis.y * angle_cos_1); mat->row0.y = temp.x + _axis_sin.z; mat->row1.y = temp.y + angle_cos; mat->row2.y = temp.z - _axis_sin.x; - vec3_mult_scalar(_axis, _axis.z * angle_cos_1, temp); + temp = _axis * (_axis.z * angle_cos_1); mat->row0.z = temp.x - _axis_sin.y; mat->row1.z = temp.y + _axis_sin.x; mat->row2.z = temp.z + angle_cos; @@ -1837,9 +1830,9 @@ inline void mat4_get_rotation(const mat4* x, vec3* z) { } inline void mat4_get_scale(const mat4* x, vec3* z) { - vec4_length(x->row0, z->x); - vec4_length(x->row1, z->y); - vec4_length(x->row2, z->z); + z->x = vec4::length(x->row0); + z->y = vec4::length(x->row1); + z->z = vec4::length(x->row2); } inline void mat4_get_translation(const mat4* x, vec3* z) { @@ -1851,12 +1844,12 @@ inline void mat4_set_translation(mat4* x, vec3* z) { } inline void mat4_blend(const mat4* x, const mat4* y, mat4* z, float_t blend) { + quat q0; quat q1; quat q2; - quat q3; quat_from_mat3(x->row0.x, x->row1.x, x->row2.x, x->row0.y, - x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q1); + x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q0); quat_from_mat3(y->row0.x, y->row1.x, y->row2.x, y->row0.y, y->row1.y, y->row2.y, y->row0.z, y->row1.z, y->row2.z, &q1); @@ -1866,10 +1859,10 @@ inline void mat4_blend(const mat4* x, const mat4* y, mat4* z, float_t blend) { mat4_get_translation(x, &t1); mat4_get_translation(y, &t2); - quat_slerp(&q3, &q1, &q2, blend); - vec3_lerp_scalar(t1, t2, t3, blend); + q2 = quat::slerp(q0, q1, blend); + t3 = vec3::lerp(t1, t2, blend); - mat4_from_quat(&q3, z); + mat4_from_quat(&q2, z); mat4_set_translation(z, &t3); } @@ -1882,20 +1875,18 @@ inline void mat4_blend_rotation(const mat4* x, const mat4* y, mat4* z, float_t b x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q1); quat_from_mat3(y->row0.x, y->row1.x, y->row2.x, y->row0.y, y->row1.y, y->row2.y, y->row0.z, y->row1.z, y->row2.z, &q1); - quat_slerp(&q0, &q1, &q2, blend); + q2 = quat::slerp(q0, q1, blend); mat4_from_quat(&q2, z); } void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t blend) { vec3 m0; vec3 m1; - vec3_lerp_scalar(*(vec3*)&src0->row0, *(vec3*)&src1->row0, m0, blend); - vec3_lerp_scalar(*(vec3*)&src0->row1, *(vec3*)&src1->row1, m1, blend); + m0 = vec3::lerp(*(vec3*)&src0->row0, *(vec3*)&src1->row0, blend); + m1 = vec3::lerp(*(vec3*)&src0->row1, *(vec3*)&src1->row1, blend); - float_t m0_len_sq; - float_t m1_len_sq; - vec3_length_squared(m0, m0_len_sq); - vec3_length_squared(m1, m1_len_sq); + float_t m0_len_sq = vec3::length_squared(m0); + float_t m1_len_sq = vec3::length_squared(m1); if (m0_len_sq <= 0.000001f || m1_len_sq <= 0.000001f) { *dst = *src1; @@ -1903,12 +1894,12 @@ void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t b } vec3 m2; - vec3_cross(m0, m1, m2); - vec3_cross(m2, m0, m1); + m2 = vec3::cross(m0, m1); + m1 = vec3::cross(m2, m0); float_t m2_len_sq; - vec3_length_squared(m1, m1_len_sq); - vec3_length_squared(m2, m2_len_sq); + m1_len_sq = vec3::length_squared(m1); + m2_len_sq = vec3::length_squared(m2); if (m2_len_sq <= 0.000001f || m1_len_sq <= 0.000001) { *dst = *src1; return; @@ -1916,15 +1907,15 @@ void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t b float_t m0_len = sqrtf(m0_len_sq); if (m0_len != 0.0f) - vec3_div_scalar(m0, 1.0f / m0_len, m0); + m0 *= 1.0f / m0_len; float_t m1_len = sqrtf(m1_len_sq); if (m1_len != 0.0f) - vec3_div_scalar(m1, 1.0f / m1_len, m1); + m1 *= 1.0f / m1_len; float_t m2_len = sqrtf(m2_len_sq); if (m2_len != 0.0f) - vec3_div_scalar(m2, 1.0f / m2_len, m2); + m2 *= 1.0f / m2_len; *dst = mat4_identity; *(vec3*)&dst->row0 = m0; @@ -1938,13 +1929,13 @@ inline float_t mat4_get_max_scale(const mat4* x) { float_t length; float_t max = 0.0f; - vec3_length(*(vec3*)&mat.row0, length); + length = vec3::length(*(vec3*)&mat.row0); if (max < length) max = length; - vec3_length(*(vec3*)&mat.row1, length); + length = vec3::length(*(vec3*)&mat.row1); if (max < length) max = length; - vec3_length(*(vec3*)&mat.row2, length); + length = vec3::length(*(vec3*)&mat.row2); if (max < length) max = length; return max; @@ -2010,39 +2001,32 @@ inline void mat4_persp(double_t fov_y, double_t aspect, double_t z_near, double_ inline void mat4_look_at(const vec3* eye, const vec3* target, const vec3* up, mat4* mat) { vec3 x_axis, y_axis, z_axis; - float_t t; vec3 xyz; - vec3_sub(*eye, *target, z_axis); - vec3_normalize(z_axis, z_axis); + z_axis = vec3::normalize(*eye - *target); - vec3_cross(*up, z_axis, x_axis); - vec3_normalize(x_axis, x_axis); - vec3_length(x_axis, t); - if (t == 0.0f) + x_axis = vec3::normalize(vec3::cross(*up, z_axis)); + if (vec3::length(x_axis) == 0.0f) x_axis = { 1.0f, 0.0f, 0.0f }; - vec3_cross(z_axis, x_axis, y_axis); - vec3_normalize(y_axis, y_axis); - vec3_dot(x_axis, *eye, xyz.x); - vec3_dot(y_axis, *eye, xyz.y); - vec3_dot(z_axis, *eye, xyz.z); + y_axis = vec3::normalize(vec3::cross(z_axis, x_axis)); + + xyz.x = vec3::dot(x_axis, *eye); + xyz.y = vec3::dot(y_axis, *eye); + xyz.z = vec3::dot(z_axis, *eye); mat->row0 = { x_axis.x, y_axis.x, z_axis.x, 0.0f }; mat->row1 = { x_axis.y, y_axis.y, z_axis.y, 0.0f }; mat->row2 = { x_axis.z, y_axis.z, z_axis.z, 0.0f }; - vec3_negate(xyz, xyz); - *(vec3*)&mat->row3 = xyz; + *(vec3*)&mat->row3 = -xyz; mat->row3.w = 1.0f; } inline void mat4_look_at(const vec3* eye, const vec3* target, mat4* mat) { vec3 up = { 0.0f, 1.0f, 0.0f }; vec3 dir; - float_t length; - vec3_sub(*target, *eye, dir); - vec3_length_squared(dir, length); - if (length <= 0.000001f) { + dir = *target - *eye; + if (vec3::length_squared(dir) <= 0.000001f) { up.x = 0.0f; up.y = 0.0f; if (dir.z < 0.0f) diff --git a/src/KKdLib/mot.cpp b/src/KKdLib/mot.cpp index 8366ace7..400a860a 100644 --- a/src/KKdLib/mot.cpp +++ b/src/KKdLib/mot.cpp @@ -6,7 +6,7 @@ #include "mot.hpp" #include "f2/struct.hpp" #include "io/path.hpp" -#include "io/stream.hpp" +#include "io/memory_stream.hpp" #include "interpolation.hpp" #include "half_t.hpp" #include "hash.hpp" @@ -60,7 +60,7 @@ mot_data::~mot_data() { } -mot_set::mot_set() : ready(), modern(), is_x() { +mot_set::mot_set() : ready(), modern(), big_endian(), is_x() { } @@ -72,7 +72,7 @@ void mot_set::pack_file(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); if (!modern) mot_classic_write_inner(this, s); @@ -85,7 +85,7 @@ void mot_set::unpack_file(const void* data, size_t size, bool modern) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); if (!modern) mot_classic_read_inner(this, s); @@ -93,6 +93,228 @@ void mot_set::unpack_file(const void* data, size_t size, bool modern) { mot_modern_read_inner(this, s); } +inline static float_t interpolate_mot_value(float_t p1, float_t p2, + float_t t1, float_t t2, float_t f1, float_t f2, float_t f) { + float_t df = f - f1; + float_t t = df / (f2 - f1); + float_t t_1 = t - 1.0f; + return (t_1 * t1 + t * t2) * t_1 * df + (t * 2.0f - 3.0f) * (t * t) * (p1 - p2) + p1; +} + +inline static void interpolate_mot_reverse_value(float_t* arr, size_t length, + float_t* t1, float_t* t2, size_t f1, size_t f2, size_t f) { + *t2 = 0.0f; + + if (!arr || length < 2 || f - f1 + 1 >= length || f < 1 || f < f1 || f + 2 > f2) + return; + + float_t df_1 = (float_t)(f - f1); + float_t df_2 = (float_t)(f - f1 + 1); + float_t _t1 = df_1 / (float_t)(f2 - f1); + float_t _t2 = df_2 / (float_t)(f2 - f1); + float_t t1_1 = _t1 - 1.0f; + float_t t2_1 = _t2 - 1.0f; + + float_t t1_t2_1 = arr[f] - arr[f1] - (_t1 * 2.0f - 3.0f) * (_t1 * _t1) * (arr[f1] - arr[f2]); + float_t t1_t2_2 = arr[f + 1] - arr[f1] - (_t2 * 2.0f - 3.0f) * (_t2 * _t2) * (arr[f1] - arr[f2]); + t1_t2_1 /= df_1 * t1_1; + t1_t2_2 /= df_2 * t2_1; + + *t1 = (t1_t2_1 * _t2 - t1_t2_2 * _t1) / (_t1 - _t2); + *t2 = (-t1_t2_1 * t2_1 + t1_t2_2 * t1_1) / (_t1 - _t2); +} + +inline static void mot_set_add_key(uint16_t frame, float_t v, float_t t, + std::vector& frames, std::vector& values) { + frames.push_back(frame); + values.push_back(v); + values.push_back(t); +} + +inline static float_t mot_set_add_key(bool has_error, float_t* a, int32_t frame, + size_t i, float_t t1, float_t t2, float_t t2_old, + std::vector& frames, std::vector& values) { + if (has_error) { + float_t _t2 = t2_old; + for (size_t j = 0; j < i; j++) { + mot_set_add_key((uint16_t)(frame + j), a[j], _t2, frames, values); + _t2 = 0.0f; + mot_set_add_key((uint16_t)(frame + j), a[j], 0.0f, frames, values); + } + return 0.0f; + } + else { + mot_set_add_key((uint16_t)frame, a[0], t2_old, frames, values); + if (t2_old == 0.0f) + mot_set_add_key((uint16_t)frame, a[0], t2_old, frames, values); + if (t1 != t2_old) { + mot_set_add_key((uint16_t)frame, a[0], t1, frames, values); + if (t1 == 0.0f) + mot_set_add_key((uint16_t)frame, a[0], t1, frames, values); + } + return t2; + } +} + +mot_key_set_type mot_set::fit_keys_into_curve(std::vector& values_src, + std::vector& frames, std::vector& values) { + size_t count = values_src.size(); + if (!count) + return MOT_KEY_SET_NONE; + else if (count == 1) { + if (values_src[0] != 0.0f) { + values.push_back(values_src[0]); + return MOT_KEY_SET_STATIC; + } + else + return MOT_KEY_SET_NONE; + } + else { + uint32_t val = *(uint32_t*)&values_src.data()[0]; + uint32_t* arr = (uint32_t*)&values_src.data()[1]; + for (size_t i = count - 1; i; i--) + if (val != *arr++) + break; + + if (arr == (uint32_t*)(values_src.data() + count)) + if (values_src[0] != 0.0f) { + values.push_back(values_src[0]); + return MOT_KEY_SET_STATIC; + } + else + return MOT_KEY_SET_NONE; + } + + int32_t start_time = 0; + int32_t end_time = (int32_t)(count - 1); + + float_t* arr = values_src.data(); + + const float_t reverse_bias = 0.0001f; + const int32_t reverse_min_count = 4; + + float_t* a = arr; + size_t left_count = count; + int32_t frame = start_time; + int32_t prev_frame = start_time; + float_t t2_old = 0.0f; + while (left_count > 0) { + if (left_count < reverse_min_count) { + if (left_count > 1) + t2_old = mot_set_add_key(true, a, frame, left_count - 1, 0.0f, 0.0f, t2_old, frames, values); + break; + } + + size_t i = 0; + size_t i_prev = 0; + float_t t1 = 0.0f; + float_t t2 = 0.0f; + float_t t1_prev = 0.0f; + float_t t2_prev = 0.0f; + bool has_prev_succeded = false; + bool has_error = false; + bool has_prev_error = false; + + int32_t c = 0; + for (i = reverse_min_count - 1, i_prev = i; i < left_count; i++) { + double_t tt1 = 0.0; + double_t tt2 = 0.0; + for (size_t j = 1; j < i; j++) { + float_t _t1 = 0.0f; + float_t _t2 = 0.0f; + interpolate_mot_reverse_value(a, left_count, &_t1, &_t2, 0, i, j); + tt1 += _t1; + tt2 += _t2; + } + t1 = (float_t)(tt1 / (double_t)(i - 2)); + t2 = (float_t)(tt2 / (double_t)(i - 2)); + + has_error = false; + for (size_t j = 1; j < i - 1; j++) { + float_t val = interpolate_mot_value(a[0], a[i], t1, t2, 0.0f, (float_t)i, (float_t)j); + if (fabsf(val - a[j]) > reverse_bias) { + has_error = true; + break; + } + } + + if (fabsf(t1) > 0.5f || fabsf(t2) > 0.5f) + has_error = true; + + if (!has_error) { + i_prev = i; + t1_prev = t1; + t2_prev = t2; + has_prev_succeded = true; + has_prev_error = has_error; + if (i < left_count) + continue; + } + + if (has_prev_succeded) { + i = i_prev; + t1 = t1_prev; + t2 = t2_prev; + has_error = has_prev_error; + } + + if (!has_error) + c = (int32_t)i; + else + c = 1; + + t2_old = mot_set_add_key(has_error, a, frame, c, t1, t2, t2_old, frames, values); + has_prev_succeded = false; + break; + + if (!has_error) { + i_prev = i; + t1_prev = t1; + t2_prev = t2; + has_prev_succeded = true; + has_prev_error = has_error; + if (i < left_count) + continue; + } + break; + } + + if (has_prev_succeded) { + t2_old = mot_set_add_key(has_error, a, frame, c, t1_prev, t2_prev, t2_old, frames, values); + c = (int32_t)i; + } + + prev_frame = frame; + frame += c; + a += c; + left_count -= c; + } + + mot_set_add_key((uint16_t)(start_time + (count - 1)), arr[count - 1], t2_old, frames, values); + if (t2_old != 0.0f) + mot_set_add_key((uint16_t)(start_time + (count - 1)), arr[count - 1], 0.0f, frames, values); + + + count = values.size() / 2; + arr = values.data(); + for (size_t i = count; i; i--) + if (*arr++ != 0.0f) + break; + + if (arr != values.data() + count) + return MOT_KEY_SET_HERMITE_TANGENT; + + float_t* arr_src = values.data(); + float_t* arr_dst = values.data(); + for (size_t i = count; i; i--) { + *arr_dst = *arr_src; + arr_src++; + arr_dst += 2; + } + values.resize(count); + return MOT_KEY_SET_HERMITE; +} + static void mot_classic_read_inner(mot_set* ms, stream& s) { size_t count = 0; while (s.read_uint64_t() != 0) { @@ -103,6 +325,7 @@ static void mot_classic_read_inner(mot_set* ms, stream& s) { if (count == 0) { ms->ready = false; ms->modern = false; + ms->big_endian = false; ms->is_x = false; } @@ -183,10 +406,11 @@ static void mot_classic_read_inner(mot_set* ms, stream& s) { } } } - free(mh); + free_def(mh); ms->ready = true; ms->modern = false; + ms->big_endian = false; ms->is_x = false; } @@ -262,7 +486,7 @@ static void mot_classic_write_inner(mot_set* ms, stream& s) { s.write_uint32_t(mh[i].key_set_offset); s.write_uint32_t(mh[i].bone_info_offset); } - free(mh); + free_def(mh); } static void mot_modern_read_inner(mot_set* ms, stream& s) { @@ -271,13 +495,16 @@ static void mot_modern_read_inner(mot_set* ms, stream& s) { if (st.header.signature != reverse_endianness_uint32_t('MOTC') || !st.data.size()) { ms->ready = false; ms->modern = false; + ms->big_endian = false; ms->is_x = false; return; } - stream s_motc; + bool big_endian = st.header.use_big_endian; + + memory_stream s_motc; s_motc.open(st.data); - s_motc.is_big_endian = st.header.use_big_endian; + s_motc.big_endian = big_endian; s_motc.set_position(0x0C, SEEK_SET); bool is_x = s_motc.read_uint32_t_reverse_endianness() == 0; @@ -394,15 +621,18 @@ static void mot_modern_read_inner(mot_set* ms, stream& s) { ms->ready = true; ms->modern = true; + ms->big_endian = big_endian; ms->is_x = is_x; } static void mot_modern_write_inner(mot_set* ms, stream& s) { - stream s_motc; - s_motc.open(); - + bool big_endian = ms->big_endian; bool is_x = ms->is_x; + memory_stream s_motc; + s_motc.open(); + s_motc.big_endian = big_endian; + uint32_t o; enrs e; enrs_entry ee; @@ -535,8 +765,8 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { mh.hash = hash_string_murmurhash(m->name); mh.key_set_count_offset = s_motc.get_position(); - s_motc.write_uint16_t(m->info); - s_motc.write_uint16_t(m->frame_count); + s_motc.write_uint16_t_reverse_endianness(m->info); + s_motc.write_uint16_t_reverse_endianness(m->frame_count); mh.key_set_types_offset = s_motc.get_position(); uint16_t key_set_type_buf = 0; @@ -548,13 +778,13 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { key_set_type_buf |= ((uint16_t)type & 0x03) << (j % 8 * 2); if (j % 8 == 7) { - s_motc.write_uint16_t(key_set_type_buf); + s_motc.write_uint16_t_reverse_endianness(key_set_type_buf); key_set_type_buf = 0; } } if (m->key_set_count % 8 != 0) - s_motc.write_uint16_t(key_set_type_buf); + s_motc.write_uint16_t_reverse_endianness(key_set_type_buf); s_motc.align_write(0x04); mh.key_set_offset = s_motc.get_position(); @@ -562,34 +792,34 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { mot_key_set_data* mks = &m->key_set[j]; if (mks->type == MOT_KEY_SET_STATIC) { if (mks->values[0] != 0.0f) - s.write_float_t(mks->values[0]); + s.write_float_t_reverse_endianness(mks->values[0]); } else if (mks->type != MOT_KEY_SET_NONE) { bool has_tangents = mks->type != MOT_KEY_SET_HERMITE; uint16_t keys_count = mks->keys_count; mot_key_set_data_type data_type = mks->data_type; - s_motc.write_uint16_t(keys_count); - s_motc.write_uint16_t((uint16_t)data_type); + s_motc.write_uint16_t_reverse_endianness(keys_count); + s_motc.write_uint16_t_reverse_endianness((uint16_t)data_type); uint8_t step = has_tangents ? 2 : 1; if (has_tangents) { float_t* values = &mks->values[1]; for (int32_t k = 0; k < keys_count; k++, values += step) - s_motc.write_float_t(*values); + s_motc.write_float_t_reverse_endianness(*values); } float_t* values = mks->values.data(); if (data_type == MOT_KEY_SET_DATA_F16) for (int32_t k = 0; k < keys_count; k++, values += step) - s_motc.write_half_t(float_to_half(*values)); + s_motc.write_half_t_reverse_endianness(float_to_half(*values)); else for (int32_t k = 0; k < keys_count; k++, values += step) - s_motc.write_float_t(*values); + s_motc.write_float_t_reverse_endianness(*values); s_motc.align_write(0x04); int16_t* frames = (int16_t*)mks->frames.data(); for (int32_t k = 0; k < keys_count; k++) - s_motc.write_int16_t(*frames++); + s_motc.write_int16_t_reverse_endianness(*frames++); s_motc.align_write(0x04); } } @@ -607,7 +837,7 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { mh.bone_hash_offset = s_motc.get_position(); for (int32_t j = 0; j < m->bone_info_count; j++) - s_motc.write_uint64_t(hash_string_murmurhash(m->bone_info[j].name)); + s_motc.write_uint64_t_reverse_endianness(hash_string_murmurhash(m->bone_info[j].name)); s_motc.align_write(0x10); mh.name_offset = s_motc.get_position(); @@ -627,36 +857,36 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { else for (int32_t j = 0; j < m->bone_info_count; j++) s_motc.write_offset_x(bone_info_offsets[j]); - free(bone_info_offsets); + free_def(bone_info_offsets); s_motc.set_position(0x00, SEEK_SET); if (!is_x) { - s_motc.write_uint64_t((uint64_t)mh.hash); + s_motc.write_uint64_t_reverse_endianness((uint64_t)mh.hash); s_motc.write_offset_f2(mh.name_offset, 0x40); s_motc.write_offset_f2(mh.key_set_count_offset, 0x40); s_motc.write_offset_f2(mh.key_set_types_offset, 0x40); s_motc.write_offset_f2(mh.key_set_offset, 0x40); s_motc.write_offset_f2(mh.bone_info_offset, 0x40); s_motc.write_offset_f2(mh.bone_hash_offset, 0x40); - s_motc.write_int32_t(mh.bone_info_count); + s_motc.write_int32_t_reverse_endianness(mh.bone_info_count); } else { - s_motc.write_uint64_t((uint64_t)mh.hash); + s_motc.write_uint64_t_reverse_endianness((uint64_t)mh.hash); s_motc.write_offset_x(mh.name_offset); s_motc.write_offset_x(mh.key_set_count_offset); s_motc.write_offset_x(mh.key_set_types_offset); s_motc.write_offset_x(mh.key_set_offset); s_motc.write_offset_x(mh.bone_info_offset); s_motc.write_offset_x(mh.bone_hash_offset); - s_motc.write_int32_t(mh.bone_info_count); + s_motc.write_int32_t_reverse_endianness(mh.bone_info_count); } if (m->div_frames > 0) { - s_motc.write_uint16_t(m->div_frames); + s_motc.write_uint16_t_reverse_endianness(m->div_frames); s_motc.write_uint8_t(m->div_count); } else { - s_motc.write_uint16_t(0); + s_motc.write_uint16_t_reverse_endianness(0); s_motc.write_uint8_t(0); } @@ -673,7 +903,7 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { st.header.signature = reverse_endianness_uint32_t('MOTC'); st.header.length = 0x40; - st.header.use_big_endian = false; + st.header.use_big_endian = big_endian; st.header.use_section_size = true; st.header.murmurhash = murmurhash; st.header.inner_signature = 0xFF010008; diff --git a/src/KKdLib/mot.hpp b/src/KKdLib/mot.hpp index 494b9b80..b800c011 100644 --- a/src/KKdLib/mot.hpp +++ b/src/KKdLib/mot.hpp @@ -67,6 +67,7 @@ struct mot_data { struct mot_set { bool ready; bool modern; + bool big_endian; bool is_x; std::string name; @@ -77,4 +78,7 @@ struct mot_set { void pack_file(void** data, size_t* size); void unpack_file(const void* data, size_t size, bool modern); + + static mot_key_set_type fit_keys_into_curve(std::vector& values_src, + std::vector& frames, std::vector& values); }; diff --git a/src/KKdLib/msgpack.cpp b/src/KKdLib/msgpack.cpp index 2bbacee8..0ec2b063 100644 --- a/src/KKdLib/msgpack.cpp +++ b/src/KKdLib/msgpack.cpp @@ -4,407 +4,12 @@ */ #include "msgpack.hpp" -#include "str_utils.hpp" - -#define MSGPACK_ALLOCATE(a, b) \ -if (MSGPACK_CHECK(a)) \ - (b).data.ptr = new (a); -#define MSGPACK_ALLOCATE_PTR(a, b) \ -if (MSGPACK_CHECK(a)) \ - (b)->data.ptr = new (a); - -msgpack::msgpack() : data() { - type = MSGPACK_NULL; -} - -msgpack::msgpack(const msgpack& m) : type(), data() { - if (this == &m) - return; - - switch (m.type) { - case MSGPACK_BOOL: { - MSGPACK_ALLOCATE_PTR(double_t, this); - bool* s_ptr = MSGPACK_SELECT(bool, m); - bool* d_ptr = MSGPACK_SELECT_PTR(bool, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT8: { - MSGPACK_ALLOCATE_PTR(int8_t, this); - int8_t* s_ptr = MSGPACK_SELECT(int8_t, m); - int8_t* d_ptr = MSGPACK_SELECT_PTR(int8_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT8: { - MSGPACK_ALLOCATE_PTR(uint8_t, this); - uint8_t* s_ptr = MSGPACK_SELECT(uint8_t, m); - uint8_t* d_ptr = MSGPACK_SELECT_PTR(uint8_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT16: { - MSGPACK_ALLOCATE_PTR(int16_t, this); - int16_t* s_ptr = MSGPACK_SELECT(int16_t, m); - int16_t* d_ptr = MSGPACK_SELECT_PTR(int16_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT16: { - MSGPACK_ALLOCATE_PTR(uint16_t, this); - uint16_t* s_ptr = MSGPACK_SELECT(uint16_t, m); - uint16_t* d_ptr = MSGPACK_SELECT_PTR(uint16_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT32: { - MSGPACK_ALLOCATE_PTR(int32_t, this); - int32_t* s_ptr = MSGPACK_SELECT(int32_t, m); - int32_t* d_ptr = MSGPACK_SELECT_PTR(int32_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT32: { - MSGPACK_ALLOCATE_PTR(uint32_t, this); - uint32_t* s_ptr = MSGPACK_SELECT(uint32_t, m); - uint32_t* d_ptr = MSGPACK_SELECT_PTR(uint32_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT64: { - MSGPACK_ALLOCATE_PTR(int64_t, this); - int64_t* s_ptr = MSGPACK_SELECT(int64_t, m); - int64_t* d_ptr = MSGPACK_SELECT_PTR(int64_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT64: { - MSGPACK_ALLOCATE_PTR(uint64_t, this); - uint64_t* s_ptr = MSGPACK_SELECT(uint64_t, m); - uint64_t* d_ptr = MSGPACK_SELECT_PTR(uint64_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_FLOAT: { - MSGPACK_ALLOCATE_PTR(float_t, this); - float_t* s_ptr = MSGPACK_SELECT(float_t, m); - float_t* d_ptr = MSGPACK_SELECT_PTR(float_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_DOUBLE: { - MSGPACK_ALLOCATE_PTR(double_t, this); - double_t* s_ptr = MSGPACK_SELECT(double_t, m); - double_t* d_ptr = MSGPACK_SELECT_PTR(double_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_STRING: { - MSGPACK_ALLOCATE_PTR(std::string, this); - std::string* s_ptr = MSGPACK_SELECT(std::string, m); - std::string* d_ptr = MSGPACK_SELECT_PTR(std::string, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_ARRAY: - case MSGPACK_MAP: { - MSGPACK_ALLOCATE_PTR(msgpack_array, this); - msgpack_array* s_ptr = MSGPACK_SELECT(msgpack_array, m); - msgpack_array* d_ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - *d_ptr = *s_ptr; - } break; - } - type = m.type; - name = m.name; -} - -msgpack::msgpack(const char* name, bool array, size_t length) : data() { - type = array ? MSGPACK_ARRAY : MSGPACK_MAP; - MSGPACK_ALLOCATE_PTR(msgpack_array, this); - if (name) - this->name = std::string(name); - - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - *ptr = {}; - ptr->resize(length); -} - -msgpack::msgpack(const char* name, bool array, msgpack_array& val) : data() { - type = array ? MSGPACK_ARRAY : MSGPACK_MAP; - MSGPACK_ALLOCATE_PTR(msgpack_array, this); - if (name) - this->name = std::string(name); - - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - *ptr = val; -} - -msgpack::msgpack(const char* name) : data() { - type = MSGPACK_NULL; - if (name) - this->name = std::string(name); -} - -msgpack::msgpack(const char* name, bool val) : data() { - type = MSGPACK_BOOL; - MSGPACK_ALLOCATE_PTR(bool, this); - if (name) - this->name = std::string(name); - - bool* ptr = MSGPACK_SELECT_PTR(bool, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, int8_t val) : data() { - type = MSGPACK_INT8; - MSGPACK_ALLOCATE_PTR(int8_t, this); - if (name) - this->name = std::string(name); - - int8_t* ptr = MSGPACK_SELECT_PTR(int8_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, uint8_t val) : data() { - type = MSGPACK_UINT8; - MSGPACK_ALLOCATE_PTR(uint8_t, this); - if (name) - this->name = std::string(name); - - uint8_t* ptr = MSGPACK_SELECT_PTR(uint8_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, int16_t val) : data() { - type = MSGPACK_INT16; - MSGPACK_ALLOCATE_PTR(int16_t, this); - if (name) - this->name = std::string(name); - - int16_t* ptr = MSGPACK_SELECT_PTR(int16_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, uint16_t val) : data() { - type = MSGPACK_UINT16; - MSGPACK_ALLOCATE_PTR(uint16_t, this); - if (name) - this->name = std::string(name); - - uint16_t* ptr = MSGPACK_SELECT_PTR(uint16_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, int32_t val) : data() { - type = MSGPACK_INT32; - MSGPACK_ALLOCATE_PTR(int32_t, this); - if (name) - this->name = std::string(name); - - int32_t* ptr = MSGPACK_SELECT_PTR(int32_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, uint32_t val) : data() { - type = MSGPACK_UINT32; - MSGPACK_ALLOCATE_PTR(uint32_t, this); - if (name) - this->name = std::string(name); - - uint32_t* ptr = MSGPACK_SELECT_PTR(uint32_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, int64_t val) : data() { - type = MSGPACK_INT64; - MSGPACK_ALLOCATE_PTR(int64_t, this); - if (name) - this->name = std::string(name); - - int64_t* ptr = MSGPACK_SELECT_PTR(int64_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, uint64_t val) : data() { - type = MSGPACK_UINT64; - MSGPACK_ALLOCATE_PTR(uint64_t, this); - if (name) - this->name = std::string(name); - - uint64_t* ptr = MSGPACK_SELECT_PTR(uint64_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, float_t val) : data() { - type = MSGPACK_FLOAT; - MSGPACK_ALLOCATE_PTR(float_t, this); - if (name) - this->name = std::string(name); - - float_t* ptr = MSGPACK_SELECT_PTR(float_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, double_t val) : data() { - type = MSGPACK_DOUBLE; - MSGPACK_ALLOCATE_PTR(double_t, this); - if (name) - this->name = std::string(name); - - double_t* ptr = MSGPACK_SELECT_PTR(double_t, this); - *ptr = val; -} - -msgpack::msgpack(const char* name, const char* val) : data() { - type = MSGPACK_STRING; - MSGPACK_ALLOCATE_PTR(std::string, this); - if (name) - this->name = std::string(name); - std::string* ptr = MSGPACK_SELECT_PTR(std::string, this); - *ptr = {}; - if (val) - *ptr = std::string(val); -} - -msgpack::msgpack(const char* name, const wchar_t* val) : data() { - type = MSGPACK_STRING; - MSGPACK_ALLOCATE_PTR(std::string, this); - if (name) - this->name = std::string(name); - std::string* ptr = MSGPACK_SELECT_PTR(std::string, this); - *ptr = {}; - if (val) - *ptr = utf16_to_utf8(val); -} - -msgpack::msgpack(const char* name, std::string& val) : data() { - type = MSGPACK_STRING; - MSGPACK_ALLOCATE_PTR(std::string, this); - if (name) - this->name = std::string(name); - std::string* ptr = MSGPACK_SELECT_PTR(std::string, this); - *ptr = {}; - if (val.size()) - *ptr = val; -} - -msgpack::msgpack(const char* name, std::wstring& val) : data() { - type = MSGPACK_STRING; - MSGPACK_ALLOCATE_PTR(std::string, this); - if (name) - this->name = std::string(name); - std::string* ptr = MSGPACK_SELECT_PTR(std::string, this); - *ptr = {}; - if (val.size()) - *ptr = utf16_to_utf8(val); -} - -msgpack::~msgpack() { - switch (type) { - case MSGPACK_BOOL: { - bool* ptr = MSGPACK_SELECT_PTR(bool, this); - if (MSGPACK_CHECK(bool)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_INT8: { - int8_t* ptr = MSGPACK_SELECT_PTR(int8_t, this); - if (MSGPACK_CHECK(int8_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_UINT8: { - uint8_t* ptr = MSGPACK_SELECT_PTR(uint8_t, this); - if (MSGPACK_CHECK(uint8_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_INT16: { - int16_t* ptr = MSGPACK_SELECT_PTR(int16_t, this); - if (MSGPACK_CHECK(int16_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_UINT16: { - uint16_t* ptr = MSGPACK_SELECT_PTR(uint16_t, this); - if (MSGPACK_CHECK(uint16_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_INT32: { - int32_t* ptr = MSGPACK_SELECT_PTR(int32_t, this); - if (MSGPACK_CHECK(int32_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_UINT32: { - uint32_t* ptr = MSGPACK_SELECT_PTR(uint32_t, this); - if (MSGPACK_CHECK(uint32_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_INT64: { - int64_t* ptr = MSGPACK_SELECT_PTR(int64_t, this); - if (MSGPACK_CHECK(int64_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_UINT64: { - uint64_t* ptr = MSGPACK_SELECT_PTR(uint64_t, this); - if (MSGPACK_CHECK(uint64_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_FLOAT: { - float_t* ptr = MSGPACK_SELECT_PTR(float_t, this); - if (MSGPACK_CHECK(float_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_DOUBLE: { - double_t* ptr = MSGPACK_SELECT_PTR(double_t, this); - if (MSGPACK_CHECK(double_t)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_STRING: { - std::string* ptr = MSGPACK_SELECT_PTR(std::string, this); - ptr->clear(); - ptr->shrink_to_fit(); - if (MSGPACK_CHECK(std::string)) { - delete ptr; - data.ptr = 0; - } - } break; - case MSGPACK_ARRAY: - case MSGPACK_MAP: { - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - ptr->clear(); - ptr->shrink_to_fit(); - if (MSGPACK_CHECK(msgpack_array)) { - delete ptr; - data.ptr = 0; - } - } break; - } -} - -bool msgpack::check_null() { - if (type == MSGPACK_ARRAY || type == MSGPACK_MAP) - return MSGPACK_SELECT_PTR(msgpack_array, this)->size() == 0; - return type == MSGPACK_NONE; -} - -bool msgpack::check_not_null() { - if (type == MSGPACK_ARRAY || type == MSGPACK_MAP) - return MSGPACK_SELECT_PTR(msgpack_array, this)->size() != 0; - return type != MSGPACK_NONE; -} msgpack* msgpack::get_by_index(size_t index) { if (type != MSGPACK_ARRAY) return 0; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); + msgpack_array* ptr = data.arr; if (index < ptr->size()) return &ptr->data()[index]; return 0; @@ -414,10 +19,9 @@ void msgpack::set_by_index(msgpack* m, size_t index) { if (type != MSGPACK_ARRAY) return; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); + msgpack_array* ptr = data.arr; if (index < ptr->size()) { msgpack& msg = ptr->data()[index]; - msg.~msgpack(); msg = *m; } } @@ -426,54 +30,77 @@ msgpack* msgpack::get_by_name(const char* name) { if (type != MSGPACK_MAP) return 0; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - for (msgpack& i : *ptr) - if (!i.name.compare(name)) - return &i; + msgpack_map* ptr = data.map; + for (msgpack_key_value& i : *ptr) + if (!i.first.compare(name)) + return &i.second; return 0; } -void msgpack::set_by_name(msgpack* m) { +void msgpack::set_by_name(const char* name, msgpack* m) { if (type != MSGPACK_MAP) return; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - for (msgpack& i : *ptr) - if (!i.name.compare(m->name)) { - i.~msgpack(); - i = *m; + msgpack_map* ptr = data.map; + for (msgpack_key_value& i : *ptr) + if (!i.first.compare(name)) { + i.second = *m; return; } - append(m); + append(name, m); } -void msgpack::append(msgpack* m) { +msgpack* msgpack::append(const char* name, msgpack* m) { if (type != MSGPACK_MAP) - return; + return 0; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - ptr->push_back(*m); - *m = {}; + msgpack* tm = get_by_name(name); + if (tm) { + *tm = *m; + m->clear(); + return tm; + } + else { + data.map->push_back({ name, *m }); + m->clear(); + return &data.map->back().second; + } } -void msgpack::append(msgpack& m) { +msgpack* msgpack::append(const char* name, msgpack& m) { if (type != MSGPACK_MAP) - return; + return 0; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - ptr->push_back(m); - m = {}; + msgpack* tm = get_by_name(name); + if (tm) { + *tm = m; + m.clear(); + return tm; + } + else { + data.map->push_back({ name, m }); + m.clear(); + return &data.map->back().second; + } } -void msgpack::append(msgpack&& m) { +msgpack* msgpack::append(const char* name, msgpack&& m) { if (type != MSGPACK_MAP) - return; + return 0; - msgpack_array* ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - ptr->push_back(m); - m = {}; + msgpack* tm = get_by_name(name); + if (tm) { + *tm = m; + m.clear(); + return tm; + } + else { + data.map->push_back({ name, m }); + m.clear(); + return &data.map->back().second; + } } msgpack* msgpack::read(const char* name) { @@ -483,13 +110,43 @@ msgpack* msgpack::read(const char* name) { return name ? get_by_name(name) : this; } +msgpack* msgpack::read(const char* name, msgpack_type type) { + if (!this) + return 0; + + msgpack* m = name ? get_by_name(name) : this; + if (m && m->type == type) + return m; + return 0; +} + +msgpack* msgpack::read_array(const char* name) { + if (!this) + return 0; + + msgpack* m = name ? get_by_name(name) : this; + if (m && m->type == MSGPACK_ARRAY) + return m; + return 0; +} + +msgpack* msgpack::read_map(const char* name) { + if (!this) + return 0; + + msgpack* m = name ? get_by_name(name) : this; + if (m && m->type == MSGPACK_MAP) + return m; + return 0; +} + bool msgpack::read_bool(const char* name) { if (!this) return 0; msgpack* m = name ? get_by_name(name) : this; if (m && m->type == MSGPACK_BOOL) - return *MSGPACK_SELECT_PTR(bool, m); + return m->data.b; return 0; } @@ -502,9 +159,9 @@ int8_t msgpack::read_int8_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return *MSGPACK_SELECT_PTR(int8_t, m); + return m->data.i8; else if (m->type == MSGPACK_UINT8) - return (int8_t)*MSGPACK_SELECT_PTR(uint8_t, m); + return (int8_t)m->data.u8; return 0; } @@ -517,9 +174,9 @@ uint8_t msgpack::read_uint8_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return (uint8_t)*MSGPACK_SELECT_PTR(int8_t, m); + return (uint8_t)m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; return 0; } @@ -532,13 +189,13 @@ int16_t msgpack::read_int16_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return *MSGPACK_SELECT_PTR(int8_t, m); + return m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return *MSGPACK_SELECT_PTR(int16_t, m); + return m->data.i16; else if (m->type == MSGPACK_UINT16) - return (int16_t)*MSGPACK_SELECT_PTR(uint16_t, m); + return (int16_t)m->data.u16; return 0; } @@ -551,13 +208,13 @@ uint16_t msgpack::read_uint16_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return (uint16_t)(int16_t)*MSGPACK_SELECT_PTR(int8_t, m); + return (uint16_t)(int16_t)m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return (uint16_t)(int16_t)*MSGPACK_SELECT_PTR(int16_t, m); + return (uint16_t)(int16_t)m->data.i16; else if (m->type == MSGPACK_UINT16) - return *MSGPACK_SELECT_PTR(uint16_t, m); + return m->data.u16; return 0; } @@ -570,17 +227,17 @@ int32_t msgpack::read_int32_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return *MSGPACK_SELECT_PTR(int8_t, m); + return m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return *MSGPACK_SELECT_PTR(int16_t, m); + return m->data.i16; else if (m->type == MSGPACK_UINT16) - return *MSGPACK_SELECT_PTR(uint16_t, m); + return m->data.u16; else if (m->type == MSGPACK_INT32) - return *MSGPACK_SELECT_PTR(int32_t, m); + return m->data.i32; else if (m->type == MSGPACK_UINT32) - return (int32_t)*MSGPACK_SELECT_PTR(uint32_t, m); + return (int32_t)m->data.u32; return 0; } @@ -593,17 +250,17 @@ uint32_t msgpack::read_uint32_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return (uint32_t)(int32_t)*MSGPACK_SELECT_PTR(int8_t, m); + return (uint32_t)(int32_t)m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return (uint32_t)(int32_t)*MSGPACK_SELECT_PTR(int16_t, m); + return (uint32_t)(int32_t)m->data.i16; else if (m->type == MSGPACK_UINT16) - return *MSGPACK_SELECT_PTR(uint16_t, m); + return m->data.u16; else if (m->type == MSGPACK_INT32) - return (uint32_t)(int32_t)*MSGPACK_SELECT_PTR(int32_t, m); + return (uint32_t)(int32_t)m->data.i32; else if (m->type == MSGPACK_UINT32) - return *MSGPACK_SELECT_PTR(uint32_t, m); + return m->data.u32; return 0; } @@ -616,21 +273,21 @@ int64_t msgpack::read_int64_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return *MSGPACK_SELECT_PTR(int8_t, m); + return m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return *MSGPACK_SELECT_PTR(int16_t, m); + return m->data.i16; else if (m->type == MSGPACK_UINT16) - return *MSGPACK_SELECT_PTR(uint16_t, m); + return m->data.u16; else if (m->type == MSGPACK_INT32) - return *MSGPACK_SELECT_PTR(int32_t, m); + return m->data.i32; else if (m->type == MSGPACK_UINT32) - return *MSGPACK_SELECT_PTR(uint32_t, m); + return m->data.u32; else if (m->type == MSGPACK_INT64) - return *MSGPACK_SELECT_PTR(int64_t, m); + return m->data.i64; else if (m->type == MSGPACK_UINT64) - return (int64_t)*MSGPACK_SELECT_PTR(uint64_t, m); + return (int64_t)m->data.u64; return 0; } @@ -643,21 +300,21 @@ uint64_t msgpack::read_uint64_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return (uint64_t)(int64_t)*MSGPACK_SELECT_PTR(int8_t, m); + return (uint64_t)(int64_t)m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return (uint64_t)(int64_t)*MSGPACK_SELECT_PTR(int16_t, m); + return (uint64_t)(int64_t)m->data.i16; else if (m->type == MSGPACK_UINT16) - return *MSGPACK_SELECT_PTR(uint16_t, m); + return m->data.u16; else if (m->type == MSGPACK_INT32) - return (uint64_t)(int64_t)*MSGPACK_SELECT_PTR(int32_t, m); + return (uint64_t)(int64_t)m->data.i32; else if (m->type == MSGPACK_UINT32) - return *MSGPACK_SELECT_PTR(uint32_t, m); + return m->data.u32; else if (m->type == MSGPACK_INT32) - return (uint64_t)*MSGPACK_SELECT_PTR(int64_t, m); + return (uint64_t)m->data.i64; else if (m->type == MSGPACK_UINT32) - return *MSGPACK_SELECT_PTR(uint64_t, m); + return m->data.u64; return 0; } @@ -670,25 +327,25 @@ float_t msgpack::read_float_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return *MSGPACK_SELECT_PTR(int8_t, m); + return m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return *MSGPACK_SELECT_PTR(int16_t, m); + return m->data.i16; else if (m->type == MSGPACK_UINT16) - return *MSGPACK_SELECT_PTR(uint16_t, m); + return m->data.u16; else if (m->type == MSGPACK_INT32) - return (float_t)*MSGPACK_SELECT_PTR(int32_t, m); + return (float_t)m->data.i32; else if (m->type == MSGPACK_UINT32) - return (float_t)*MSGPACK_SELECT_PTR(uint32_t, m); + return (float_t)m->data.u32; else if (m->type == MSGPACK_INT64) - return (float_t)*MSGPACK_SELECT_PTR(int64_t, m); + return (float_t)m->data.i64; else if (m->type == MSGPACK_UINT64) - return (float_t)*MSGPACK_SELECT_PTR(uint64_t, m); + return (float_t)m->data.u64; else if (m->type == MSGPACK_FLOAT) - return *MSGPACK_SELECT_PTR(float_t, m); + return m->data.f32; else if (m->type == MSGPACK_DOUBLE) - return (float_t)*MSGPACK_SELECT_PTR(double_t, m); + return (float_t)m->data.f64; return 0; } @@ -701,25 +358,25 @@ double_t msgpack::read_double_t(const char* name) { return 0; if (m->type == MSGPACK_INT8) - return *MSGPACK_SELECT_PTR(int8_t, m); + return m->data.i8; else if (m->type == MSGPACK_UINT8) - return *MSGPACK_SELECT_PTR(uint8_t, m); + return m->data.u8; else if (m->type == MSGPACK_INT16) - return *MSGPACK_SELECT_PTR(int16_t, m); + return m->data.i16; else if (m->type == MSGPACK_UINT16) - return *MSGPACK_SELECT_PTR(uint16_t, m); + return m->data.u16; else if (m->type == MSGPACK_INT32) - return *MSGPACK_SELECT_PTR(int32_t, m); + return m->data.i32; else if (m->type == MSGPACK_UINT32) - return *MSGPACK_SELECT_PTR(uint32_t, m); + return m->data.u32; else if (m->type == MSGPACK_INT64) - return (double_t)*MSGPACK_SELECT_PTR(int64_t, m); + return (double_t)m->data.i64; else if (m->type == MSGPACK_UINT64) - return (double_t)*MSGPACK_SELECT_PTR(uint64_t, m); + return (double_t)m->data.u64; else if (m->type == MSGPACK_FLOAT) - return *MSGPACK_SELECT_PTR(float_t, m); + return m->data.f32; else if (m->type == MSGPACK_DOUBLE) - return *MSGPACK_SELECT_PTR(double_t, m); + return m->data.f64; return 0; } @@ -728,12 +385,10 @@ char* msgpack::read_utf8_string(const char* name) { return 0; msgpack* m = name ? get_by_name(name) : this; - if (m && m->type == MSGPACK_STRING) { - std::string* ptr = MSGPACK_SELECT_PTR(std::string, m); - size_t length = ptr->size(); + size_t length = m->data.str->size(); char* val = force_malloc_s(char, length + 1); - memcpy(val, ptr->c_str(), length); + memcpy(val, m->data.str->c_str(), length); val[length] = 0; return val; } @@ -745,11 +400,8 @@ wchar_t* msgpack::read_utf16_string(const char* name) { return 0; msgpack* m = name ? get_by_name(name) : this; - - if (m && m->type == MSGPACK_STRING) { - std::string* ptr = MSGPACK_SELECT_PTR(std::string, m); - return utf8_to_utf16(ptr->c_str()); - } + if (m && m->type == MSGPACK_STRING) + return utf8_to_utf16(m->data.str->c_str()); return 0; } @@ -758,11 +410,8 @@ std::string msgpack::read_string(const char* name) { return {}; msgpack* m = name ? get_by_name(name) : this; - - if (m && m->type == MSGPACK_STRING) { - std::string* ptr = MSGPACK_SELECT_PTR(std::string, m); - return *ptr; - } + if (m && m->type == MSGPACK_STRING) + return *m->data.str; return {}; } @@ -771,11 +420,8 @@ std::wstring msgpack::read_wstring(const char* name) { return {}; msgpack* m = name ? get_by_name(name) : this; - - if (m && m->type == MSGPACK_STRING) { - std::string* ptr = MSGPACK_SELECT_PTR(std::string, m); - return utf8_to_utf16(*ptr); - } + if (m && m->type == MSGPACK_STRING) + return utf8_to_utf16(*m->data.str); return {}; } @@ -784,86 +430,89 @@ msgpack& msgpack::operator=(const msgpack& m) { return *this; switch (m.type) { - case MSGPACK_BOOL: { - MSGPACK_ALLOCATE_PTR(double_t, this); - bool* s_ptr = MSGPACK_SELECT(bool, m); - bool* d_ptr = MSGPACK_SELECT_PTR(bool, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT8: { - MSGPACK_ALLOCATE_PTR(int8_t, this); - int8_t* s_ptr = MSGPACK_SELECT(int8_t, m); - int8_t* d_ptr = MSGPACK_SELECT_PTR(int8_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT8: { - MSGPACK_ALLOCATE_PTR(uint8_t, this); - uint8_t* s_ptr = MSGPACK_SELECT(uint8_t, m); - uint8_t* d_ptr = MSGPACK_SELECT_PTR(uint8_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT16: { - MSGPACK_ALLOCATE_PTR(int16_t, this); - int16_t* s_ptr = MSGPACK_SELECT(int16_t, m); - int16_t* d_ptr = MSGPACK_SELECT_PTR(int16_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT16: { - MSGPACK_ALLOCATE_PTR(uint16_t, this); - uint16_t* s_ptr = MSGPACK_SELECT(uint16_t, m); - uint16_t* d_ptr = MSGPACK_SELECT_PTR(uint16_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT32: { - MSGPACK_ALLOCATE_PTR(int32_t, this); - int32_t* s_ptr = MSGPACK_SELECT(int32_t, m); - int32_t* d_ptr = MSGPACK_SELECT_PTR(int32_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT32: { - MSGPACK_ALLOCATE_PTR(uint32_t, this); - uint32_t* s_ptr = MSGPACK_SELECT(uint32_t, m); - uint32_t* d_ptr = MSGPACK_SELECT_PTR(uint32_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_INT64: { - MSGPACK_ALLOCATE_PTR(int64_t, this); - int64_t* s_ptr = MSGPACK_SELECT(int64_t, m); - int64_t* d_ptr = MSGPACK_SELECT_PTR(int64_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_UINT64: { - MSGPACK_ALLOCATE_PTR(uint64_t, this); - uint64_t* s_ptr = MSGPACK_SELECT(uint64_t, m); - uint64_t* d_ptr = MSGPACK_SELECT_PTR(uint64_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_FLOAT: { - MSGPACK_ALLOCATE_PTR(float_t, this); - float_t* s_ptr = MSGPACK_SELECT(float_t, m); - float_t* d_ptr = MSGPACK_SELECT_PTR(float_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_DOUBLE: { - MSGPACK_ALLOCATE_PTR(double_t, this); - double_t* s_ptr = MSGPACK_SELECT(double_t, m); - double_t* d_ptr = MSGPACK_SELECT_PTR(double_t, this); - *d_ptr = *s_ptr; - } break; - case MSGPACK_STRING: { - MSGPACK_ALLOCATE_PTR(std::string, this); - std::string* s_ptr = MSGPACK_SELECT(std::string, m); - std::string* d_ptr = MSGPACK_SELECT_PTR(std::string, this); - *d_ptr = *s_ptr; - } break; + case MSGPACK_BOOL: + case MSGPACK_INT8: + case MSGPACK_UINT8: + case MSGPACK_INT16: + case MSGPACK_UINT16: + case MSGPACK_INT32: + case MSGPACK_UINT32: + case MSGPACK_INT64: + case MSGPACK_UINT64: + case MSGPACK_FLOAT: + case MSGPACK_DOUBLE: + switch (type) { + case MSGPACK_STRING: + delete data.str; + break; + case MSGPACK_ARRAY: + delete data.arr; + break; + case MSGPACK_MAP: + delete data.map; + break; + } + + memcpy(&data, &m.data, sizeof(data)); + break; + case MSGPACK_STRING: + switch (type) { + case MSGPACK_STRING: + break; + case MSGPACK_ARRAY: + delete data.arr; + data.str = new std::string; + break; + case MSGPACK_MAP: + delete data.map; + data.str = new std::string; + break; + default: + data.str = new std::string; + break; + } + data.str->assign(*m.data.str); + break; case MSGPACK_ARRAY: - case MSGPACK_MAP: { - MSGPACK_ALLOCATE_PTR(msgpack_array, this); - msgpack_array* s_ptr = MSGPACK_SELECT(msgpack_array, m); - msgpack_array* d_ptr = MSGPACK_SELECT_PTR(msgpack_array, this); - *d_ptr = *s_ptr; - } break;} + switch (type) { + case MSGPACK_STRING: + delete data.str; + data.arr = new msgpack_array; + break; + case MSGPACK_ARRAY: + break; + case MSGPACK_MAP: + delete data.map; + data.arr = new msgpack_array; + break; + default: + data.arr = new msgpack_array; + break; + } + data.arr->assign(m.data.arr->begin(), m.data.arr->end()); + break; + case MSGPACK_MAP: + switch (type) { + case MSGPACK_STRING: + delete data.str; + data.map = new msgpack_map; + break; + case MSGPACK_ARRAY: + delete data.arr; + data.map = new msgpack_map; + break; + case MSGPACK_MAP: + break; + default: + data.map = new msgpack_map; + break; + } + data.map->assign(m.data.map->begin(), m.data.map->end()); + break; + default: + memset(&data, 0, sizeof(data)); + break; + } type = m.type; - name = m.name; return *this; } diff --git a/src/KKdLib/msgpack.hpp b/src/KKdLib/msgpack.hpp index e2235021..ceac9395 100644 --- a/src/KKdLib/msgpack.hpp +++ b/src/KKdLib/msgpack.hpp @@ -31,53 +31,41 @@ enum msgpack_type : uint32_t { struct msgpack; typedef std::vector msgpack_array; +typedef std::pair msgpack_key_value; +typedef std::vector msgpack_map; union msgpack_data { - uint8_t data[0x08]; - union { - void* ptr; - std::string* str; - msgpack_array* arr; - }; + bool b; + int8_t i8; + uint8_t u8; + int16_t i16; + uint16_t u16; + int32_t i32; + uint32_t u32; + int64_t i64; + uint64_t u64; + float_t f32; + double_t f64; + std::string* str; + msgpack_array* arr; + msgpack_map* map; }; struct msgpack { msgpack_type type; - std::string name; msgpack_data data; - msgpack(); - msgpack(const msgpack& m); - msgpack(const char* name); - msgpack(const char* name, bool array, size_t length); - msgpack(const char* name, bool array, msgpack_array& val); - msgpack(const char* name, bool val); - msgpack(const char* name, int8_t val); - msgpack(const char* name, uint8_t val); - msgpack(const char* name, int16_t val); - msgpack(const char* name, uint16_t val); - msgpack(const char* name, int32_t val); - msgpack(const char* name, uint32_t val); - msgpack(const char* name, int64_t val); - msgpack(const char* name, uint64_t val); - msgpack(const char* name, float_t val); - msgpack(const char* name, double_t val); - msgpack(const char* name, const char* val); - msgpack(const char* name, const wchar_t* val); - msgpack(const char* name, std::string& val); - msgpack(const char* name, std::wstring& val); - ~msgpack(); - - bool check_null(); - bool check_not_null(); msgpack* get_by_index(size_t index); void set_by_index(msgpack* m, size_t index); msgpack* get_by_name(const char* name); - void set_by_name(msgpack* m); - void append(msgpack* m); - void append(msgpack& m); - void append(msgpack&& m); + void set_by_name(const char* name, msgpack* m); + msgpack* append(const char* name, msgpack* m); + msgpack* append(const char* name, msgpack& m); + msgpack* append(const char* name, msgpack&& m); msgpack* read(const char* name); + msgpack* read(const char* name, msgpack_type type); + msgpack* read_array(const char* name = 0); + msgpack* read_map(const char* name = 0); bool read_bool(const char* name = 0); int8_t read_int8_t(const char* name = 0); uint8_t read_uint8_t(const char* name = 0); @@ -95,8 +83,282 @@ struct msgpack { std::wstring read_wstring(const char* name = 0); msgpack& operator=(const msgpack& m); -}; -#define MSGPACK_CHECK(a) (sizeof(a) > 0x08) -#define MSGPACK_SELECT(a, b) (MSGPACK_CHECK(a) ? (a*)(b).data.ptr : (##a##*)(b).data.data) -#define MSGPACK_SELECT_PTR(a, b) (MSGPACK_CHECK(a) ? (a*)(b)->data.ptr : (##a##*)(b)->data.data) + inline msgpack() : data() { + type = MSGPACK_NULL; + } + + inline msgpack(const msgpack& m) : type(), data() { + if (this == &m) + return; + + switch (m.type) { + case MSGPACK_BOOL: + case MSGPACK_INT8: + case MSGPACK_UINT8: + case MSGPACK_INT16: + case MSGPACK_UINT16: + case MSGPACK_INT32: + case MSGPACK_UINT32: + case MSGPACK_INT64: + case MSGPACK_UINT64: + case MSGPACK_FLOAT: + case MSGPACK_DOUBLE: + switch (type) { + case MSGPACK_STRING: + delete data.str; + break; + case MSGPACK_ARRAY: + delete data.arr; + break; + case MSGPACK_MAP: + delete data.map; + break; + } + + memcpy(&data, &m.data, sizeof(data)); + break; + case MSGPACK_STRING: + switch (type) { + case MSGPACK_STRING: + break; + case MSGPACK_ARRAY: + delete data.arr; + data.str = new std::string; + break; + case MSGPACK_MAP: + delete data.map; + data.str = new std::string; + break; + default: + data.str = new std::string; + break; + } + data.str->assign(*m.data.str); + break; + case MSGPACK_ARRAY: + switch (type) { + case MSGPACK_STRING: + delete data.str; + data.arr = new msgpack_array; + break; + case MSGPACK_ARRAY: + break; + case MSGPACK_MAP: + delete data.map; + data.arr = new msgpack_array; + break; + default: + data.arr = new msgpack_array; + break; + } + data.arr->assign(m.data.arr->begin(), m.data.arr->end()); + break; + case MSGPACK_MAP: + switch (type) { + case MSGPACK_STRING: + delete data.str; + data.map = new msgpack_map; + break; + case MSGPACK_ARRAY: + delete data.arr; + data.map = new msgpack_map; + break; + case MSGPACK_MAP: + break; + default: + data.map = new msgpack_map; + break; + } + data.map->assign(m.data.map->begin(), m.data.map->end()); + break; + default: + memset(&data, 0, sizeof(data)); + break; + } + type = m.type; + } + + inline msgpack(msgpack_array& val) : data() { + type = MSGPACK_ARRAY; + data.arr = new msgpack_array; + data.arr->assign(val.begin(), val.end()); + val.clear(); + val.shrink_to_fit(); + } + + inline msgpack(msgpack_array&& val) : data() { + type = MSGPACK_ARRAY; + data.arr = new msgpack_array; + data.arr->assign(val.begin(), val.end()); + val.clear(); + val.shrink_to_fit(); + } + + inline msgpack(msgpack_map& val) : data() { + type = MSGPACK_MAP; + data.map = new msgpack_map; + data.map->assign(val.begin(), val.end()); + val.clear(); + val.shrink_to_fit(); + } + inline msgpack(msgpack_map&& val) : data() { + type = MSGPACK_MAP; + data.map = new msgpack_map; + data.map->assign(val.begin(), val.end()); + val.clear(); + val.shrink_to_fit(); + } + + inline msgpack(bool val) : data() { + type = MSGPACK_BOOL; + data.b = val; + } + + inline msgpack(int8_t val) : data() { + type = MSGPACK_INT8; + data.i64 = val; + } + + inline msgpack(uint8_t val) : data() { + type = MSGPACK_UINT8; + data.u64 = val; + } + + inline msgpack(int16_t val) : data() { + type = MSGPACK_INT16; + data.i64 = val; + } + + inline msgpack(uint16_t val) : data() { + type = MSGPACK_UINT16; + data.u64 = val; + } + + inline msgpack(int32_t val) : data() { + type = MSGPACK_INT32; + data.i64 = val; + } + + inline msgpack(uint32_t val) : data() { + type = MSGPACK_UINT32; + data.u64 = val; + } + + inline msgpack(int64_t val) : data() { + type = MSGPACK_INT64; + data.i64 = val; + } + + inline msgpack(uint64_t val) : data() { + type = MSGPACK_UINT64; + data.u64 = val; + } + + inline msgpack(float_t val) : data() { + type = MSGPACK_FLOAT; + data.f32 = val; + } + + inline msgpack(double_t val) : data() { + type = MSGPACK_DOUBLE; + data.f64 = val; + } + + inline msgpack(const char* val) : data() { + type = MSGPACK_STRING; + data.str = new std::string; + if (val) + data.str->assign(val); + } + + inline msgpack(const wchar_t* val) : data() { + type = MSGPACK_STRING; + data.str = new std::string; + if (val) { + char* temp = utf16_to_utf8(val); + data.str->assign(temp); + free_def(temp); + } + } + + inline msgpack(std::string& val) : data() { + type = MSGPACK_STRING; + data.str = new std::string; + if (val.size()) + data.str->assign(val); + } + + inline msgpack(std::string&& val) : data() { + type = MSGPACK_STRING; + data.str = new std::string; + if (val.size()) + data.str->assign(val); + } + + inline msgpack(std::wstring& val) : data() { + type = MSGPACK_STRING; + data.str = new std::string; + if (val.size()) { + char* temp = utf16_to_utf8(val.c_str()); + data.str->assign(temp); + free_def(temp); + } + } + + inline msgpack(std::wstring&& val) : data() { + type = MSGPACK_STRING; + data.str = new std::string; + if (val.size()) { + char* temp = utf16_to_utf8(val.c_str()); + data.str->assign(temp); + free_def(temp); + } + } + + inline ~msgpack() { + switch (type) { + case MSGPACK_STRING: + delete data.str; + break; + case MSGPACK_ARRAY: + delete data.arr; + break; + case MSGPACK_MAP: + delete data.map; + break; + } + } + + inline bool check_null() { + if (type == MSGPACK_ARRAY) + return data.arr->size() == 0; + else if (type == MSGPACK_MAP) + return data.map->size() == 0; + return type == MSGPACK_NONE; + } + + inline bool check_not_null() { + if (type == MSGPACK_ARRAY) + return data.arr->size() != 0; + else if (type == MSGPACK_MAP) + return data.map->size() != 0; + return type != MSGPACK_NONE; + } + + inline void clear() { + switch (type) { + case MSGPACK_STRING: + delete data.str; + break; + case MSGPACK_ARRAY: + delete data.arr; + break; + case MSGPACK_MAP: + delete data.map; + break; + } + type = MSGPACK_NONE; + memset(&data, 0, sizeof(data)); + } +}; diff --git a/src/KKdLib/obj.cpp b/src/KKdLib/obj.cpp index d79da3af..429dc8fe 100644 --- a/src/KKdLib/obj.cpp +++ b/src/KKdLib/obj.cpp @@ -5,9 +5,8 @@ #include "obj.hpp" #include +#include "io/memory_stream.hpp" #include "f2/struct.hpp" -#include "io/path.hpp" -#include "io/stream.hpp" #include "half_t.hpp" #include "hash.hpp" #include "sort.hpp" @@ -129,47 +128,47 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset); static void obj_classic_read_skin_block_cloth(obj_skin_block_cloth* b, stream& s, char** str); static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* b, - stream& s, std::vector& strings, std::vector& string_offsets, + stream& s, std::vector& strings, std::vector& string_offsets, int64_t* mats_offset, int64_t* root_offset, int64_t* nodes_offset, int64_t* mesh_indices_offset, int64_t* backface_mesh_indices_offset); static void obj_classic_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* sub, stream& s, char** str); static void obj_classic_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* sub, - stream& s, std::vector& strings, std::vector& string_offsets); + stream& s, std::vector& strings, std::vector& string_offsets); static void obj_classic_read_skin_block_constraint(obj_skin_block_constraint* b, stream& s, char** str); static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* b, - stream& s, std::vector& strings, std::vector& string_offsets, + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, int64_t* offsets); static void obj_classic_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, stream& s, char** str); static void obj_classic_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, - stream& s, std::vector& strings, std::vector& string_offsets); + stream& s, std::vector& strings, std::vector& string_offsets); static void obj_classic_read_skin_block_constraint_up_vector_old(obj_skin_block_constraint_up_vector* up, stream& s, char** str); static void obj_classic_write_skin_block_constraint_up_vector_old(obj_skin_block_constraint_up_vector* up, - stream& s, std::vector& strings, std::vector& string_offsets); + stream& s, std::vector& strings, std::vector& string_offsets); static void obj_classic_read_skin_block_expression(obj_skin_block_expression* b, stream& s, char** str); static void obj_classic_write_skin_block_expression(obj_skin_block_expression* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names); + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names); static void obj_classic_read_skin_block_motion(obj_skin_block_motion* b, stream& s, char** str); static void obj_classic_write_skin_block_motion(obj_skin_block_motion* b, - stream& s, std::vector& strings, std::vector& string_offsets, + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, int64_t* bone_names_offset, int64_t* bone_matrices_offset); static void obj_classic_read_skin_block_node(obj_skin_block_node* b, stream& s, char** str); static void obj_classic_write_skin_block_node(obj_skin_block_node* b, - stream& s, std::vector& strings, std::vector& string_offsets); + stream& s, std::vector& strings, std::vector& string_offsets); static void obj_classic_read_skin_block_osage(obj_skin_block_osage* b, stream& s, char** str); static void obj_classic_write_skin_block_osage(obj_skin_block_osage* b, - stream& s, std::vector& strings, std::vector& string_offsets, int64_t* nodes_offset); + stream& s, std::vector& strings, std::vector& string_offsets, int64_t* nodes_offset); static void obj_classic_read_skin_param(obj_skin_skin_param* skp, stream& s, char** str); static void obj_classic_write_skin_param(obj_skin_skin_param* skp, - stream& s, std::vector& strings, std::vector& string_offsets); + stream& s, std::vector& strings, std::vector& string_offsets); static void obj_classic_read_vertex(obj* obj, stream& s, int64_t* vertex, obj_mesh* mesh, int64_t base_offset, uint32_t num_vertex, obj_vertex_format_file vertex_format_file); static void obj_classic_write_vertex(obj* obj, stream& s, int64_t* vertex, obj_mesh* mesh, @@ -191,56 +190,56 @@ static void obj_modern_write_skin(obj* obj, stream& s, static void obj_modern_read_skin_block_cloth(obj_skin_block_cloth* b, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, int64_t* mats_offset, int64_t* root_offset, int64_t* nodes_offset, int64_t* mesh_indices_offset, int64_t* backface_mesh_indices_offset); static void obj_modern_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* sub, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* sub, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); static void obj_modern_read_skin_block_constraint(obj_skin_block_constraint* b, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, bool is_x, int64_t* offsets); static void obj_modern_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); static void obj_modern_read_skin_block_constraint_up_vector_old(obj_skin_block_constraint_up_vector* up, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_constraint_up_vector_old(obj_skin_block_constraint_up_vector* up, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); static void obj_modern_read_skin_block_expression(obj_skin_block_expression* b, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_expression(obj_skin_block_expression* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, bool is_x); + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, bool is_x); static void obj_modern_read_skin_block_motion(obj_skin_block_motion* b, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_motion(obj_skin_block_motion* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, char** bone_names, int64_t* bone_names_offset, int64_t* bone_matrices_offset); static void obj_modern_read_skin_block_node(obj_skin_block_node* b, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_node(obj_skin_block_node* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); static void obj_modern_read_skin_block_osage(obj_skin_block_osage* b, stream& s, uint32_t header_length, char** str, bool is_x); static void obj_modern_write_skin_block_osage(obj_skin_block_osage* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); static void obj_modern_read_vertex(obj* obj, stream& s, int64_t* vertex, obj_mesh* mesh, const uint32_t attrib_flags, uint32_t num_vertex, uint32_t size_vertex); static void obj_modern_write_vertex(obj* obj, stream& s, bool is_x, int64_t* vertex, obj_mesh* mesh, uint32_t* attrib_flags, uint32_t* num_vertex, uint32_t* size_vertex, f2_struct* ovtx); static void obj_skin_block_node_free(obj_skin_block_node* b); -static uint32_t obj_skin_strings_get_string_index(std::vector& vec, const char* str); -static int64_t obj_skin_strings_get_string_offset(std::vector& vec, +static uint32_t obj_skin_strings_get_string_index(std::vector& vec, const char* str); +static int64_t obj_skin_strings_get_string_offset(std::vector& vec, std::vector& vec_off, const char* str); -static int64_t obj_skin_strings_get_string_offset_by_index(std::vector& vec, +static int64_t obj_skin_strings_get_string_offset_by_index(std::vector& vec, std::vector& vec_off, char** strings, uint32_t index); -static void obj_skin_strings_push_back_check(std::vector& vec, const char* str); -static void obj_skin_strings_push_back_check_by_index(std::vector& vec, +static void obj_skin_strings_push_back_check(std::vector& vec, const char* str); +static void obj_skin_strings_push_back_check_by_index(std::vector& vec, char** strings, uint32_t index); obj_bounding_sphere::obj_bounding_sphere() : radius() { @@ -308,7 +307,7 @@ obj_mesh* obj::get_obj_mesh(const char* name) { return -1; } -obj_set::obj_set() : ready(), modern(), is_x(), obj_data(), +obj_set::obj_set() : ready(), modern(), big_endian(), is_x(), obj_data(), obj_num(), tex_id_data(), tex_id_num(), reserved() { } @@ -317,59 +316,59 @@ obj_set::~obj_set() { for (uint32_t i = 0; i < obj_num; i++) { obj* obj = &obj_data[i]; for (uint32_t j = 0; j < obj->skin.bones_count; j++) - free(obj->skin.bones[j].name); - free(obj->skin.bones); + free_def(obj->skin.bones[j].name); + free_def(obj->skin.bones); for (uint32_t j = 0; j < obj->skin.ex_data.blocks_count; j++) { obj_skin_block* block = &obj->skin.ex_data.blocks[j]; switch (block->type) { case OBJ_SKIN_BLOCK_CLOTH: { obj_skin_block_cloth* cloth = &block->cloth; - free(cloth->mesh_name); - free(cloth->backface_mesh_name); + free_def(cloth->mesh_name); + free_def(cloth->backface_mesh_name); for (uint32_t k = 0; k < cloth->root_count; k++) { obj_skin_block_cloth_root* sub = &cloth->root[k]; for (uint32_t l = 0; l < 4; l++) - free(sub->bone_weights[l].bone_name); + free_def(sub->bone_weights[l].bone_name); } - free(cloth->root); - free(cloth->nodes); - free(cloth->mesh_indices); - free(cloth->backface_mesh_indices); - free(cloth->skin_param.coli); + free_def(cloth->root); + free_def(cloth->nodes); + free_def(cloth->mesh_indices); + free_def(cloth->backface_mesh_indices); + free_def(cloth->skin_param.coli); } break; case OBJ_SKIN_BLOCK_CONSTRAINT: { obj_skin_block_constraint* constraint = &block->constraint; obj_skin_block_node_free(&constraint->base); - free(constraint->source_node_name); + free_def(constraint->source_node_name); } break; case OBJ_SKIN_BLOCK_EXPRESSION: { obj_skin_block_expression* expression = &block->expression; obj_skin_block_node_free(&expression->base); for (uint32_t k = 0; k < 9; k++) - free(expression->expressions[k]); + free_def(expression->expressions[k]); } break; case OBJ_SKIN_BLOCK_MOTION: { obj_skin_block_motion* motion = &block->motion; obj_skin_block_node_free(&motion->base); if (is_x) - free(motion->name); - free(motion->nodes); + free_def(motion->name); + free_def(motion->nodes); } break; case OBJ_SKIN_BLOCK_OSAGE: { obj_skin_block_osage* osage = &block->osage; obj_skin_block_node_free(&osage->base); - free(osage->skin_param.coli); - free(osage->nodes); + free_def(osage->skin_param.coli); + free_def(osage->nodes); } break; } } - free(obj->skin.ex_data.blocks); - free(obj->skin.ex_data.osage_nodes); - free(obj->skin.ex_data.bone_names_buf); - free(obj->skin.ex_data.bone_names); - free(obj->skin.ex_data.osage_sibling_infos); + free_def(obj->skin.ex_data.blocks); + free_def(obj->skin.ex_data.osage_nodes); + free_def(obj->skin.ex_data.bone_names_buf); + free_def(obj->skin.ex_data.bone_names); + free_def(obj->skin.ex_data.osage_sibling_infos); if (obj->mesh_array) for (uint32_t j = 0; j < obj->num_mesh; j++) { @@ -377,25 +376,25 @@ obj_set::~obj_set() { if (mesh->submesh_array) for (uint32_t k = 0; k < mesh->num_submesh; k++) { obj_sub_mesh* sub_mesh = &mesh->submesh_array[k]; - free(sub_mesh->bone_indices); - free(sub_mesh->indices); + free_def(sub_mesh->bone_indices); + free_def(sub_mesh->indices); } - free(mesh->vertex); - free(mesh->submesh_array); + free_def(mesh->vertex); + free_def(mesh->submesh_array); } - free(obj->mesh_array); - free(obj->material_array); - free(obj->name); + free_def(obj->mesh_array); + free_def(obj->material_array); + free_def(obj->name); } - free(obj_data); - free(tex_id_data); + free_def(obj_data); + free_def(tex_id_data); } void obj_set::pack_file(void** data, size_t* size) { if (!data || !ready) return; - stream s; + memory_stream s; s.open(); if (!modern) obj_set_classic_write_inner(this, s); @@ -409,7 +408,7 @@ void obj_set::unpack_file(const void* data, size_t size, bool modern) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); if (!modern) obj_set_classic_read_inner(this, s); @@ -419,7 +418,7 @@ void obj_set::unpack_file(const void* data, size_t size, bool modern) { static void obj_material_texture_enrs_table_init() { if (!obj_material_texture_enrs_table_initialized) { - stream s; + memory_stream s; s.open((void*)&obj_material_texture_enrs_table_bin, sizeof(obj_material_texture_enrs_table_bin)); obj_material_texture_enrs_table.read(s); @@ -459,41 +458,27 @@ static void calculate_tangent(obj_vertex_data* vtx, obj_vertex_data* vtx_b = &vtx[b]; obj_vertex_data* vtx_c = &vtx[c]; - vec3 pos_a; - vec3 pos_b; - vec3_sub(vtx_c->position, vtx_a->position, pos_a); - vec3_sub(vtx_b->position, vtx_a->position, pos_b); + vec3 pos_a = vtx_c->position - vtx_a->position; + vec3 pos_b = vtx_b->position - vtx_a->position; - vec2 uv_a; - vec2 uv_b; - vec2_sub(vtx_c->texcoord0, vtx_a->texcoord0, uv_a); - vec2_sub(vtx_b->texcoord0, vtx_a->texcoord0, uv_b); + vec2 uv_a = vtx_c->texcoord0 - vtx_a->texcoord0; + vec2 uv_b = vtx_b->texcoord0 - vtx_a->texcoord0; - vec3 tangent; - vec3 bitangent; - - vec3 temp1; - vec3 temp2; - vec3_mult_scalar(pos_a, uv_b.y, temp1); - vec3_mult_scalar(pos_b, uv_a.y, temp2); - vec3_sub(temp1, temp2, tangent); - - vec3_mult_scalar(pos_b, uv_a.x, temp1); - vec3_mult_scalar(pos_a, uv_b.x, temp2); - vec3_sub(temp1, temp2, bitangent); + vec3 tangent = pos_a * uv_b.y - pos_b * uv_a.y; + vec3 bitangent = pos_b * uv_a.x - pos_a * uv_b.x; if (uv_a.x * uv_b.y - uv_a.y * uv_b.x <= 0.0f) { - vec3_negate(tangent, tangent); - vec3_negate(bitangent, bitangent); + tangent = -tangent; + bitangent = -bitangent; } - vec3_add(tangents[a], tangent, tangents[a]); - vec3_add(tangents[b], tangent, tangents[b]); - vec3_add(tangents[c], tangent, tangents[c]); - - vec3_add(bitangents[a], bitangent, bitangents[a]); - vec3_add(bitangents[b], bitangent, bitangents[b]); - vec3_add(bitangents[c], bitangent, bitangents[c]); + tangents[a] += tangent; + tangents[b] += tangent; + tangents[c] += tangent; + + bitangents[a] += bitangent; + bitangents[b] += bitangent; + bitangents[c] += bitangent; } static void obj_vertex_generate_tangents(obj* obj, obj_mesh* mesh) { @@ -560,29 +545,15 @@ static void obj_vertex_generate_tangents(obj* obj, obj_mesh* mesh) { for (uint32_t i = 0; i < num_vertex; i++) { vec3 normal = vtx[i].normal; - vec3 tangent; - vec3 bitangent; - vec3_normalize(tangents[i], tangent); - vec3_normalize(bitangents[i], bitangent); + vec3 tangent = vec3::normalize(tangents[i]); + vec3 bitangent = vec3::normalize(bitangents[i]); - float_t temp1; - vec3 temp2; - vec3_dot(tangent, normal, temp1); - vec3_mult_scalar(normal, temp1, temp2); - vec3_sub(tangent, temp2, tangent); - vec3_normalize(tangent, tangent); + tangent = vec3::normalize(tangent - normal * vec3::dot(tangent, normal)); + bitangent = vec3::normalize(bitangent - normal * vec3::dot(bitangent, normal)); - vec3_dot(bitangent, normal, temp1); - vec3_mult_scalar(normal, temp1, temp2); - vec3_sub(bitangent, temp2, bitangent); - vec3_normalize(bitangent, bitangent); + vec3 binormal = vec3::normalize(vec3::cross(normal, tangent)); - vec3 binormal; - vec3_cross(normal, tangent, binormal); - vec3_normalize(binormal, binormal); - - float_t dir_check; - vec3_dot(binormal, bitangent, dir_check); + float_t dir_check = vec3::dot(binormal, bitangent); *(vec3*)&vtx[i].tangent = tangent; vtx[i].tangent.w = dir_check > 0.0f ? 1.0f : -1.0f; @@ -607,8 +578,7 @@ static void obj_vertex_generate_tangents(obj* obj, obj_mesh* mesh) { if (i == j || !memcmp(&tangent_to_compare, &vec3_null, sizeof(vec3))) continue; - float_t distance; - vec3_distance_squared(position, position_to_compare, distance); + float_t distance = vec3::distance_squared(position, position_to_compare); if (current_distance >= distance) { nearest_vtx_idx = j; @@ -623,26 +593,21 @@ static void obj_vertex_generate_tangents(obj* obj, obj_mesh* mesh) { const vec3 up = { 0.0f, 1.0f, 0.0f }; const vec3 left = { 1.0f, 0.0f, 0.0f }; - vec3 temp1; - vec3 temp2; - vec3_cross(normal, up, temp1); - vec3_cross(normal, left, temp2); + vec3 temp1 = vec3::cross(normal, up); + vec3 temp2 = vec3::cross(normal, left); - float_t temp3; - float_t temp4; - vec3_length_squared(temp1, temp3); - vec3_length_squared(temp2, temp4); + float_t temp3 = vec3::length_squared(temp1); + float_t temp4 = vec3::length_squared(temp2); - vec3 tangent = temp3 > temp4 ? temp1 : temp2; - vec3_normalize(tangent, tangent); + vec3 tangent = vec3::normalize(temp3 > temp4 ? temp1 : temp2); *(vec3*)&vtx[i].tangent = tangent; vtx[i].tangent.w = 1.0f; } } - free(tangents); - free(bitangents); + free_def(tangents); + free_def(bitangents); enum_or(mesh->vertex_format, OBJ_VERTEX_TANGENT); } @@ -665,7 +630,7 @@ static void obj_vertex_validate_bone_data(vec4& bone_weight, vec4i& bone_index) float_t sum = _bone_weight.x + _bone_weight.y + _bone_weight.z + _bone_weight.w; if (sum > 0.0f && fabsf(sum - 1.0f) > 0.000001f) - vec4_div_scalar(_bone_weight, sum, _bone_weight); + _bone_weight *= 1.0f / sum; bone_weight = _bone_weight; bone_index = _bone_index; @@ -674,9 +639,10 @@ static void obj_vertex_validate_bone_data(vec4& bone_weight, vec4i& bone_index) static void obj_set_classic_read_inner(obj_set* os, stream& s) { uint32_t version = s.read_uint32_t(); if (version != 0x05062500) { - os->is_x = false; - os->modern = false; os->ready = false; + os->modern = false; + os->big_endian = false; + os->is_x = false; return; } @@ -748,13 +714,14 @@ static void obj_set_classic_read_inner(obj_set* os, stream& s) { os->tex_id_data[i] = s.read_uint32_t(); } - free(obj_datas); - free(obj_skin_datas); - free(obj_name_datas); + free_def(obj_datas); + free_def(obj_skin_datas); + free_def(obj_name_datas); - os->is_x = false; - os->modern = false; os->ready = true; + os->modern = false; + os->big_endian = false; + os->is_x = false; } static void obj_set_classic_write_inner(obj_set* os, stream& s) { @@ -794,7 +761,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { for (uint32_t i = 0; i < obj_num; i++) s.write_uint32_t(obj_datas[i]); s.position_pop(); - free(obj_datas); + free_def(obj_datas); osh.obj_id_data = s.get_position(); for (uint32_t i = 0; i < obj_num; i++) { @@ -816,7 +783,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { for (uint32_t i = 0; i < obj_num; i++) s.write_int32_t(obj_name_datas[i]); s.align_write(0x10); - free(obj_name_datas); + free_def(obj_name_datas); osh.tex_id_data = s.get_position(); for (uint32_t i = 0; i < os->tex_id_num; i++) @@ -844,7 +811,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { for (uint32_t i = 0; i < obj_num; i++) s.write_int32_t(obj_skin_datas[i]); s.position_pop(); - free(obj_skin_datas); + free_def(obj_skin_datas); s.position_push(0x00, SEEK_SET); s.write_uint32_t(0x05062500); @@ -1179,7 +1146,7 @@ static void obj_classic_write_model(obj* obj, stream& s, int64_t base_offset) { s.write_char('\0'); } s.position_pop(); - free(mhs); + free_def(mhs); } if (obj->num_material) { @@ -1281,7 +1248,7 @@ static void obj_classic_read_skin(obj* obj, stream& s, int64_t base_offset) { sk->bones[i].parent = s.read_uint32_t(); } } - free(bone_names_offsets); + free_def(bone_names_offsets); } if (sh.ex_data_offset) { @@ -1325,7 +1292,7 @@ static void obj_classic_read_skin(obj* obj, stream& s, int64_t base_offset) { bone_names.push_back({}); buf_size += bone_names.back().size() + 1; } - free(strings_offsets); + free_def(strings_offsets); if (bone_names.size()) { ex->bone_names_buf = force_malloc_s(char, buf_size); @@ -1425,7 +1392,7 @@ static void obj_classic_read_skin(obj* obj, stream& s, int64_t base_offset) { break; } } - free(bhs); + free_def(bhs); } if (exh.osage_sibling_infos_offset) { @@ -1485,9 +1452,9 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { s.write(0x0C); s.align_write(0x10); - std::vector strings; + std::vector strings; std::vector string_offsets; - std::vector bone_names; + std::vector bone_names; if (sk->bones) { sh.bone_ids_offset = s.get_position(); for (uint32_t i = 0; i < sk->bones_count; i++) @@ -1745,7 +1712,7 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { exh.bone_names_count = (int32_t)bone_names.size(); exh.bone_names_offset = s.get_position(); - for (std::string& i : bone_names) + for (string_hash& i : bone_names) s.write_int32_t(0); s.align_write(0x10); @@ -1958,16 +1925,16 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { } if (sk->bones || sk->ex_data_init) { - quicksort_string(strings.data(), strings.size()); + quicksort_string_hash(strings.data(), strings.size()); string_offsets.reserve(strings.size()); - for (std::string& i : strings) { + for (string_hash& i : strings) { string_offsets.push_back(s.get_position()); - s.write_string_null_terminated(i); + s.write_string_null_terminated(i.str); } } s.align_write(0x10); - std::vector osage_names; + std::vector osage_names; if (sk->ex_data_init) { obj_skin_ex_data* ex = &sk->ex_data; @@ -2092,7 +2059,7 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { s.write_int32_t(0); s.write_int32_t(0); s.position_pop(); - free(bhs); + free_def(bhs); } } @@ -2111,7 +2078,7 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { if (ex->blocks_count > 0) { s.position_push(exh.bone_names_offset, SEEK_SET); - for (std::string& i : bone_names) { + for (string_hash& i : bone_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); s.write_uint32_t((uint32_t)str_offset); @@ -2142,7 +2109,7 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { exh.osage_count = (int32_t)osage_names.size(); exh.osage_count -= exh.cloth_count; s.position_push(exh.osage_names_offset, SEEK_SET); - for (std::string& i : osage_names) { + for (string_hash& i : osage_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); s.write_uint32_t((uint32_t)str_offset); @@ -2312,7 +2279,7 @@ static void obj_classic_read_skin_block_cloth(obj_skin_block_cloth* b, } static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* b, - stream& s, std::vector& strings, std::vector& string_offsets, + stream& s, std::vector& strings, std::vector& string_offsets, int64_t* mats_offset, int64_t* root_offset, int64_t* nodes_offset, int64_t* mesh_indices_offset, int64_t* backface_mesh_indices_offset) { int64_t skin_param_offset = 0; @@ -2437,7 +2404,7 @@ static void obj_classic_read_skin_block_cloth_root_bone_weight(obj_skin_block_cl } static void obj_classic_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* sub, - stream& s, std::vector& strings, std::vector& string_offsets) { + stream& s, std::vector& strings, std::vector& string_offsets) { int64_t bone_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, sub->bone_name); s.write_uint32_t((uint32_t)bone_name_offset); @@ -2462,7 +2429,7 @@ static void obj_classic_read_skin_block_constraint(obj_skin_block_constraint* b, b->name_index = 0x8000 | (int32_t)(i - str); break; } - free(name); + free_def(name); b->coupling = (obj_skin_block_constraint_coupling)s.read_int32_t(); @@ -2507,11 +2474,11 @@ static void obj_classic_read_skin_block_constraint(obj_skin_block_constraint* b, } else b->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; - free(type); + free_def(type); } static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* b, - stream& s, std::vector& strings, std::vector& string_offsets, + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, int64_t* offsets) { obj_classic_write_skin_block_node(&b->base, s, strings, string_offsets); @@ -2588,7 +2555,7 @@ static void obj_classic_read_skin_block_constraint_attach_point(obj_skin_block_c } static void obj_classic_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, - stream& s, std::vector& strings, std::vector& string_offsets) { + stream& s, std::vector& strings, std::vector& string_offsets) { s.write_int32_t(ap->affected_by_orientation ? 1 : 0); s.write_int32_t(ap->affected_by_scaling ? 1 : 0); s.write_float_t(ap->offset.x); @@ -2612,7 +2579,7 @@ static void obj_classic_read_skin_block_constraint_up_vector_old(obj_skin_block_ } static void obj_classic_write_skin_block_constraint_up_vector_old(obj_skin_block_constraint_up_vector* up, - stream& s, std::vector& strings, std::vector& string_offsets) { + stream& s, std::vector& strings, std::vector& string_offsets) { s.write_int32_t(up->active ? 1 : 0); s.write_float_t(up->roll); s.write_float_t(up->affected_axis.x); @@ -2640,10 +2607,10 @@ static void obj_classic_read_skin_block_expression(obj_skin_block_expression* b, b->name_index = 0x8000 | (int32_t)(i - str); break; } - free(name); + free_def(name); b->expressions_count = s.read_int32_t(); - b->expressions_count = min(b->expressions_count, 9); + b->expressions_count = min_def(b->expressions_count, 9); for (uint32_t i = 0; i < b->expressions_count; i++) { uint32_t expression_offset = s.read_uint32_t(); if (expression_offset) @@ -2655,14 +2622,14 @@ static void obj_classic_read_skin_block_expression(obj_skin_block_expression* b, } static void obj_classic_write_skin_block_expression(obj_skin_block_expression* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names) { + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names) { obj_classic_write_skin_block_node(&b->base, s, strings, string_offsets); int64_t name_offset = obj_skin_strings_get_string_offset_by_index(strings, string_offsets, bone_names, b->name_index); s.write_uint32_t((uint32_t)name_offset); - s.write_int32_t(min(b->expressions_count, 9)); + s.write_int32_t(min_def(b->expressions_count, 9)); for (uint32_t i = 0; i < b->expressions_count && i < 9; i++) { int64_t expression_offset = obj_skin_strings_get_string_offset(strings, string_offsets, b->expressions[i]); @@ -2690,7 +2657,7 @@ static void obj_classic_read_skin_block_motion(obj_skin_block_motion* b, b->name_index = 0x8000 | (int32_t)(i - str); break; } - free(name); + free_def(name); b->nodes = 0; @@ -2732,7 +2699,7 @@ static void obj_classic_read_skin_block_motion(obj_skin_block_motion* b, } static void obj_classic_write_skin_block_motion(obj_skin_block_motion* b, - stream& s, std::vector& strings, std::vector& string_offsets, + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, int64_t* bone_names_offset, int64_t* bone_matrices_offset) { obj_classic_write_skin_block_node(&b->base, s, strings, string_offsets); @@ -2792,7 +2759,7 @@ static void obj_classic_read_skin_block_node(obj_skin_block_node* b, } static void obj_classic_write_skin_block_node(obj_skin_block_node* b, - stream& s, std::vector& strings, std::vector& string_offsets) { + stream& s, std::vector& strings, std::vector& string_offsets) { int64_t parent_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, b->parent_name); s.write_uint32_t((uint32_t)parent_name_offset); @@ -2829,7 +2796,7 @@ static void obj_classic_read_skin_block_osage(obj_skin_block_osage* b, b->nodes = force_malloc_s(obj_skin_osage_node, b->count); s.position_push(offset, SEEK_SET); - if (~s.read_uint32_t() & 0x8000) { + if (!(s.read_uint32_t() & 0x8000)) { obj_classic_read_skin_param(&b->skin_param, s, str); b->skin_param_init = true; } @@ -2849,7 +2816,7 @@ static void obj_classic_read_skin_block_osage(obj_skin_block_osage* b, } static void obj_classic_write_skin_block_osage(obj_skin_block_osage* b, - stream& s, std::vector& strings, std::vector& string_offsets, int64_t* nodes_offset) { + stream& s, std::vector& strings, std::vector& string_offsets, int64_t* nodes_offset) { int64_t skin_param_offset = 0; if (b->skin_param_init) { skin_param_offset = s.get_position(); @@ -2935,7 +2902,7 @@ static void obj_classic_read_skin_param(obj_skin_skin_param* skp, } static void obj_classic_write_skin_param(obj_skin_skin_param* skp, - stream& s, std::vector& strings, std::vector& string_offsets) { + stream& s, std::vector& strings, std::vector& string_offsets) { int64_t coli_offset = 0; if (skp->coli) { coli_offset = s.get_position(); @@ -3020,7 +2987,7 @@ static void obj_classic_read_vertex(obj* obj, stream& s, int64_t* vertex, obj_me obj_vertex_data* vtx = force_malloc_s(obj_vertex_data, num_vertex); for (uint32_t i = 0; i < 20; i++) { obj_vertex_format_file attribute = (obj_vertex_format_file)(1 << i); - if (~vertex_format_file & attribute) + if (!(vertex_format_file & attribute)) continue; s.set_position(base_offset + vertex[i], SEEK_SET); @@ -3327,15 +3294,18 @@ static void obj_set_modern_read_inner(obj_set* os, stream& s) { if (st.header.signature != reverse_endianness_uint32_t('MOSD') || !st.data.size()) return; - stream s_mosd; + bool big_endian = st.header.use_big_endian; + + memory_stream s_mosd; s_mosd.open(st.data); - s_mosd.is_big_endian = st.header.use_big_endian; + s_mosd.big_endian = big_endian; uint32_t version = s_mosd.read_uint32_t_reverse_endianness(); if (version != 0x05062501) { - os->is_x = false; - os->modern = false; os->ready = false; + os->modern = false; + os->big_endian = false; + os->is_x = false; return; } @@ -3433,9 +3403,9 @@ static void obj_set_modern_read_inner(obj_set* os, stream& s) { os->obj_data[i].id = s_mosd.read_uint32_t_reverse_endianness(); } - free(obj_datas); - free(obj_skin_datas); - free(obj_name_datas); + free_def(obj_datas); + free_def(obj_skin_datas); + free_def(obj_name_datas); if (osh.tex_id_data) { s_mosd.set_position(osh.tex_id_data, SEEK_SET); @@ -3460,34 +3430,34 @@ static void obj_set_modern_read_inner(obj_set* os, stream& s) { else if (!ovtx && j.header.signature == reverse_endianness_uint32_t('OVTX')) ovtx = &j; - stream s_oskn; - stream s_oidx; - stream s_ovtx; + memory_stream s_oskn; + memory_stream s_oidx; + memory_stream s_ovtx; stream* s_oskn_ptr = 0; stream* s_oidx_ptr = 0; stream* s_ovtx_ptr = 0; if (oskn) { s_oskn.open(oskn->data); - s_oskn.is_big_endian = oskn->header.use_big_endian; + s_oskn.big_endian = oskn->header.use_big_endian; s_oskn_ptr = &s_oskn; } if (oidx) { s_oidx.open(oidx->data); - s_oidx.is_big_endian = oidx->header.use_big_endian; + s_oidx.big_endian = oidx->header.use_big_endian; s_oidx_ptr = &s_oidx; } if (ovtx) { s_ovtx.open(ovtx->data); - s_ovtx.is_big_endian = ovtx->header.use_big_endian; + s_ovtx.big_endian = ovtx->header.use_big_endian; s_ovtx_ptr = &s_ovtx; } obj* obj = &os->obj_data[omdl_index]; - stream s_omdl; + memory_stream s_omdl; s_omdl.open(i.data); - s_omdl.is_big_endian = i.header.use_big_endian; + s_omdl.big_endian = i.header.use_big_endian; obj_modern_read_model(obj, s_omdl, 0, i.header.length, is_x, s_oidx_ptr, s_ovtx_ptr); s_omdl.close(); @@ -3496,14 +3466,19 @@ static void obj_set_modern_read_inner(obj_set* os, stream& s) { omdl_index++; } - os->is_x = is_x; - os->modern = true; os->ready = true; + os->modern = true; + os->big_endian = big_endian; + os->is_x = is_x; } static void obj_set_modern_write_inner(obj_set* os, stream& s) { - stream s_mosd; + bool big_endian = s.big_endian; + + memory_stream s_mosd; s_mosd.open(); + s_mosd.big_endian = big_endian; + uint32_t off; enrs e; enrs_entry ee; @@ -3627,12 +3602,12 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { osh.obj_id_data = s_mosd.get_position(); for (uint32_t i = 0; i < obj_num; i++) - s_mosd.write_uint32_t(os->obj_data[i].id); + s_mosd.write_uint32_t_reverse_endianness(os->obj_data[i].id); s_mosd.align_write(0x10); osh.tex_id_data = s_mosd.get_position(); for (uint32_t i = 0; i < os->tex_id_num; i++) - s_mosd.write_uint32_t(os->tex_id_data[i]); + s_mosd.write_uint32_t_reverse_endianness(os->tex_id_data[i]); s_mosd.align_write(0x10); int64_t* obj_name_datas = force_malloc_s(int64_t, obj_num); @@ -3650,34 +3625,34 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { for (uint32_t i = 0; i < obj_num; i++) s_mosd.write_offset_x(obj_name_datas[i]); s_mosd.position_pop(); - free(obj_name_datas); + free_def(obj_name_datas); s_mosd.position_push(0x00, SEEK_SET); if (!is_x) { - s_mosd.write_uint32_t(0x05062501); - s_mosd.write_int32_t(os->obj_num); - s_mosd.write_int32_t(-1); + s_mosd.write_uint32_t_reverse_endianness(0x05062501); + s_mosd.write_int32_t_reverse_endianness(os->obj_num); + s_mosd.write_int32_t_reverse_endianness(-1); s_mosd.write_offset_f2(osh.obj_data, 0x20); s_mosd.write_offset_f2(osh.obj_skin_data, 0x20); s_mosd.write_offset_f2(osh.obj_name_data, 0x20); s_mosd.write_offset_f2(osh.obj_id_data, 0x20); s_mosd.write_offset_f2(osh.tex_id_data, 0x20); - s_mosd.write_int32_t(os->tex_id_num); - s_mosd.write_uint32_t(os->reserved[0]); - s_mosd.write_uint32_t(os->reserved[1]); + s_mosd.write_int32_t_reverse_endianness(os->tex_id_num); + s_mosd.write_uint32_t_reverse_endianness(os->reserved[0]); + s_mosd.write_uint32_t_reverse_endianness(os->reserved[1]); } else { - s_mosd.write_uint32_t(0x05062501); - s_mosd.write_int32_t(os->obj_num); - s_mosd.write_int32_t(-1); + s_mosd.write_uint32_t_reverse_endianness(0x05062501); + s_mosd.write_int32_t_reverse_endianness(os->obj_num); + s_mosd.write_int32_t_reverse_endianness(-1); s_mosd.write_offset_x(osh.obj_data); s_mosd.write_offset_x(osh.obj_skin_data); s_mosd.write_offset_x(osh.obj_name_data); s_mosd.write_offset_x(osh.obj_id_data); s_mosd.write_offset_x(osh.tex_id_data); - s_mosd.write_int32_t(os->tex_id_num); - s_mosd.write_uint32_t(os->reserved[0]); - s_mosd.write_uint32_t(os->reserved[1]); + s_mosd.write_int32_t_reverse_endianness(os->tex_id_num); + s_mosd.write_uint32_t_reverse_endianness(os->reserved[0]); + s_mosd.write_uint32_t_reverse_endianness(os->reserved[1]); } s_mosd.position_pop(); @@ -3688,15 +3663,17 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { st.sub_structs.push_back({}); f2_struct* omdl = &st.sub_structs.back(); - stream s_omdl; + memory_stream s_omdl; s_omdl.open(); + s_omdl.big_endian = big_endian; if (obj->skin_init) { st.sub_structs.push_back({}); f2_struct* oskn = &st.sub_structs.back(); - stream s_oskn; + memory_stream s_oskn; s_oskn.open(); + s_oskn.big_endian = big_endian; obj_modern_write_skin(obj, s_oskn, 0, is_x, oskn); @@ -3706,7 +3683,7 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { oskn->header.signature = reverse_endianness_uint32_t('OSKN'); oskn->header.length = 0x20; - oskn->header.use_big_endian = false; + oskn->header.use_big_endian = big_endian; oskn->header.use_section_size = true; } @@ -3718,7 +3695,7 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { omdl->header.signature = reverse_endianness_uint32_t('OMDL'); omdl->header.length = 0x20; - omdl->header.use_big_endian = false; + omdl->header.use_big_endian = big_endian; omdl->header.use_section_size = true; } @@ -3731,7 +3708,7 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { st.header.signature = reverse_endianness_uint32_t('MOSD'); st.header.length = 0x20; - st.header.use_big_endian = false; + st.header.use_big_endian = big_endian; st.header.use_section_size = true; st.write(s, true, os->is_x); @@ -3808,11 +3785,11 @@ static void obj_modern_write_index(obj* obj, stream& s, bool is_x, break; case OBJ_INDEX_U16: for (uint32_t i = 0; i < _indices_count; i++) - s.write_uint16_t((uint16_t)indices[i]); + s.write_uint16_t_reverse_endianness((uint16_t)indices[i]); break; case OBJ_INDEX_U32: for (uint32_t i = 0; i < _indices_count; i++) - s.write_uint32_t(indices[i]); + s.write_uint32_t_reverse_endianness(indices[i]); break; } s.align_write(0x04); @@ -3951,7 +3928,7 @@ static void obj_modern_read_model(obj* obj, stream& s, int64_t base_offset, sub_mesh->bone_indices = force_malloc_s(uint16_t, sub_mesh->bone_indices_count); s.set_position(base_offset + smh.bone_indices_offset, SEEK_SET); s.read(sub_mesh->bone_indices, sub_mesh->bone_indices_count * sizeof(uint16_t)); - if (s.is_big_endian) { + if (s.big_endian) { uint16_t* bone_indices = sub_mesh->bone_indices; for (uint32_t k = 0; k < sub_mesh->bone_indices_count; k++) bone_indices[k] = reverse_endianness_uint16_t(bone_indices[k]); @@ -3978,7 +3955,7 @@ static void obj_modern_read_model(obj* obj, stream& s, int64_t base_offset, obj_material_data mat_data; s.read(&mat_data, sizeof(obj_material_data)); - if (s.is_big_endian) + if (s.big_endian) obj_material_texture_enrs_table.apply(&mat_data); for (obj_material_texture_data& j : mat_data.material.texdata) @@ -3990,6 +3967,8 @@ static void obj_modern_read_model(obj* obj, stream& s, int64_t base_offset, static void obj_modern_write_model(obj* obj, stream& s, int64_t base_offset, bool is_x, f2_struct* omdl) { + bool big_endian = s.big_endian; + const size_t mesh_size = is_x ? 0x130 : 0xD8; const size_t sub_mesh_size = is_x ? 0x80 : 0x70; @@ -3998,10 +3977,12 @@ static void obj_modern_write_model(obj* obj, stream& s, f2_struct* oidx = &omdl->sub_structs.end()[-2]; f2_struct* ovtx = &omdl->sub_structs.back(); - stream s_oidx; - stream s_ovtx; + memory_stream s_oidx; + memory_stream s_ovtx; s_oidx.open(); s_ovtx.open(); + s_oidx.big_endian = big_endian; + s_ovtx.big_endian = big_endian; uint32_t off; enrs e; @@ -4277,28 +4258,28 @@ static void obj_modern_write_model(obj* obj, stream& s, obj_sub_mesh* sub_mesh = &mesh->submesh_array[j]; obj_sub_mesh_header* smh = &smhs[j]; - s.write_uint32_t(sub_mesh->flags); - s.write_float_t(sub_mesh->bounding_sphere.center.x); - s.write_float_t(sub_mesh->bounding_sphere.center.y); - s.write_float_t(sub_mesh->bounding_sphere.center.z); - s.write_float_t(sub_mesh->bounding_sphere.radius); - s.write_uint32_t(sub_mesh->material_index); + s.write_uint32_t_reverse_endianness(sub_mesh->flags); + s.write_float_t_reverse_endianness(sub_mesh->bounding_sphere.center.x); + s.write_float_t_reverse_endianness(sub_mesh->bounding_sphere.center.y); + s.write_float_t_reverse_endianness(sub_mesh->bounding_sphere.center.z); + s.write_float_t_reverse_endianness(sub_mesh->bounding_sphere.radius); + s.write_uint32_t_reverse_endianness(sub_mesh->material_index); s.write(&sub_mesh->uv_index, 0x08); - s.write_int32_t(sub_mesh->bone_indices_count); + s.write_int32_t_reverse_endianness(sub_mesh->bone_indices_count); s.write_offset(smh->bone_indices_offset, 0x20, is_x); - s.write_uint32_t(sub_mesh->bones_per_vertex); - s.write_uint32_t(sub_mesh->primitive_type); - s.write_uint32_t(sub_mesh->index_format); - s.write_int32_t(sub_mesh->indices_count); + s.write_uint32_t_reverse_endianness(sub_mesh->bones_per_vertex); + s.write_uint32_t_reverse_endianness(sub_mesh->primitive_type); + s.write_uint32_t_reverse_endianness(sub_mesh->index_format); + s.write_int32_t_reverse_endianness(sub_mesh->indices_count); s.write_offset(smh->indices_offset, 0, is_x); - s.write_uint32_t(sub_mesh->attrib.w); + s.write_uint32_t_reverse_endianness(sub_mesh->attrib.w); s.write(0x10); - s.write_float_t(sub_mesh->bounding_box.center.x); - s.write_float_t(sub_mesh->bounding_box.center.y); - s.write_float_t(sub_mesh->bounding_box.center.z); - s.write_float_t(sub_mesh->bounding_box.size.x); - s.write_float_t(sub_mesh->bounding_box.size.y); - s.write_float_t(sub_mesh->bounding_box.size.z); + s.write_float_t_reverse_endianness(sub_mesh->bounding_box.center.x); + s.write_float_t_reverse_endianness(sub_mesh->bounding_box.center.y); + s.write_float_t_reverse_endianness(sub_mesh->bounding_box.center.z); + s.write_float_t_reverse_endianness(sub_mesh->bounding_box.size.x); + s.write_float_t_reverse_endianness(sub_mesh->bounding_box.size.y); + s.write_float_t_reverse_endianness(sub_mesh->bounding_box.size.z); uint32_t index_max = 0; for (uint32_t k = 0; k < sub_mesh->indices_count; k++) @@ -4307,23 +4288,23 @@ static void obj_modern_write_model(obj* obj, stream& s, switch (sub_mesh->index_format) { case OBJ_INDEX_U8: - s.write_uint32_t(index_max << 24); + s.write_uint32_t_reverse_endianness(index_max << 24); break; case OBJ_INDEX_U16: - s.write_uint32_t(index_max << 16); + s.write_uint32_t_reverse_endianness(index_max << 16); break; case OBJ_INDEX_U32: - s.write_uint32_t(index_max); + s.write_uint32_t_reverse_endianness(index_max); break; } - s.write_uint32_t(sub_mesh->indices_offset); + s.write_uint32_t_reverse_endianness(sub_mesh->indices_offset); if (is_x) s.write(0x04); } s.position_pop(); } - free(smhs); + free_def(smhs); } s.position_push(base_offset + oh.mesh_array, SEEK_SET); @@ -4331,18 +4312,18 @@ static void obj_modern_write_model(obj* obj, stream& s, obj_mesh* mesh = &obj->mesh_array[i]; obj_mesh_header* mh = &mhs[i]; - s.write_uint32_t(mesh->flags); - s.write_float_t(mesh->bounding_sphere.center.x); - s.write_float_t(mesh->bounding_sphere.center.y); - s.write_float_t(mesh->bounding_sphere.center.z); - s.write_float_t(mesh->bounding_sphere.radius); - s.write_int32_t(mesh->num_submesh); + s.write_uint32_t_reverse_endianness(mesh->flags); + s.write_float_t_reverse_endianness(mesh->bounding_sphere.center.x); + s.write_float_t_reverse_endianness(mesh->bounding_sphere.center.y); + s.write_float_t_reverse_endianness(mesh->bounding_sphere.center.z); + s.write_float_t_reverse_endianness(mesh->bounding_sphere.radius); + s.write_int32_t_reverse_endianness(mesh->num_submesh); if (mh->submesh_array && !is_x) mh->submesh_array += 0x20; s.write_offset(mh->submesh_array, 0, is_x); - s.write_uint32_t(mh->format); - s.write_int32_t(mh->size_vertex); - s.write_int32_t(mh->num_vertex); + s.write_uint32_t_reverse_endianness(mh->format); + s.write_int32_t_reverse_endianness(mh->size_vertex); + s.write_int32_t_reverse_endianness(mh->num_vertex); if (!is_x) for (uint32_t j = 0; j < 20; j++) @@ -4351,20 +4332,20 @@ static void obj_modern_write_model(obj* obj, stream& s, for (uint32_t j = 0; j < 20; j++) s.write_offset_x(mh->vertex[j]); - s.write_uint32_t(mesh->attrib.w); - s.write_uint32_t(mh->vertex_flags); - s.write_uint32_t(mesh->reserved[0]); - s.write_uint32_t(mesh->reserved[1]); - s.write_uint32_t(mesh->reserved[2]); - s.write_uint32_t(mesh->reserved[3]); - s.write_uint32_t(mesh->reserved[4]); - s.write_uint32_t(mesh->reserved[5]); + s.write_uint32_t_reverse_endianness(mesh->attrib.w); + s.write_uint32_t_reverse_endianness(mh->vertex_flags); + s.write_uint32_t_reverse_endianness(mesh->reserved[0]); + s.write_uint32_t_reverse_endianness(mesh->reserved[1]); + s.write_uint32_t_reverse_endianness(mesh->reserved[2]); + s.write_uint32_t_reverse_endianness(mesh->reserved[3]); + s.write_uint32_t_reverse_endianness(mesh->reserved[4]); + s.write_uint32_t_reverse_endianness(mesh->reserved[5]); s.write(&mesh->name, sizeof(mesh->name) - 1); s.write_char('\0'); } s.position_pop(); - free(mhs); - free(smhss); + free_def(mhs); + free_def(smhss); } if (obj->material_array) { @@ -4380,51 +4361,51 @@ static void obj_modern_write_model(obj* obj, stream& s, s.position_push(base_offset, SEEK_SET); if (!is_x) { - s.write_uint32_t(0x10000); // version - s.write_uint32_t(0x00); // flags - s.write_float_t(obj->bounding_sphere.center.x); - s.write_float_t(obj->bounding_sphere.center.y); - s.write_float_t(obj->bounding_sphere.center.z); - s.write_float_t(obj->bounding_sphere.radius); - s.write_int32_t(obj->num_mesh); + s.write_uint32_t_reverse_endianness(0x10000); // version + s.write_uint32_t_reverse_endianness(0x00); // flags + s.write_float_t_reverse_endianness(obj->bounding_sphere.center.x); + s.write_float_t_reverse_endianness(obj->bounding_sphere.center.y); + s.write_float_t_reverse_endianness(obj->bounding_sphere.center.z); + s.write_float_t_reverse_endianness(obj->bounding_sphere.radius); + s.write_int32_t_reverse_endianness(obj->num_mesh); s.write_offset_f2(oh.mesh_array, 0x20); - s.write_int32_t(obj->num_material); + s.write_int32_t_reverse_endianness(obj->num_material); s.write_offset_f2(oh.material_array, 0x20); - s.write_uint32_t(obj->reserved[0]); - s.write_uint32_t(obj->reserved[1]); - s.write_uint32_t(obj->reserved[2]); - s.write_uint32_t(obj->reserved[3]); - s.write_uint32_t(obj->reserved[4]); - s.write_uint32_t(obj->reserved[5]); - s.write_uint32_t(obj->reserved[6]); - s.write_uint32_t(obj->reserved[7]); - s.write_uint32_t(obj->reserved[8]); - s.write_uint32_t(obj->reserved[9]); + s.write_uint32_t_reverse_endianness(obj->reserved[0]); + s.write_uint32_t_reverse_endianness(obj->reserved[1]); + s.write_uint32_t_reverse_endianness(obj->reserved[2]); + s.write_uint32_t_reverse_endianness(obj->reserved[3]); + s.write_uint32_t_reverse_endianness(obj->reserved[4]); + s.write_uint32_t_reverse_endianness(obj->reserved[5]); + s.write_uint32_t_reverse_endianness(obj->reserved[6]); + s.write_uint32_t_reverse_endianness(obj->reserved[7]); + s.write_uint32_t_reverse_endianness(obj->reserved[8]); + s.write_uint32_t_reverse_endianness(obj->reserved[9]); } else { - s.write_uint32_t(0x10000); // version - s.write_uint32_t(0x00); // flags - s.write_int32_t(obj->num_mesh); - s.write_int32_t(obj->num_material); - s.write_float_t(obj->bounding_sphere.center.x); - s.write_float_t(obj->bounding_sphere.center.y); - s.write_float_t(obj->bounding_sphere.center.z); - s.write_float_t(obj->bounding_sphere.radius); + s.write_uint32_t_reverse_endianness(0x10000); // version + s.write_uint32_t_reverse_endianness(0x00); // flags + s.write_int32_t_reverse_endianness(obj->num_mesh); + s.write_int32_t_reverse_endianness(obj->num_material); + s.write_float_t_reverse_endianness(obj->bounding_sphere.center.x); + s.write_float_t_reverse_endianness(obj->bounding_sphere.center.y); + s.write_float_t_reverse_endianness(obj->bounding_sphere.center.z); + s.write_float_t_reverse_endianness(obj->bounding_sphere.radius); s.write_offset_x(oh.mesh_array); s.write_offset_x(oh.material_array); s.write(0x10); s.write_uint8_t(obj->flags); s.write(0x07); - s.write_uint32_t(obj->reserved[0]); - s.write_uint32_t(obj->reserved[1]); - s.write_uint32_t(obj->reserved[2]); - s.write_uint32_t(obj->reserved[3]); - s.write_uint32_t(obj->reserved[4]); - s.write_uint32_t(obj->reserved[5]); - s.write_uint32_t(obj->reserved[6]); - s.write_uint32_t(obj->reserved[7]); - s.write_uint32_t(obj->reserved[8]); - s.write_uint32_t(obj->reserved[9]); + s.write_uint32_t_reverse_endianness(obj->reserved[0]); + s.write_uint32_t_reverse_endianness(obj->reserved[1]); + s.write_uint32_t_reverse_endianness(obj->reserved[2]); + s.write_uint32_t_reverse_endianness(obj->reserved[3]); + s.write_uint32_t_reverse_endianness(obj->reserved[4]); + s.write_uint32_t_reverse_endianness(obj->reserved[5]); + s.write_uint32_t_reverse_endianness(obj->reserved[6]); + s.write_uint32_t_reverse_endianness(obj->reserved[7]); + s.write_uint32_t_reverse_endianness(obj->reserved[8]); + s.write_uint32_t_reverse_endianness(obj->reserved[9]); } s.position_pop(); @@ -4437,7 +4418,7 @@ static void obj_modern_write_model(obj* obj, stream& s, oidx->header.signature = reverse_endianness_uint32_t('OIDX'); oidx->header.length = 0x20; - oidx->header.use_big_endian = false; + oidx->header.use_big_endian = big_endian; oidx->header.use_section_size = true; s_ovtx.align_write(0x10); @@ -4446,7 +4427,7 @@ static void obj_modern_write_model(obj* obj, stream& s, ovtx->header.signature = reverse_endianness_uint32_t('OVTX'); ovtx->header.length = 0x20; - ovtx->header.use_big_endian = false; + ovtx->header.use_big_endian = big_endian; ovtx->header.use_section_size = true; } @@ -4530,7 +4511,7 @@ static void obj_modern_read_skin(obj* obj, stream& s, int64_t base_offset, sk->bones[i].parent = s.read_uint32_t_reverse_endianness(); } } - free(bone_names_offsets); + free_def(bone_names_offsets); } if (sh.ex_data_offset) { @@ -4595,7 +4576,7 @@ static void obj_modern_read_skin(obj* obj, stream& s, int64_t base_offset, bone_names.push_back({}); buf_size += bone_names.back().size() + 1; } - free(strings_offsets); + free_def(strings_offsets); if (bone_names.size()) { ex->bone_names_buf = force_malloc_s(char, buf_size); @@ -4709,7 +4690,7 @@ static void obj_modern_read_skin(obj* obj, stream& s, int64_t base_offset, break; } } - free(bhs); + free_def(bhs); } if (exh.osage_sibling_infos_offset) { @@ -4803,9 +4784,9 @@ static void obj_modern_write_skin(obj* obj, stream& s, off = align_val(off, 0x10); } - std::vector strings; + std::vector strings; std::vector string_offsets; - std::vector bone_names; + std::vector bone_names; obj_skin_ex_data_header exh = {}; @@ -5332,12 +5313,12 @@ static void obj_modern_write_skin(obj* obj, stream& s, if (sk->bones_count) { sh.bone_ids_offset = s.get_position(); for (uint32_t i = 0; i < sk->bones_count; i++) - s.write_int32_t(sk->bones[i].id); + s.write_int32_t_reverse_endianness(sk->bones[i].id); s.align_write(0x10); sh.bone_parent_ids_offset = s.get_position(); for (uint32_t i = 0; i < sk->bones_count; i++) - s.write_int32_t(sk->bones[i].parent); + s.write_int32_t_reverse_endianness(sk->bones[i].parent); s.align_write(0x10); sh.bone_names_offset = s.get_position(); @@ -5356,22 +5337,22 @@ static void obj_modern_write_skin(obj* obj, stream& s, sh.bone_matrices_offset = s.get_position(); for (uint32_t i = 0; i < sk->bones_count; i++) { mat4& mat = sk->bones[i].inv_bind_pose_mat; - s.write_float_t(mat.row0.x); - s.write_float_t(mat.row1.x); - s.write_float_t(mat.row2.x); - s.write_float_t(mat.row3.x); - s.write_float_t(mat.row0.y); - s.write_float_t(mat.row1.y); - s.write_float_t(mat.row2.y); - s.write_float_t(mat.row3.y); - s.write_float_t(mat.row0.z); - s.write_float_t(mat.row1.z); - s.write_float_t(mat.row2.z); - s.write_float_t(mat.row3.z); - s.write_float_t(mat.row0.w); - s.write_float_t(mat.row1.w); - s.write_float_t(mat.row2.w); - s.write_float_t(mat.row3.w); + s.write_float_t_reverse_endianness(mat.row0.x); + s.write_float_t_reverse_endianness(mat.row1.x); + s.write_float_t_reverse_endianness(mat.row2.x); + s.write_float_t_reverse_endianness(mat.row3.x); + s.write_float_t_reverse_endianness(mat.row0.y); + s.write_float_t_reverse_endianness(mat.row1.y); + s.write_float_t_reverse_endianness(mat.row2.y); + s.write_float_t_reverse_endianness(mat.row3.y); + s.write_float_t_reverse_endianness(mat.row0.z); + s.write_float_t_reverse_endianness(mat.row1.z); + s.write_float_t_reverse_endianness(mat.row2.z); + s.write_float_t_reverse_endianness(mat.row3.z); + s.write_float_t_reverse_endianness(mat.row0.w); + s.write_float_t_reverse_endianness(mat.row1.w); + s.write_float_t_reverse_endianness(mat.row2.w); + s.write_float_t_reverse_endianness(mat.row3.w); } s.align_write(0x10); } @@ -5462,10 +5443,10 @@ static void obj_modern_write_skin(obj* obj, stream& s, exh.bone_names_offset = s.get_position(); if (!is_x) - for (std::string& i : bone_names) + for (string_hash& i : bone_names) io_write_offset_f2_pof_add(s, 0, 0x20, &pof); else - for (std::string& i : bone_names) + for (string_hash& i : bone_names) io_write_offset_x_pof_add(s, 0, &pof); s.align_write(0x10); @@ -5844,16 +5825,16 @@ static void obj_modern_write_skin(obj* obj, stream& s, } if (sk->bones || sk->ex_data_init) { - quicksort_string(strings.data(), strings.size()); + quicksort_string_hash(strings.data(), strings.size()); string_offsets.reserve(strings.size()); - for (std::string& i : strings) { + for (string_hash& i : strings) { string_offsets.push_back(s.get_position()); - s.write_string_null_terminated(i); + s.write_string_null_terminated(i.str); } } s.align_write(0x10); - std::vector osage_names; + std::vector osage_names; if (sk->ex_data_init) { obj_skin_ex_data* ex = &sk->ex_data; @@ -6013,7 +5994,7 @@ static void obj_modern_write_skin(obj* obj, stream& s, s.write_offset_x(0); } s.position_pop(); - free(bhs); + free_def(bhs); } } @@ -6040,13 +6021,13 @@ static void obj_modern_write_skin(obj* obj, stream& s, if (ex->blocks_count > 0) { s.position_push(exh.bone_names_offset, SEEK_SET); if (!is_x) - for (std::string& i : bone_names) { + for (string_hash& i : bone_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); s.write_offset_f2(str_offset, 0x20); } else - for (std::string& i : bone_names) { + for (string_hash& i : bone_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); s.write_offset_x(str_offset); @@ -6056,18 +6037,18 @@ static void obj_modern_write_skin(obj* obj, stream& s, s.position_push(exh.osage_nodes_offset, SEEK_SET); for (uint32_t i = 0; i < ex->osage_nodes_count; i++) { obj_skin_osage_node* osage_node = &ex->osage_nodes[i]; - s.write_uint32_t(osage_node->name_index); - s.write_float_t(osage_node->length); - s.write_uint32_t(0); + s.write_uint32_t_reverse_endianness(osage_node->name_index); + s.write_float_t_reverse_endianness(osage_node->length); + s.write_uint32_t_reverse_endianness(0); } s.position_pop(); s.position_push(exh.osage_sibling_infos_offset, SEEK_SET); for (uint32_t i = 0; i < ex->osage_sibling_infos_count; i++) { obj_skin_osage_sibling_info* osage_sibling_info = &ex->osage_sibling_infos[i]; - s.write_uint32_t(osage_sibling_info->name_index); - s.write_uint32_t(osage_sibling_info->sibling_name_index); - s.write_float_t(osage_sibling_info->max_distance); + s.write_uint32_t_reverse_endianness(osage_sibling_info->name_index); + s.write_uint32_t_reverse_endianness(osage_sibling_info->sibling_name_index); + s.write_float_t_reverse_endianness(osage_sibling_info->max_distance); } s.write_int32_t(0); s.write_int32_t(0); @@ -6078,13 +6059,13 @@ static void obj_modern_write_skin(obj* obj, stream& s, exh.osage_count -= exh.cloth_count; s.position_push(exh.osage_names_offset, SEEK_SET); if (!is_x) - for (std::string& i : osage_names) { + for (string_hash& i : osage_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); s.write_offset_f2(str_offset, 0x20); } else - for (std::string& i : osage_names) { + for (string_hash& i : osage_names) { size_t str_offset = obj_skin_strings_get_string_offset(strings, string_offsets, i.c_str()); s.write_offset_x(str_offset); @@ -6094,16 +6075,16 @@ static void obj_modern_write_skin(obj* obj, stream& s, s.position_push(sh.ex_data_offset, SEEK_SET); if (!is_x) { - s.write_int32_t(exh.osage_count); - s.write_int32_t(ex->osage_nodes_count); + s.write_int32_t_reverse_endianness(exh.osage_count); + s.write_int32_t_reverse_endianness(ex->osage_nodes_count); s.write(0x04); s.write_offset_f2(exh.osage_nodes_offset, 0x20); s.write_offset_f2(exh.osage_names_offset, 0x20); s.write_offset_f2(exh.blocks_offset, 0x20); - s.write_int32_t(exh.bone_names_count); + s.write_int32_t_reverse_endianness(exh.bone_names_count); s.write_offset_f2(exh.bone_names_offset, 0x20); s.write_offset_f2(exh.osage_sibling_infos_offset, 0x20); - s.write_int32_t(exh.cloth_count); + s.write_int32_t_reverse_endianness(exh.cloth_count); s.write_offset_f2(ex->reserved[0], 0x20); s.write_offset_f2(ex->reserved[1], 0x20); s.write_offset_f2(ex->reserved[2], 0x20); @@ -6113,16 +6094,16 @@ static void obj_modern_write_skin(obj* obj, stream& s, s.write_offset_f2(ex->reserved[6], 0x20); } else { - s.write_int32_t(exh.osage_count); - s.write_int32_t(ex->osage_nodes_count); + s.write_int32_t_reverse_endianness(exh.osage_count); + s.write_int32_t_reverse_endianness(ex->osage_nodes_count); s.write(0x08); s.write_offset_x(exh.osage_nodes_offset); s.write_offset_x(exh.osage_names_offset); s.write_offset_x(exh.blocks_offset); - s.write_int32_t(exh.bone_names_count); + s.write_int32_t_reverse_endianness(exh.bone_names_count); s.write_offset_x(exh.bone_names_offset); s.write_offset_x(exh.osage_sibling_infos_offset); - s.write_int32_t(exh.cloth_count); + s.write_int32_t_reverse_endianness(exh.cloth_count); s.write_offset_x(ex->reserved[0]); s.write_offset_x(ex->reserved[1]); s.write_offset_x(ex->reserved[2]); @@ -6140,7 +6121,7 @@ static void obj_modern_write_skin(obj* obj, stream& s, s.write_offset_f2(sh.bone_matrices_offset, 0x20); s.write_offset_f2(sh.bone_names_offset, 0x20); s.write_offset_f2(sh.ex_data_offset, 0x20); - s.write_int32_t(sk->bones_count); + s.write_int32_t_reverse_endianness(sk->bones_count); s.write_offset_f2(sh.bone_parent_ids_offset, 0x20); s.write(0x0C); } @@ -6149,7 +6130,7 @@ static void obj_modern_write_skin(obj* obj, stream& s, s.write_offset_x(sh.bone_matrices_offset); s.write_offset_x(sh.bone_names_offset); s.write_offset_x(sh.ex_data_offset); - s.write_int32_t(sk->bones_count); + s.write_int32_t_reverse_endianness(sk->bones_count); s.write_offset_x(sh.bone_parent_ids_offset); s.write(0x18); } @@ -6274,7 +6255,7 @@ static void obj_modern_read_skin_block_cloth(obj_skin_block_cloth* b, b->mesh_indices_count = s.read_uint16_t_reverse_endianness(); b->mesh_indices = force_malloc_s(uint16_t, b->mesh_indices_count); s.read(b->mesh_indices, b->mesh_indices_count * sizeof(uint16_t)); - if (s.is_big_endian) { + if (s.big_endian) { uint16_t* mesh_indices = b->mesh_indices; for (int32_t i = 0; i < b->mesh_indices_count; i++) mesh_indices[i] = reverse_endianness_uint16_t(mesh_indices[i]); @@ -6287,7 +6268,7 @@ static void obj_modern_read_skin_block_cloth(obj_skin_block_cloth* b, b->backface_mesh_indices_count = s.read_uint16_t_reverse_endianness(); b->backface_mesh_indices = force_malloc_s(uint16_t, b->backface_mesh_indices_count); s.read(b->backface_mesh_indices, b->backface_mesh_indices_count * sizeof(uint16_t)); - if (s.is_big_endian) { + if (s.big_endian) { uint16_t* backface_mesh_indices = b->backface_mesh_indices; for (int32_t i = 0; i < b->backface_mesh_indices_count; i++) backface_mesh_indices[i] = reverse_endianness_uint16_t(backface_mesh_indices[i]); @@ -6298,7 +6279,7 @@ static void obj_modern_read_skin_block_cloth(obj_skin_block_cloth* b, } static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, int64_t* mats_offset, int64_t* root_offset, int64_t* nodes_offset, int64_t* mesh_indices_offset, int64_t* backface_mesh_indices_offset) { int64_t mesh_name_offset = obj_skin_strings_get_string_offset(strings, @@ -6309,54 +6290,54 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* b, if (!is_x) { s.write_offset_f2(mesh_name_offset, 0x20); s.write_offset_f2(backface_mesh_name_offset, 0x20); - s.write_int32_t(b->field_8); - s.write_int32_t(b->root_count); - s.write_int32_t(b->nodes_count); - s.write_int32_t(b->field_14); + s.write_int32_t_reverse_endianness(b->field_8); + s.write_int32_t_reverse_endianness(b->root_count); + s.write_int32_t_reverse_endianness(b->nodes_count); + s.write_int32_t_reverse_endianness(b->field_14); s.write_offset_f2(b->nodes_count ? *mats_offset : 0, 0x20); s.write_offset_f2(b->root ? *root_offset : 0, 0x20); s.write_offset_f2(b->nodes ? *nodes_offset : 0, 0x20); s.write_offset_f2(b->mesh_indices ? *mesh_indices_offset : 0, 0x20); s.write_offset_f2(b->backface_mesh_indices ? *backface_mesh_indices_offset : 0, 0x20); - s.write_uint32_t(0); - s.write_uint32_t(b->reserved); + s.write_uint32_t_reverse_endianness(0); + s.write_uint32_t_reverse_endianness(b->reserved); } else { s.write_offset_x(mesh_name_offset); s.write_offset_x(backface_mesh_name_offset); - s.write_int32_t(b->field_8); - s.write_int32_t(b->root_count); - s.write_int32_t(b->nodes_count); - s.write_int32_t(b->field_14); + s.write_int32_t_reverse_endianness(b->field_8); + s.write_int32_t_reverse_endianness(b->root_count); + s.write_int32_t_reverse_endianness(b->nodes_count); + s.write_int32_t_reverse_endianness(b->field_14); s.write_offset_x(b->nodes_count ? *mats_offset : 0); s.write_offset_x(b->root ? *root_offset : 0); s.write_offset_x(b->nodes ? *nodes_offset : 0); s.write_offset_x(b->mesh_indices ? *mesh_indices_offset : 0); s.write_offset_x(b->backface_mesh_indices ? *backface_mesh_indices_offset : 0); - s.write_uint32_t(0); - s.write_uint32_t(b->reserved); + s.write_uint32_t_reverse_endianness(0); + s.write_uint32_t_reverse_endianness(b->reserved); } if (b->mats) { s.position_push(*mats_offset, SEEK_SET); for (uint32_t i = 0; i < b->mats_count; i++) { mat4& mat = b->mats[i]; - s.write_float_t(mat.row0.x); - s.write_float_t(mat.row1.x); - s.write_float_t(mat.row2.x); - s.write_float_t(mat.row3.x); - s.write_float_t(mat.row0.y); - s.write_float_t(mat.row1.y); - s.write_float_t(mat.row2.y); - s.write_float_t(mat.row3.y); - s.write_float_t(mat.row0.z); - s.write_float_t(mat.row1.z); - s.write_float_t(mat.row2.z); - s.write_float_t(mat.row3.z); - s.write_float_t(mat.row0.w); - s.write_float_t(mat.row1.w); - s.write_float_t(mat.row2.w); - s.write_float_t(mat.row3.w); + s.write_float_t_reverse_endianness(mat.row0.x); + s.write_float_t_reverse_endianness(mat.row1.x); + s.write_float_t_reverse_endianness(mat.row2.x); + s.write_float_t_reverse_endianness(mat.row3.x); + s.write_float_t_reverse_endianness(mat.row0.y); + s.write_float_t_reverse_endianness(mat.row1.y); + s.write_float_t_reverse_endianness(mat.row2.y); + s.write_float_t_reverse_endianness(mat.row3.y); + s.write_float_t_reverse_endianness(mat.row0.z); + s.write_float_t_reverse_endianness(mat.row1.z); + s.write_float_t_reverse_endianness(mat.row2.z); + s.write_float_t_reverse_endianness(mat.row3.z); + s.write_float_t_reverse_endianness(mat.row0.w); + s.write_float_t_reverse_endianness(mat.row1.w); + s.write_float_t_reverse_endianness(mat.row2.w); + s.write_float_t_reverse_endianness(mat.row3.w); *mats_offset += sizeof(mat4); } s.position_pop(); @@ -6366,16 +6347,16 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* b, s.position_push(*root_offset, SEEK_SET); for (uint32_t i = 0; i < b->root_count; i++) { obj_skin_block_cloth_root* f = &b->root[i]; - s.write_float_t(f->trans.x); - s.write_float_t(f->trans.y); - s.write_float_t(f->trans.z); - s.write_float_t(f->normal.x); - s.write_float_t(f->normal.y); - s.write_float_t(f->normal.z); - s.write_float_t(f->field_18); - s.write_int32_t(f->field_1C); - s.write_int32_t(f->field_20); - s.write_int32_t(f->field_24); + s.write_float_t_reverse_endianness(f->trans.x); + s.write_float_t_reverse_endianness(f->trans.y); + s.write_float_t_reverse_endianness(f->trans.z); + s.write_float_t_reverse_endianness(f->normal.x); + s.write_float_t_reverse_endianness(f->normal.y); + s.write_float_t_reverse_endianness(f->normal.z); + s.write_float_t_reverse_endianness(f->field_18); + s.write_int32_t_reverse_endianness(f->field_1C); + s.write_int32_t_reverse_endianness(f->field_20); + s.write_int32_t_reverse_endianness(f->field_24); for (uint32_t j = 0; j < 4; j++) obj_modern_write_skin_block_cloth_root_bone_weight(&f->bone_weights[j], @@ -6395,17 +6376,17 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* b, for (uint32_t i = 0; i < b->nodes_count - 1; i++) for (uint32_t j = 0; j < b->root_count; j++) { obj_skin_block_cloth_node* f = &b->nodes[i * b->root_count + j]; - s.write_uint32_t(f->flags); - s.write_float_t(f->trans.x); - s.write_float_t(f->trans.y); - s.write_float_t(f->trans.z); - s.write_float_t(f->trans_diff.x); - s.write_float_t(f->trans_diff.y); - s.write_float_t(f->trans_diff.z); - s.write_float_t(f->dist_top); - s.write_float_t(f->dist_bottom); - s.write_float_t(f->dist_right); - s.write_float_t(f->dist_left); + s.write_uint32_t_reverse_endianness(f->flags); + s.write_float_t_reverse_endianness(f->trans.x); + s.write_float_t_reverse_endianness(f->trans.y); + s.write_float_t_reverse_endianness(f->trans.z); + s.write_float_t_reverse_endianness(f->trans_diff.x); + s.write_float_t_reverse_endianness(f->trans_diff.y); + s.write_float_t_reverse_endianness(f->trans_diff.z); + s.write_float_t_reverse_endianness(f->dist_top); + s.write_float_t_reverse_endianness(f->dist_bottom); + s.write_float_t_reverse_endianness(f->dist_right); + s.write_float_t_reverse_endianness(f->dist_left); } s.position_pop(); *nodes_offset += (11 * sizeof(int32_t)) * b->root_count * (b->nodes_count - 1ULL); @@ -6413,16 +6394,18 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* b, if (b->mesh_indices) { s.position_push(*mesh_indices_offset, SEEK_SET); - s.write_uint16_t((uint16_t)b->mesh_indices_count); - s.write(b->mesh_indices, b->mesh_indices_count * sizeof(uint16_t)); + s.write_uint16_t_reverse_endianness((uint16_t)b->mesh_indices_count); + for (size_t i = 0; i < b->mesh_indices_count; i++) + s.write_uint16_t_reverse_endianness(b->mesh_indices[i]); s.position_pop(); *mesh_indices_offset += sizeof(uint16_t) + b->mesh_indices_count * sizeof(uint16_t); } if (b->backface_mesh_indices) { s.position_push(*backface_mesh_indices_offset, SEEK_SET); - s.write_uint16_t((uint16_t)b->backface_mesh_indices_count); - s.write(b->backface_mesh_indices, b->backface_mesh_indices_count * sizeof(uint16_t)); + s.write_uint16_t_reverse_endianness((uint16_t)b->backface_mesh_indices_count); + for (size_t i = 0; i < b->backface_mesh_indices_count; i++) + s.write_uint16_t_reverse_endianness(b->backface_mesh_indices[i]); s.position_pop(); *backface_mesh_indices_offset += sizeof(uint16_t) + b->backface_mesh_indices_count * sizeof(uint16_t); } @@ -6440,13 +6423,13 @@ static void obj_modern_read_skin_block_cloth_root_bone_weight(obj_skin_block_clo } static void obj_modern_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* sub, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { int64_t bone_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, sub->bone_name); s.write_offset(bone_name_offset, 0x20, is_x); - s.write_float_t(sub->weight); - s.write_uint32_t(sub->matrix_index); - s.write_uint32_t(sub->reserved); + s.write_float_t_reverse_endianness(sub->weight); + s.write_uint32_t_reverse_endianness(sub->matrix_index); + s.write_uint32_t_reverse_endianness(sub->reserved); if (is_x) s.write(0x04); } @@ -6467,7 +6450,7 @@ static void obj_modern_read_skin_block_constraint(obj_skin_block_constraint* b, b->name_index = 0x8000 | (int32_t)(i - str); break; } - free(name); + free_def(name); b->coupling = (obj_skin_block_constraint_coupling)s.read_int32_t_reverse_endianness(); @@ -6512,11 +6495,11 @@ static void obj_modern_read_skin_block_constraint(obj_skin_block_constraint* b, } else b->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; - free(type); + free_def(type); } static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, bool is_x, int64_t* offsets) { obj_modern_write_skin_block_node(&b->base, s, strings, string_offsets, is_x); @@ -6541,7 +6524,7 @@ static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* b, string_offsets, bone_names, b->name_index); s.write_offset(name_offset, 0x20, is_x); - s.write_int32_t(b->coupling); + s.write_int32_t_reverse_endianness(b->coupling); int64_t source_node_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, b->source_node_name); @@ -6549,19 +6532,19 @@ static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* b, switch (b->type) { case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: - s.write_float_t(b->orientation.offset.x); - s.write_float_t(b->orientation.offset.y); - s.write_float_t(b->orientation.offset.z); + s.write_float_t_reverse_endianness(b->orientation.offset.x); + s.write_float_t_reverse_endianness(b->orientation.offset.y); + s.write_float_t_reverse_endianness(b->orientation.offset.z); break; case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: obj_modern_write_skin_block_constraint_up_vector_old(&b->direction.up_vector, s, strings, string_offsets, is_x); - s.write_float_t(b->direction.align_axis.x); - s.write_float_t(b->direction.align_axis.y); - s.write_float_t(b->direction.align_axis.z); - s.write_float_t(b->direction.target_offset.x); - s.write_float_t(b->direction.target_offset.y); - s.write_float_t(b->direction.target_offset.z); + s.write_float_t_reverse_endianness(b->direction.align_axis.x); + s.write_float_t_reverse_endianness(b->direction.align_axis.y); + s.write_float_t_reverse_endianness(b->direction.align_axis.z); + s.write_float_t_reverse_endianness(b->direction.target_offset.x); + s.write_float_t_reverse_endianness(b->direction.target_offset.y); + s.write_float_t_reverse_endianness(b->direction.target_offset.z); break; case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: obj_modern_write_skin_block_constraint_up_vector_old(&b->position.up_vector, @@ -6574,7 +6557,7 @@ static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* b, case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: obj_modern_write_skin_block_constraint_up_vector_old(&b->distance.up_vector, s, strings, string_offsets, is_x); - s.write_float_t(b->distance.distance); + s.write_float_t_reverse_endianness(b->distance.distance); obj_modern_write_skin_block_constraint_attach_point(&b->distance.constrained_object, s, strings, string_offsets, is_x); obj_modern_write_skin_block_constraint_attach_point(&b->distance.constraining_object, @@ -6593,12 +6576,12 @@ static void obj_modern_read_skin_block_constraint_attach_point(obj_skin_block_co } static void obj_modern_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { - s.write_int32_t(ap->affected_by_orientation ? 1 : 0); - s.write_int32_t(ap->affected_by_scaling ? 1 : 0); - s.write_float_t(ap->offset.x); - s.write_float_t(ap->offset.y); - s.write_float_t(ap->offset.z); + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { + s.write_int32_t_reverse_endianness(ap->affected_by_orientation ? 1 : 0); + s.write_int32_t_reverse_endianness(ap->affected_by_scaling ? 1 : 0); + s.write_float_t_reverse_endianness(ap->offset.x); + s.write_float_t_reverse_endianness(ap->offset.y); + s.write_float_t_reverse_endianness(ap->offset.z); } static void obj_modern_read_skin_block_constraint_up_vector_old(obj_skin_block_constraint_up_vector* up, @@ -6617,15 +6600,15 @@ static void obj_modern_read_skin_block_constraint_up_vector_old(obj_skin_block_c } static void obj_modern_write_skin_block_constraint_up_vector_old(obj_skin_block_constraint_up_vector* up, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { - s.write_int32_t(up->active ? 1 : 0); - s.write_float_t(up->roll); - s.write_float_t(up->affected_axis.x); - s.write_float_t(up->affected_axis.y); - s.write_float_t(up->affected_axis.z); - s.write_float_t(up->point_at.x); - s.write_float_t(up->point_at.y); - s.write_float_t(up->point_at.z); + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { + s.write_int32_t_reverse_endianness(up->active ? 1 : 0); + s.write_float_t_reverse_endianness(up->roll); + s.write_float_t_reverse_endianness(up->affected_axis.x); + s.write_float_t_reverse_endianness(up->affected_axis.y); + s.write_float_t_reverse_endianness(up->affected_axis.z); + s.write_float_t_reverse_endianness(up->point_at.x); + s.write_float_t_reverse_endianness(up->point_at.y); + s.write_float_t_reverse_endianness(up->point_at.z); int64_t name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, up->name); @@ -6645,10 +6628,10 @@ static void obj_modern_read_skin_block_expression(obj_skin_block_expression* b, b->name_index = 0x8000 | (int32_t)(i - str); break; } - free(name); + free_def(name); b->expressions_count = s.read_int32_t_reverse_endianness(); - b->expressions_count = min(b->expressions_count, 9); + b->expressions_count = min_def(b->expressions_count, 9); if (!is_x) for (uint32_t i = 0; i < b->expressions_count; i++) { int64_t expression_offset = s.read_offset_f2(header_length); @@ -6667,14 +6650,14 @@ static void obj_modern_read_skin_block_expression(obj_skin_block_expression* b, } static void obj_modern_write_skin_block_expression(obj_skin_block_expression* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, bool is_x) { + stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, bool is_x) { obj_modern_write_skin_block_node(&b->base, s, strings, string_offsets, is_x); int64_t name_offset = obj_skin_strings_get_string_offset_by_index(strings, string_offsets, bone_names, b->name_index); s.write_offset(name_offset, 0x20, is_x); - s.write_int32_t(min(b->expressions_count, 9)); + s.write_int32_t_reverse_endianness(min_def(b->expressions_count, 9)); if (!is_x) { for (uint32_t i = 0; i < b->expressions_count && i < 9; i++) { int64_t expression_offset = obj_skin_strings_get_string_offset(strings, @@ -6714,7 +6697,7 @@ static void obj_modern_read_skin_block_motion(obj_skin_block_motion* b, b->name_index = 0x8000 | (int32_t)(i - str); break; } - free(name); + free_def(name); } else b->name = s.read_utf8_string_null_terminated_offset(name_offset); @@ -6759,7 +6742,7 @@ static void obj_modern_read_skin_block_motion(obj_skin_block_motion* b, } static void obj_modern_write_skin_block_motion(obj_skin_block_motion* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, char** bone_names, int64_t* bone_names_offset, int64_t* bone_matrices_offset) { obj_modern_write_skin_block_node(&b->base, s, strings, string_offsets, is_x); @@ -6771,36 +6754,36 @@ static void obj_modern_write_skin_block_motion(obj_skin_block_motion* b, name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, b->name); s.write_offset(name_offset, 0x20, is_x); - s.write_int32_t(b->nodes_count); + s.write_int32_t_reverse_endianness(b->nodes_count); s.write_offset(b->nodes ? *bone_names_offset : 0, 0x20, is_x); s.write_offset(b->nodes ? *bone_matrices_offset : 0, 0x20, is_x); if (b->nodes) { s.position_push(*bone_names_offset, SEEK_SET); for (uint32_t i = 0; i < b->nodes_count; i++) - s.write_uint32_t(b->nodes[i].name_index); + s.write_uint32_t_reverse_endianness(b->nodes[i].name_index); s.position_pop(); *bone_names_offset += b->nodes_count * sizeof(uint32_t); s.position_push(*bone_matrices_offset, SEEK_SET); for (uint32_t i = 0; i < b->nodes_count; i++) { mat4& mat = b->nodes[i].inv_bind_pose_mat; - s.write_float_t(mat.row0.x); - s.write_float_t(mat.row1.x); - s.write_float_t(mat.row2.x); - s.write_float_t(mat.row3.x); - s.write_float_t(mat.row0.y); - s.write_float_t(mat.row1.y); - s.write_float_t(mat.row2.y); - s.write_float_t(mat.row3.y); - s.write_float_t(mat.row0.z); - s.write_float_t(mat.row1.z); - s.write_float_t(mat.row2.z); - s.write_float_t(mat.row3.z); - s.write_float_t(mat.row0.w); - s.write_float_t(mat.row1.w); - s.write_float_t(mat.row2.w); - s.write_float_t(mat.row3.w); + s.write_float_t_reverse_endianness(mat.row0.x); + s.write_float_t_reverse_endianness(mat.row1.x); + s.write_float_t_reverse_endianness(mat.row2.x); + s.write_float_t_reverse_endianness(mat.row3.x); + s.write_float_t_reverse_endianness(mat.row0.y); + s.write_float_t_reverse_endianness(mat.row1.y); + s.write_float_t_reverse_endianness(mat.row2.y); + s.write_float_t_reverse_endianness(mat.row3.y); + s.write_float_t_reverse_endianness(mat.row0.z); + s.write_float_t_reverse_endianness(mat.row1.z); + s.write_float_t_reverse_endianness(mat.row2.z); + s.write_float_t_reverse_endianness(mat.row3.z); + s.write_float_t_reverse_endianness(mat.row0.w); + s.write_float_t_reverse_endianness(mat.row1.w); + s.write_float_t_reverse_endianness(mat.row2.w); + s.write_float_t_reverse_endianness(mat.row3.w); } s.position_pop(); *bone_matrices_offset += b->nodes_count * sizeof(mat4); @@ -6826,20 +6809,20 @@ static void obj_modern_read_skin_block_node(obj_skin_block_node* b, } static void obj_modern_write_skin_block_node(obj_skin_block_node* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { int64_t parent_name_offset = obj_skin_strings_get_string_offset(strings, string_offsets, b->parent_name); s.write_offset(parent_name_offset, 0x20, is_x); - s.write_float_t(b->position.x); - s.write_float_t(b->position.y); - s.write_float_t(b->position.z); - s.write_float_t(b->rotation.x); - s.write_float_t(b->rotation.y); - s.write_float_t(b->rotation.z); - s.write_float_t(b->scale.x); - s.write_float_t(b->scale.y); - s.write_float_t(b->scale.z); + s.write_float_t_reverse_endianness(b->position.x); + s.write_float_t_reverse_endianness(b->position.y); + s.write_float_t_reverse_endianness(b->position.z); + s.write_float_t_reverse_endianness(b->rotation.x); + s.write_float_t_reverse_endianness(b->rotation.y); + s.write_float_t_reverse_endianness(b->rotation.z); + s.write_float_t_reverse_endianness(b->scale.x); + s.write_float_t_reverse_endianness(b->scale.y); + s.write_float_t_reverse_endianness(b->scale.z); if (is_x) s.write(0x04); } @@ -6867,13 +6850,13 @@ static void obj_modern_read_skin_block_osage(obj_skin_block_osage* b, } static void obj_modern_write_skin_block_osage(obj_skin_block_osage* b, - stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { obj_modern_write_skin_block_node(&b->base, s, strings, string_offsets, is_x); - s.write_int32_t(b->start_index); - s.write_int32_t(b->count); - s.write_uint32_t(b->external_name_index); - s.write_uint32_t(b->name_index); + s.write_int32_t_reverse_endianness(b->start_index); + s.write_int32_t_reverse_endianness(b->count); + s.write_uint32_t_reverse_endianness(b->external_name_index); + s.write_uint32_t_reverse_endianness(b->name_index); if (!is_x) s.write(0x14); @@ -6920,15 +6903,14 @@ static void obj_modern_read_vertex(obj* obj, stream& s, int64_t* vertex, obj_mes normal.y = (float_t)s.read_int16_t_reverse_endianness(); normal.z = (float_t)s.read_int16_t_reverse_endianness(); s.read(0, 0x02); - vec3_div_min_max_scalar(normal, -32768.0f, 32767.0f, vtx[i].normal); + vtx[i].normal = vec3::div_min_max(normal, -32768.0f, 32767.0f); vec4 tangent; tangent.x = (float_t)s.read_int16_t_reverse_endianness(); tangent.y = (float_t)s.read_int16_t_reverse_endianness(); tangent.z = (float_t)s.read_int16_t_reverse_endianness(); tangent.w = (float_t)s.read_int16_t_reverse_endianness(); - vec4_div_min_max_scalar(tangent, -32768.0f, 32767.0f, tangent); - vtx[i].tangent = tangent; + vtx[i].tangent = vec4::div_min_max(tangent, -32768.0f, 32767.0f); vec2h texcoord0; texcoord0.x = s.read_half_t_reverse_endianness(); @@ -6971,7 +6953,7 @@ static void obj_modern_read_vertex(obj* obj, stream& s, int64_t* vertex, obj_mes bone_weight.y = (float_t)s.read_int16_t_reverse_endianness(); bone_weight.z = (float_t)s.read_int16_t_reverse_endianness(); bone_weight.w = (float_t)s.read_int16_t_reverse_endianness(); - vec4_div_min_max_scalar(bone_weight, -32768.0f, 32767.0f, bone_weight); + bone_weight = vec4::div_min_max(bone_weight, -32768.0f, 32767.0f); vec4i bone_index; bone_index.x = (int32_t)s.read_uint8_t(); @@ -7057,69 +7039,66 @@ static void obj_modern_write_vertex(obj* obj, stream& s, bool is_x, vertex[13] = s.get_position(); for (uint32_t i = 0; i < _num_vertex; i++) { vec3 position = vtx[i].position; - s.write_float_t(position.x); - s.write_float_t(position.y); - s.write_float_t(position.z); + s.write_float_t_reverse_endianness(position.x); + s.write_float_t_reverse_endianness(position.y); + s.write_float_t_reverse_endianness(position.z); - vec3 normal; - vec3_mult_min_max_scalar(vtx[i].normal, -32768.0f, 32767.0f, normal); - s.write_int16_t((int16_t)roundf(normal.x)); - s.write_int16_t((int16_t)roundf(normal.y)); - s.write_int16_t((int16_t)roundf(normal.z)); + vec3 normal = vec3::mult_min_max(vtx[i].normal, -32768.0f, 32767.0f); + s.write_int16_t_reverse_endianness((int16_t)roundf(normal.x)); + s.write_int16_t_reverse_endianness((int16_t)roundf(normal.y)); + s.write_int16_t_reverse_endianness((int16_t)roundf(normal.z)); s.write(0x02); - vec4 tangent = vtx[i].tangent; - vec4_mult_min_max_scalar(tangent, -32768.0f, 32767.0f, tangent); - s.write_int16_t((int16_t)roundf(tangent.x)); - s.write_int16_t((int16_t)roundf(tangent.y)); - s.write_int16_t((int16_t)roundf(tangent.z)); - s.write_int16_t((int16_t)roundf(tangent.w)); + vec4 tangent = vec4::mult_min_max(vtx[i].tangent, -32768.0f, 32767.0f); + s.write_int16_t_reverse_endianness((int16_t)roundf(tangent.x)); + s.write_int16_t_reverse_endianness((int16_t)roundf(tangent.y)); + s.write_int16_t_reverse_endianness((int16_t)roundf(tangent.z)); + s.write_int16_t_reverse_endianness((int16_t)roundf(tangent.w)); vec2h texcoord0; vec2_to_vec2h(vtx[i].texcoord0, texcoord0); - s.write_half_t(texcoord0.x); - s.write_half_t(texcoord0.y); + s.write_half_t_reverse_endianness(texcoord0.x); + s.write_half_t_reverse_endianness(texcoord0.y); vec2h texcoord1; vec2_to_vec2h(vtx[i].texcoord1, texcoord1); - s.write_half_t(texcoord1.x); - s.write_half_t(texcoord1.y); + s.write_half_t_reverse_endianness(texcoord1.x); + s.write_half_t_reverse_endianness(texcoord1.y); if (_vertex_flags == 0x06) { vec2h texcoord2; vec2_to_vec2h(vtx[i].texcoord2, texcoord2); - s.write_half_t(texcoord2.x); - s.write_half_t(texcoord2.y); + s.write_half_t_reverse_endianness(texcoord2.x); + s.write_half_t_reverse_endianness(texcoord2.y); } else if (_vertex_flags == 0x0A) { vec2h texcoord2; vec2_to_vec2h(vtx[i].texcoord2, texcoord2); - s.write_half_t(texcoord2.x); - s.write_half_t(texcoord2.y); + s.write_half_t_reverse_endianness(texcoord2.x); + s.write_half_t_reverse_endianness(texcoord2.y); vec2h texcoord3; vec2_to_vec2h(vtx[i].texcoord3, texcoord3); - s.write_half_t(texcoord3.x); - s.write_half_t(texcoord3.y); + s.write_half_t_reverse_endianness(texcoord3.x); + s.write_half_t_reverse_endianness(texcoord3.y); } vec4h color; vec4_to_vec4h(vtx[i].color0, color); - s.write_half_t(color.x); - s.write_half_t(color.y); - s.write_half_t(color.z); - s.write_half_t(color.w); + s.write_half_t_reverse_endianness(color.x); + s.write_half_t_reverse_endianness(color.y); + s.write_half_t_reverse_endianness(color.z); + s.write_half_t_reverse_endianness(color.w); if (_vertex_flags == 0x04) { - vec4 bone_weight = vtx[i].bone_weight; - vec4_mult_min_max_scalar(bone_weight, -32768.0f, 32767.0f, bone_weight); - s.write_int16_t((int16_t)bone_weight.x); - s.write_int16_t((int16_t)bone_weight.y); - s.write_int16_t((int16_t)bone_weight.z); - s.write_int16_t((int16_t)bone_weight.w); + vec4 bone_weight = vec4::mult_min_max(vtx[i].bone_weight, -32768.0f, 32767.0f); + s.write_int16_t_reverse_endianness((int16_t)bone_weight.x); + s.write_int16_t_reverse_endianness((int16_t)bone_weight.y); + s.write_int16_t_reverse_endianness((int16_t)bone_weight.z); + s.write_int16_t_reverse_endianness((int16_t)bone_weight.w); vec4u8 bone_index; - vec4_to_vec4u8(vtx[i].bone_index, bone_index) + vec4i_to_vec4u8(vtx[i].bone_index, bone_index); s.write_uint8_t(bone_index.x); s.write_uint8_t(bone_index.y); s.write_uint8_t(bone_index.z); @@ -7133,58 +7112,68 @@ static void obj_modern_write_vertex(obj* obj, stream& s, bool is_x, } inline static void obj_skin_block_node_free(obj_skin_block_node* b) { - free(b->parent_name); + free_def(b->parent_name); } -inline static uint32_t obj_skin_strings_get_string_index(std::vector& vec, const char* str) { +inline static uint32_t obj_skin_strings_get_string_index(std::vector& vec, const char* str) { size_t len = utf8_length(str); - for (std::string& i : vec) - if (!memcmp(str, i.c_str(), min(len, i.size()) + 1)) + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) return (uint32_t)(0x8000 | &i - vec.data()); return 0x8000; } -inline static int64_t obj_skin_strings_get_string_offset(std::vector& vec, +inline static int64_t obj_skin_strings_get_string_offset(std::vector& vec, std::vector& vec_off, const char* str) { size_t len = utf8_length(str); - for (std::string& i : vec) - if (!memcmp(str, i.c_str(), min(len, i.size()) + 1)) + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) return vec_off[&i - vec.data()]; return 0; } -inline static int64_t obj_skin_strings_get_string_offset_by_index(std::vector& vec, +inline static int64_t obj_skin_strings_get_string_offset_by_index(std::vector& vec, std::vector& vec_off, char** strings, uint32_t index) { if (~index & 0x8000) return 0; char* str = strings[index & 0x7FFF]; size_t len = utf8_length(str); - for (std::string& i : vec) - if (!memcmp(str, i.c_str(), min(len, i.size()) + 1)) + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) return vec_off[&i - vec.data()]; return 0; } -inline static void obj_skin_strings_push_back_check(std::vector& vec, const char* str) { +inline static void obj_skin_strings_push_back_check(std::vector& vec, const char* str) { size_t len = utf8_length(str); - for (std::string& i : vec) - if (!memcmp(str, i.c_str(), min(len, i.size()) + 1)) + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) return; - vec.push_back(std::string(str, len)); + vec.push_back(str); } -inline static void obj_skin_strings_push_back_check_by_index(std::vector& vec, +inline static void obj_skin_strings_push_back_check_by_index(std::vector& vec, char** strings, uint32_t index) { if (~index & 0x8000) return; char* str = strings[index & 0x7FFF]; size_t len = utf8_length(str); - for (std::string& i : vec) - if (!memcmp(str, i.c_str(), min(len, i.size()) + 1)) + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) return; - vec.push_back(std::string(str, len)); + vec.push_back(str); } diff --git a/src/KKdLib/obj.hpp b/src/KKdLib/obj.hpp index 600fae7c..95b2bd4b 100644 --- a/src/KKdLib/obj.hpp +++ b/src/KKdLib/obj.hpp @@ -642,6 +642,7 @@ struct obj { struct obj_set { bool ready; bool modern; + bool big_endian; bool is_x; obj* obj_data; diff --git a/src/KKdLib/post_process_table/dof.cpp b/src/KKdLib/post_process_table/dof.cpp index c371d274..bb740edf 100644 --- a/src/KKdLib/post_process_table/dof.cpp +++ b/src/KKdLib/post_process_table/dof.cpp @@ -5,15 +5,16 @@ #include "dof.hpp" #include "../f2/struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../hash.hpp" #include "../str_utils.hpp" static void dof_read_inner(dof* d, stream& s, uint32_t header_length); static void dof_write_inner(dof* d, stream& s); -dof::dof() : ready(), is_x() { +dof::dof() : ready(), big_endian(), is_x() { murmurhash = hash_murmurhash_empty; } @@ -30,13 +31,13 @@ void dof::read(const char* path) { f2_struct st; st.read(path_dft); if (st.header.signature == reverse_endianness_uint32_t('DOFT')) { - stream s_doft; + memory_stream s_doft; s_doft.open(st.data); - s_doft.is_big_endian = st.header.use_big_endian; + s_doft.big_endian = st.header.use_big_endian; dof_read_inner(this, s_doft, st.header.length); } } - free(path_dft); + free_def(path_dft); } void dof::read(const wchar_t* path) { @@ -48,13 +49,13 @@ void dof::read(const wchar_t* path) { f2_struct st; st.read(path_dex); if (st.header.signature == reverse_endianness_uint32_t('DOFT')) { - stream s_doft; + memory_stream s_doft; s_doft.open(st.data); - s_doft.is_big_endian = st.header.use_big_endian; + s_doft.big_endian = st.header.use_big_endian; dof_read_inner(this, s_doft, st.header.length); } } - free(path_dex); + free_def(path_dex); } void dof::read(const void* data, size_t size) { @@ -65,9 +66,9 @@ void dof::read(const void* data, size_t size) { f2_struct st; st.read(data, size); if (st.header.signature == reverse_endianness_uint32_t('DOFT')) { - stream s_doft; + memory_stream s_doft; s_doft.open(st.data); - s_doft.is_big_endian = st.header.use_big_endian; + s_doft.big_endian = st.header.use_big_endian; dof_read_inner(this, s_doft, st.header.length); } } @@ -77,11 +78,11 @@ void dof::write(const char* path) { return; char* path_dex = str_utils_add(path, ".dft"); - stream s; + file_stream s; s.open(path_dex, "wb"); - if (s.io.stream) + if (s.check_not_null()) dof_write_inner(this, s); - free(path_dex); + free_def(path_dex); } void dof::write(const wchar_t* path) { @@ -89,18 +90,18 @@ void dof::write(const wchar_t* path) { return; wchar_t* path_dex = str_utils_add(path, L".dft"); - stream s; + file_stream s; s.open(path_dex, L"wb"); - if (s.io.stream) + if (s.check_not_null()) dof_write_inner(this, s); - free(path_dex); + free_def(path_dex); } void dof::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); dof_write_inner(this, s); s.align_write(0x10); @@ -132,6 +133,7 @@ static void dof_read_inner(dof* d, stream& s, uint32_t header_length) { d->data.resize(count); + bool big_endian = s.big_endian; bool is_x = false; if (offset) { s.position_push(offset, SEEK_SET); @@ -165,15 +167,18 @@ static void dof_read_inner(dof* d, stream& s, uint32_t header_length) { } d->ready = true; + d->big_endian = big_endian; d->is_x = is_x; } static void dof_write_inner(dof* d, stream& s) { - stream s_motc; - s_motc.open(); - + bool big_endian = d->big_endian; bool is_x = d->is_x; + memory_stream s_doft; + s_doft.open(); + s_doft.big_endian = big_endian; + uint32_t o; enrs e; enrs_entry ee; @@ -205,35 +210,35 @@ static void dof_write_inner(dof* d, stream& s) { } if (!is_x) { - s_motc.write_uint32_t((uint32_t)d->data.size()); + s_doft.write_uint32_t((uint32_t)d->data.size()); pof.add(s, 0x40); s.write_offset_x(0x50); s.align_write(0x10); for (dof_data& i : d->data) { - s.write_uint32_t(i.flags); - s.write_float_t(i.focus); - s.write_float_t(i.focus_range); - s.write_float_t(i.fuzzing_range); - s.write_float_t(i.ratio); - s.write_float_t(i.quality); + s.write_uint32_t_reverse_endianness(i.flags); + s.write_float_t_reverse_endianness(i.focus); + s.write_float_t_reverse_endianness(i.focus_range); + s.write_float_t_reverse_endianness(i.fuzzing_range); + s.write_float_t_reverse_endianness(i.ratio); + s.write_float_t_reverse_endianness(i.quality); } } else { - s_motc.write_uint32_t((uint32_t)d->data.size()); + s_doft.write_uint32_t((uint32_t)d->data.size()); s.align_write(0x08); pof.add(s, 0x00); s.write_offset_x(0x10); s.align_write(0x10); for (dof_data& i : d->data) { - s.write_uint32_t(i.flags); - s.write_float_t(i.focus); - s.write_float_t(i.focus_range); - s.write_float_t(i.fuzzing_range); - s.write_float_t(i.ratio); - s.write_float_t(i.quality); - s.write_int32_t(i.chara_id); + s.write_uint32_t_reverse_endianness(i.flags); + s.write_float_t_reverse_endianness(i.focus); + s.write_float_t_reverse_endianness(i.focus_range); + s.write_float_t_reverse_endianness(i.fuzzing_range); + s.write_float_t_reverse_endianness(i.ratio); + s.write_float_t_reverse_endianness(i.quality); + s.write_int32_t_reverse_endianness(i.chara_id); } } @@ -241,16 +246,16 @@ static void dof_write_inner(dof* d, stream& s) { } f2_struct st; - s_motc.align_write(0x10); - s_motc.copy(st.data); - s_motc.close(); + s_doft.align_write(0x10); + s_doft.copy(st.data); + s_doft.close(); st.enrs = e; st.pof = pof; st.header.signature = reverse_endianness_uint32_t('DOFT'); st.header.length = 0x40; - st.header.use_big_endian = false; + st.header.use_big_endian = big_endian; st.header.use_section_size = true; st.header.murmurhash = murmurhash; st.header.inner_signature = 0x03; diff --git a/src/KKdLib/post_process_table/dof.hpp b/src/KKdLib/post_process_table/dof.hpp index 226199f3..84665896 100644 --- a/src/KKdLib/post_process_table/dof.hpp +++ b/src/KKdLib/post_process_table/dof.hpp @@ -29,6 +29,7 @@ struct dof_data { struct dof { bool ready; + bool big_endian; bool is_x; uint32_t murmurhash; diff --git a/src/KKdLib/pv_exp.cpp b/src/KKdLib/pv_exp.cpp index 6e4761a9..8ec0b34f 100644 --- a/src/KKdLib/pv_exp.cpp +++ b/src/KKdLib/pv_exp.cpp @@ -5,8 +5,9 @@ #include "pv_exp.hpp" #include "f2/struct.hpp" +#include "io/file_stream.hpp" +#include "io/memory_stream.hpp" #include "io/path.hpp" -#include "io/stream.hpp" #include "str_utils.hpp" static void pv_exp_classic_read_inner(pv_exp* exp, stream& s); @@ -30,7 +31,7 @@ pv_exp_mot::~pv_exp_mot() { } } -pv_exp::pv_exp() : ready(), modern(), is_x() { +pv_exp::pv_exp() : ready(), modern(), big_endian(), is_x() { } @@ -45,18 +46,18 @@ void pv_exp::read(const char* path, bool modern) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, "rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); pv_exp_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { char* path_dex = str_utils_add(path, ".dex"); @@ -64,13 +65,13 @@ void pv_exp::read(const char* path, bool modern) { f2_struct st; st.read(path_dex); if (st.header.signature == reverse_endianness_uint32_t('EXPC')) { - stream s_expc; + memory_stream s_expc; s_expc.open(st.data); - s_expc.is_big_endian = st.header.use_big_endian; + s_expc.big_endian = st.header.use_big_endian; pv_exp_modern_read_inner(this, s_expc, st.header.length); } } - free(path_dex); + free_def(path_dex); } } @@ -81,18 +82,18 @@ void pv_exp::read(const wchar_t* path, bool modern) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); if (path_check_file_exists(path_bin)) { - stream s; + file_stream s; s.open(path_bin, L"rb"); - if (s.io.stream) { + if (s.check_not_null()) { uint8_t* data = force_malloc_s(uint8_t, s.length); s.read(data, s.length); - stream s_bin; + memory_stream s_bin; s_bin.open(data, s.length); pv_exp_classic_read_inner(this, s_bin); - free(data); + free_def(data); } } - free(path_bin); + free_def(path_bin); } else { wchar_t* path_dex = str_utils_add(path, L".dex"); @@ -100,13 +101,13 @@ void pv_exp::read(const wchar_t* path, bool modern) { f2_struct st; st.read(path_dex); if (st.header.signature == reverse_endianness_uint32_t('EXPC')) { - stream s_expc; + memory_stream s_expc; s_expc.open(st.data); - s_expc.is_big_endian = st.header.use_big_endian; + s_expc.big_endian = st.header.use_big_endian; pv_exp_modern_read_inner(this, s_expc, st.header.length); } } - free(path_dex); + free_def(path_dex); } } @@ -115,7 +116,7 @@ void pv_exp::read(const void* data, size_t size, bool modern) { return; if (!modern) { - stream s; + memory_stream s; s.open(data, size); pv_exp_classic_read_inner(this, s); } @@ -123,9 +124,9 @@ void pv_exp::read(const void* data, size_t size, bool modern) { f2_struct st; st.read(data, size); if (st.header.signature == reverse_endianness_uint32_t('EXPC')) { - stream s_expc; + memory_stream s_expc; s_expc.open(st.data); - s_expc.is_big_endian = st.header.use_big_endian; + s_expc.big_endian = st.header.use_big_endian; pv_exp_modern_read_inner(this, s_expc, st.header.length); } } @@ -137,19 +138,19 @@ void pv_exp::write(const char* path) { if (!modern) { char* path_bin = str_utils_add(path, ".bin"); - stream s; + file_stream s; s.open(path_bin, "wb"); - if (s.io.stream) + if (s.check_not_null()) pv_exp_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { char* path_dex = str_utils_add(path, ".dex"); - stream s; + file_stream s; s.open(path_dex, "wb"); - if (s.io.stream) + if (s.check_not_null()) pv_exp_modern_write_inner(this, s); - free(path_dex); + free_def(path_dex); } } @@ -159,19 +160,19 @@ void pv_exp::write(const wchar_t* path) { if (!modern) { wchar_t* path_bin = str_utils_add(path, L".bin"); - stream s; + file_stream s; s.open(path_bin, L"wb"); - if (s.io.stream) + if (s.check_not_null()) pv_exp_classic_write_inner(this, s); - free(path_bin); + free_def(path_bin); } else { wchar_t* path_dex = str_utils_add(path, L".dex"); - stream s; + file_stream s; s.open(path_dex, L"wb"); - if (s.io.stream) + if (s.check_not_null()) pv_exp_modern_write_inner(this, s); - free(path_dex); + free_def(path_dex); } } @@ -179,7 +180,7 @@ void pv_exp::write(void** data, size_t* size) { if (!data || !size || !ready) return; - stream s; + memory_stream s; s.open(); if (!modern) pv_exp_classic_write_inner(this, s); @@ -208,6 +209,7 @@ static void pv_exp_classic_read_inner(pv_exp* exp, stream& s) { if (s.read_uint32_t() != 0x64) { exp->ready = false; exp->modern = false; + exp->big_endian = false; exp->is_x = false; return; } @@ -247,8 +249,15 @@ static void pv_exp_classic_read_inner(pv_exp* exp, stream& s) { s.position_pop(); i.face_data = new pv_exp_data[face_count]; + pv_exp_data* face_data = i.face_data; s.position_push(face_offset[&i - exp->motion_data.data()], SEEK_SET); - s.read(i.face_data, sizeof(pv_exp_data) * face_count); + for (size_t j = face_count; j; j--, face_data++) { + face_data->frame = s.read_float_t(); + face_data->type = s.read_int16_t(); + face_data->id = s.read_int16_t(); + face_data->value = s.read_float_t(); + face_data->trans = s.read_float_t(); + } s.position_pop(); } @@ -264,8 +273,15 @@ static void pv_exp_classic_read_inner(pv_exp* exp, stream& s) { s.position_pop(); i.face_cl_data = new pv_exp_data[face_cl_count]; + pv_exp_data* face_cl_data = i.face_cl_data; s.position_push(face_cl_offset[&i - exp->motion_data.data()], SEEK_SET); - s.read(i.face_cl_data, sizeof(pv_exp_data) * face_cl_count); + for (size_t j = face_cl_count; j; j--, face_cl_data++) { + face_cl_data->frame = s.read_float_t(); + face_cl_data->type = s.read_int16_t(); + face_cl_data->id = s.read_int16_t(); + face_cl_data->value = s.read_float_t(); + face_cl_data->trans = s.read_float_t(); + } s.position_pop(); } @@ -273,12 +289,13 @@ static void pv_exp_classic_read_inner(pv_exp* exp, stream& s) { i.name = s.read_string_null_terminated_offset(name_offset[&i - exp->motion_data.data()]); } - free(face_offset); - free(face_cl_offset); - free(name_offset); + free_def(face_offset); + free_def(face_cl_offset); + free_def(name_offset); exp->ready = true; exp->modern = false; + exp->big_endian = false; exp->is_x = false; } @@ -308,12 +325,16 @@ static void pv_exp_classic_write_inner(pv_exp* exp, stream& s) { face_offset[&i - exp->motion_data.data()] = s.get_position(); pv_exp_data* face_data = i.face_data; - while (face_data->type != -1) { + while (true) { s.write_float_t(face_data->frame); s.write_int16_t(face_data->type); s.write_int16_t(face_data->id); s.write_float_t(face_data->value); s.write_float_t(face_data->trans); + + if (face_data->type == -1) + break; + face_data++; } s.align_write(0x20); @@ -321,12 +342,16 @@ static void pv_exp_classic_write_inner(pv_exp* exp, stream& s) { face_cl_offset[&i - exp->motion_data.data()] = s.get_position(); pv_exp_data* face_cl_data = i.face_cl_data; - while (face_cl_data->type != -1) { + while (true) { s.write_float_t(face_cl_data->frame); s.write_int16_t(face_cl_data->type); s.write_int16_t(face_cl_data->id); s.write_float_t(face_cl_data->value); s.write_float_t(face_cl_data->trans); + + if (face_cl_data->type == -1) + break; + face_cl_data++; } s.align_write(0x20); @@ -348,9 +373,9 @@ static void pv_exp_classic_write_inner(pv_exp* exp, stream& s) { for (pv_exp_mot& i : exp->motion_data) s.write_uint32_t((uint32_t)name_offset[&i - exp->motion_data.data()]); - free(face_offset); - free(face_cl_offset); - free(name_offset); + free_def(face_offset); + free_def(face_cl_offset); + free_def(name_offset); s.position_pop(); s.write_uint32_t((uint32_t)name_offsets_offset); @@ -360,10 +385,12 @@ static void pv_exp_modern_read_inner(pv_exp* exp, stream& s, uint32_t header_len if (s.read_uint32_t() != 0x64) { exp->ready = false; exp->modern = false; + exp->big_endian = false; exp->is_x = false; return; } + bool big_endian = s.big_endian; bool is_x = false; exp->motion_data.resize(0); @@ -415,8 +442,15 @@ static void pv_exp_modern_read_inner(pv_exp* exp, stream& s, uint32_t header_len s.position_pop(); i.face_data = new pv_exp_data[face_count]; + pv_exp_data* face_data = i.face_data; s.position_push(face_offset[&i - exp->motion_data.data()], SEEK_SET); - s.read(i.face_data, sizeof(pv_exp_data) * face_count); + for (size_t j = face_count; j; j--, face_data++) { + face_data->frame = s.read_float_t_reverse_endianness(); + face_data->type = s.read_int16_t_reverse_endianness(); + face_data->id = s.read_int16_t_reverse_endianness(); + face_data->value = s.read_float_t_reverse_endianness(); + face_data->trans = s.read_float_t_reverse_endianness(); + } s.position_pop(); } @@ -432,8 +466,15 @@ static void pv_exp_modern_read_inner(pv_exp* exp, stream& s, uint32_t header_len s.position_pop(); i.face_cl_data = new pv_exp_data[face_cl_count]; + pv_exp_data* face_cl_data = i.face_cl_data; s.position_push(face_cl_offset[&i - exp->motion_data.data()], SEEK_SET); - s.read(i.face_cl_data, sizeof(pv_exp_data) * face_cl_count); + for (size_t j = face_cl_count; j; j--, face_cl_data++) { + face_cl_data->frame = s.read_float_t_reverse_endianness(); + face_cl_data->type = s.read_int16_t_reverse_endianness(); + face_cl_data->id = s.read_int16_t_reverse_endianness(); + face_cl_data->value = s.read_float_t_reverse_endianness(); + face_cl_data->trans = s.read_float_t_reverse_endianness(); + } s.position_pop(); } @@ -441,23 +482,26 @@ static void pv_exp_modern_read_inner(pv_exp* exp, stream& s, uint32_t header_len i.name = s.read_string_null_terminated_offset(name_offset[&i - exp->motion_data.data()]); } - free(face_offset); - free(face_cl_offset); - free(name_offset); + free_def(face_offset); + free_def(face_cl_offset); + free_def(name_offset); exp->ready = true; exp->modern = true; + exp->big_endian = big_endian; exp->is_x = is_x; } static void pv_exp_modern_write_inner(pv_exp* exp, stream& s) { - stream s_expc; - s_expc.open(); - + bool big_endian = exp->big_endian; bool is_x = exp->is_x; - s_expc.write_uint32_t(0x64); - s_expc.write_int32_t((int32_t)exp->motion_data.size()); + memory_stream s_expc; + s_expc.open(); + s_expc.big_endian = big_endian; + + s_expc.write_uint32_t_reverse_endianness(0x64); + s_expc.write_int32_t_reverse_endianness((int32_t)exp->motion_data.size()); s_expc.write_offset(is_x ? 0x28 : 0x20, 0x20, is_x); s_expc.position_push(s_expc.get_position(), SEEK_SET); @@ -488,12 +532,16 @@ static void pv_exp_modern_write_inner(pv_exp* exp, stream& s) { face_offset[&i - exp->motion_data.data()] = s_expc.get_position(); pv_exp_data* face_data = i.face_data; - while (face_data->type != -1) { - s_expc.write_float_t(face_data->frame); - s_expc.write_int16_t(face_data->type); - s_expc.write_int16_t(face_data->id); - s_expc.write_float_t(face_data->value); - s_expc.write_float_t(face_data->trans); + while (true) { + s_expc.write_float_t_reverse_endianness(face_data->frame); + s_expc.write_int16_t_reverse_endianness(face_data->type); + s_expc.write_int16_t_reverse_endianness(face_data->id); + s_expc.write_float_t_reverse_endianness(face_data->value); + s_expc.write_float_t_reverse_endianness(face_data->trans); + + if (face_data->type == -1) + break; + face_data++; } s_expc.align_write(0x20); @@ -501,12 +549,16 @@ static void pv_exp_modern_write_inner(pv_exp* exp, stream& s) { face_cl_offset[&i - exp->motion_data.data()] = s_expc.get_position(); pv_exp_data* face_cl_data = i.face_cl_data; - while (face_cl_data->type != -1) { - s_expc.write_float_t(face_cl_data->frame); - s_expc.write_int16_t(face_cl_data->type); - s_expc.write_int16_t(face_cl_data->id); - s_expc.write_float_t(face_cl_data->value); - s_expc.write_float_t(face_cl_data->trans); + while (true) { + s_expc.write_float_t_reverse_endianness(face_cl_data->frame); + s_expc.write_int16_t_reverse_endianness(face_cl_data->type); + s_expc.write_int16_t_reverse_endianness(face_cl_data->id); + s_expc.write_float_t_reverse_endianness(face_cl_data->value); + s_expc.write_float_t_reverse_endianness(face_cl_data->trans); + + if (face_cl_data->type == -1) + break; + face_cl_data++; } s_expc.align_write(0x20); @@ -538,9 +590,9 @@ static void pv_exp_modern_write_inner(pv_exp* exp, stream& s) { for (pv_exp_mot& i : exp->motion_data) s_expc.write_offset_x(name_offset[&i - exp->motion_data.data()]); - free(face_offset); - free(face_cl_offset); - free(name_offset); + free_def(face_offset); + free_def(face_cl_offset); + free_def(name_offset); s_expc.position_pop(); @@ -553,7 +605,7 @@ static void pv_exp_modern_write_inner(pv_exp* exp, stream& s) { st.header.signature = reverse_endianness_uint32_t('EXPC'); st.header.length = 0x20; - st.header.use_big_endian = false; + st.header.use_big_endian = big_endian; st.header.use_section_size = true; st.write(s, true, exp->is_x); diff --git a/src/KKdLib/pv_exp.hpp b/src/KKdLib/pv_exp.hpp index efed5152..ebf81001 100644 --- a/src/KKdLib/pv_exp.hpp +++ b/src/KKdLib/pv_exp.hpp @@ -29,6 +29,7 @@ struct pv_exp_mot { struct pv_exp { bool ready; bool modern; + bool big_endian; bool is_x; std::vector motion_data; diff --git a/src/KKdLib/pvpp.cpp b/src/KKdLib/pvpp.cpp index 3870ff98..bd20e1c6 100644 --- a/src/KKdLib/pvpp.cpp +++ b/src/KKdLib/pvpp.cpp @@ -5,8 +5,9 @@ #include "pvpp.hpp" #include "f2/struct.hpp" +#include "io/file_stream.hpp" +#include "io/memory_stream.hpp" #include "io/path.hpp" -#include "io/stream.hpp" #include "str_utils.hpp" static void pvpp_auth_3d_read(string_hash* a3d, stream& s); @@ -70,7 +71,7 @@ pvpp_glitter::~pvpp_glitter() { } -pvpp::pvpp() : ready() { +pvpp::pvpp() : ready(), big_endian() { } @@ -84,12 +85,12 @@ void pvpp::read(const char* path) { char* path_pvpp = str_utils_add(path, ".pvpp"); if (path_check_file_exists(path_pvpp)) { - stream s; + file_stream s; s.open(path_pvpp, "rb"); - if (s.io.stream) + if (s.check_not_null()) pvpp_read_inner(this, s); } - free(path_pvpp); + free_def(path_pvpp); } void pvpp::read(const wchar_t* path) { @@ -98,19 +99,19 @@ void pvpp::read(const wchar_t* path) { wchar_t* path_pvpp = str_utils_add(path, L".pvpp"); if (path_check_file_exists(path_pvpp)) { - stream s; + file_stream s; s.open(path_pvpp, L"rb"); - if (s.io.stream) + if (s.check_not_null()) pvpp_read_inner(this, s); } - free(path_pvpp); + free_def(path_pvpp); } void pvpp::read(const void* data, size_t size) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); pvpp_read_inner(this, s); } @@ -316,12 +317,17 @@ static void pvpp_object_set_read(string_hash* objset, stream& s) { static void pvpp_read_inner(pvpp* pp, stream& s) { f2_struct st; st.read(s); - if (st.header.signature != reverse_endianness_uint32_t('PVPP') || !st.data.data()) + if (st.header.signature != reverse_endianness_uint32_t('PVPP') || !st.data.data()) { + pp->ready = false; + pp->big_endian = false; return; + } - stream s_pvpp; + bool big_endian = st.header.use_big_endian; + + memory_stream s_pvpp; s_pvpp.open(st.data); - s_pvpp.is_big_endian = st.header.use_big_endian; + s_pvpp.big_endian = big_endian; s_pvpp.read_uint32_t_reverse_endianness(); int8_t chara_count = s_pvpp.read_int8_t(); @@ -356,4 +362,5 @@ static void pvpp_read_inner(pvpp* pp, stream& s) { } pp->ready = true; + pp->big_endian = true; } diff --git a/src/KKdLib/pvpp.hpp b/src/KKdLib/pvpp.hpp index 8c83ee73..64ba32e6 100644 --- a/src/KKdLib/pvpp.hpp +++ b/src/KKdLib/pvpp.hpp @@ -108,6 +108,7 @@ struct pvpp_chara { struct pvpp { bool ready; + bool big_endian; std::vector chara; std::vector effect; diff --git a/src/KKdLib/pvsr.cpp b/src/KKdLib/pvsr.cpp index 8bedaacc..8eb61366 100644 --- a/src/KKdLib/pvsr.cpp +++ b/src/KKdLib/pvsr.cpp @@ -5,8 +5,9 @@ #include "pvsr.hpp" #include "f2/struct.hpp" +#include "io/file_stream.hpp" +#include "io/memory_stream.hpp" #include "io/path.hpp" -#include "io/stream.hpp" #include "str_utils.hpp" static void pvsr_auth_3d_read(pvsr_auth_3d* a3d, stream& s); @@ -86,7 +87,7 @@ pvsr_stage_effect_env::~pvsr_stage_effect_env() { } -pvsr::pvsr() : ready() { +pvsr::pvsr() : ready(), big_endian() { } @@ -100,12 +101,12 @@ void pvsr::read(const char* path) { char* path_pvsr = str_utils_add(path, ".pvsr"); if (path_check_file_exists(path_pvsr)) { - stream s; + file_stream s; s.open(path_pvsr, "rb"); - if (s.io.stream) + if (s.check_not_null()) pvsr_read_inner(this, s); } - free(path_pvsr); + free_def(path_pvsr); } void pvsr::read(const wchar_t* path) { @@ -114,19 +115,19 @@ void pvsr::read(const wchar_t* path) { wchar_t* path_pvsr = str_utils_add(path, L".pvsr"); if (path_check_file_exists(path_pvsr)) { - stream s; + file_stream s; s.open(path_pvsr, L"rb"); - if (s.io.stream) + if (s.check_not_null()) pvsr_read_inner(this, s); } - free(path_pvsr); + free_def(path_pvsr); } void pvsr::read(const void* data, size_t size) { if (!data || !size) return; - stream s; + memory_stream s; s.open(data, size); pvsr_read_inner(this, s); } @@ -175,12 +176,17 @@ static void pvsr_glitter_read(pvsr_glitter* glt, stream& s) { static void pvsr_read_inner(pvsr* sr, stream& s) { f2_struct st; st.read(s); - if (st.header.signature != reverse_endianness_uint32_t('PVSR') || !st.data.data()) + if (st.header.signature != reverse_endianness_uint32_t('PVSR') || !st.data.data()) { + sr->ready = false; + sr->big_endian = false; return; + } - stream s_pvsr; + bool big_endian = st.header.use_big_endian; + + memory_stream s_pvsr; s_pvsr.open(st.data); - s_pvsr.is_big_endian = st.header.use_big_endian; + s_pvsr.big_endian = big_endian; int32_t x00 = s_pvsr.read_int32_t_reverse_endianness(); uint8_t x04 = s_pvsr.read_uint8_t(); @@ -273,6 +279,7 @@ static void pvsr_read_inner(pvsr* sr, stream& s) { } sr->ready = true; + sr->big_endian = big_endian; } static void pvsr_stage_change_effect_read(pvsr_stage_change_effect* stg_chg_eff, stream& s) { diff --git a/src/KKdLib/pvsr.hpp b/src/KKdLib/pvsr.hpp index 61756585..34982e52 100644 --- a/src/KKdLib/pvsr.hpp +++ b/src/KKdLib/pvsr.hpp @@ -130,6 +130,7 @@ struct pvsr_stage_effect_env { struct pvsr { bool ready; + bool big_endian; std::vector effect; std::vector emcs; diff --git a/src/KKdLib/quat.cpp b/src/KKdLib/quat.cpp index 8b1c532f..1b37117c 100644 --- a/src/KKdLib/quat.cpp +++ b/src/KKdLib/quat.cpp @@ -16,8 +16,8 @@ inline void quat_mult(const quat* x, const quat* y, quat* z) { __m128 zt2; __m128 zt3; - xt = x->data; - yt = y->data; + xt = _mm_loadu_ps((const float*)x); + yt = _mm_loadu_ps((const float*)y); zt0 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x1B)); zt1 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x4E)); zt2 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0xB1)); @@ -37,45 +37,6 @@ inline void quat_mult(const quat* x, const quat* y, quat* z) { *z = zt; } -void quat_slerp(const quat* x, const quat* y, quat* z, const float_t blend) { - quat x_t; - quat y_t; - quat z_t; - quat zt0; - quat zt1; - vec4_normalize(*x, x_t); - vec4_normalize(*y, y_t); - - float_t dot; - vec4_dot(x_t, y_t, dot); - if (dot < 0.0f) { - vec4_negate(y_t, z_t); - dot = -dot; - } - else - z_t = y_t; - - const float_t DOT_THRESHOLD = 0.9995f; - float_t s0, s1; - if (dot <= DOT_THRESHOLD) { - float_t theta_0 = acosf(dot); - float_t theta = theta_0 * blend; - float_t sin_theta = sinf(theta); - float_t sin_theta_0 = sinf(theta_0); - - s0 = cosf(theta) - dot * sin_theta / sin_theta_0; - s1 = sin_theta / sin_theta_0; - } - else { - s0 = (1.0f - blend); - s1 = blend; - } - vec4_mult_scalar(*x, s0, zt0); - vec4_mult_scalar(z_t, s0, zt1); - vec4_add(zt0, zt1, z_t); - vec4_normalize(z_t, *z); -} - void quat_from_mat3(float_t m00, float_t m01, float_t m02, float_t m10, float_t m11, float_t m12, float_t m20, float_t m21, float_t m22, quat* quat) { float_t sq; @@ -115,13 +76,6 @@ void quat_from_mat3(float_t m00, float_t m01, float_t m02, float_t m10, } inline void quat_from_axis_angle(const vec3* axis, const float_t angle, quat* quat) { - float_t angle_sin; - float_t angle_cos; - vec3 _axis; - - angle_sin = sinf(angle * 0.5f); - angle_cos = cosf(angle * 0.5f); - vec3_normalize(*axis, _axis); - quat->w = angle_cos; - vec3_mult_scalar(_axis, angle_sin, *(vec3*)quat); + *(vec3*)quat = vec3::normalize(*axis) * sinf(angle * 0.5f); + quat->w = cosf(angle * 0.5f); } diff --git a/src/KKdLib/quat.hpp b/src/KKdLib/quat.hpp index 5fc1d3f6..2e110f07 100644 --- a/src/KKdLib/quat.hpp +++ b/src/KKdLib/quat.hpp @@ -8,20 +8,321 @@ #include "default.hpp" #include "vec.hpp" -union quat { - struct { - float_t x; - float_t y; - float_t z; - float_t w; - }; - __m128 data; +struct quat { + float_t x; + float_t y; + float_t z; + float_t w; + + static float_t dot(const quat& left, const quat& right); + static float_t length(const quat& left); + static float_t length_squared(const quat& left); + static float_t distance(const quat& left, const quat& right); + static float_t distance_squared(const quat& left, const quat& right); + static quat slerp(const quat& left, const quat& right, const float_t blend); + static quat normalize(const quat& left); + static quat rcp(const quat& left); + static quat min(const quat& left, const quat& right); + static quat max(const quat& left, const quat& right); + static quat clamp(const quat& left, const quat& min, const quat& max); + static quat clamp(const quat& left, const float_t min, const float_t max); + static quat mult_min_max(const quat& left, const quat& min, const quat& max); + static quat mult_min_max(const quat& left, const float_t min, const float_t max); + static quat div_min_max(const quat& left, const quat& min, const quat& max); + static quat div_min_max(const quat& left, const float_t min, const float_t max); }; static const quat quat_identity = { 0.0f, 0.0f, 0.0f, 1.0f }; +inline quat operator +(const quat& left, const quat& right) { + __m128 yt; + quat z; + *(quat*)&yt = right; + _mm_storeu_ps((float*)&z, _mm_add_ps(_mm_loadu_ps((const float*)&left), yt)); + return z; +} + +inline quat operator +(const quat& left, const float_t right) { + __m128 yt; + quat z; + yt = _mm_set_ss(right); + _mm_storeu_ps((float*)&z, _mm_add_ps(_mm_loadu_ps((const float*)&left), _mm_shuffle_ps(yt, yt, 0))); + return z; +} + +inline quat operator -(const quat& left, const quat& right) { + __m128 yt; + quat z; + *(quat*)&yt = right; + _mm_storeu_ps((float*)&z, _mm_sub_ps(_mm_loadu_ps((const float*)&left), yt)); + return z; +} + +inline quat operator -(const quat& left, const float_t right) { + __m128 yt; + quat z; + yt = _mm_set_ss(right); + _mm_storeu_ps((float*)&z, _mm_sub_ps(_mm_loadu_ps((const float*)&left), _mm_shuffle_ps(yt, yt, 0))); + return z; +} + +inline quat operator *(const quat& left, const quat& right) { + __m128 yt; + quat z; + *(quat*)&yt = right; + _mm_storeu_ps((float*)&z, _mm_mul_ps(_mm_loadu_ps((const float*)&left), yt)); + return z; +} + +inline quat operator *(const quat& left, const float_t right) { + __m128 yt; + quat z; + yt = _mm_set_ss(right); + _mm_storeu_ps((float*)&z, _mm_mul_ps(_mm_loadu_ps((const float*)&left), _mm_shuffle_ps(yt, yt, 0))); + return z; +} + +inline quat operator /(const quat& left, const quat& right) { + __m128 yt; + quat z; + *(quat*)&yt = right; + _mm_storeu_ps((float*)&z, _mm_div_ps(_mm_loadu_ps((const float*)&left), yt)); + return z; +} + +inline quat operator /(const quat& left, const float_t right) { + __m128 yt; + quat z; + yt = _mm_set_ss(right); + _mm_storeu_ps((float*)&z, _mm_div_ps(_mm_loadu_ps((const float*)&left), _mm_shuffle_ps(yt, yt, 0))); + return z; +} + +inline quat operator &(const quat& left, const quat& right) { + __m128 yt; + quat z; + *(quat*)&yt = right; + _mm_storeu_ps((float*)&z, _mm_and_ps(_mm_loadu_ps((const float*)&left), yt)); + return z; +} + +inline quat operator &(const quat& left, const float_t right) { + __m128 yt; + quat z; + yt = _mm_set_ss(right); + _mm_storeu_ps((float*)&z, _mm_and_ps(_mm_loadu_ps((const float*)&left), _mm_shuffle_ps(yt, yt, 0))); + return z; +} + +inline quat operator ^(const quat& left, const quat& right) { + __m128 yt; + quat z; + *(quat*)&yt = right; + _mm_storeu_ps((float*)&z, _mm_xor_ps(_mm_loadu_ps((const float*)&left), yt)); + return z; +} + +inline quat operator ^(const quat& left, const float_t right) { + __m128 yt; + quat z; + yt = _mm_set_ss(right); + _mm_storeu_ps((float*)&z, _mm_xor_ps(_mm_loadu_ps((const float*)&left), _mm_shuffle_ps(yt, yt, 0))); + return z; +} + +inline quat operator -(const quat& left) { + quat z; + _mm_storeu_ps((float*)&z, _mm_xor_ps(_mm_loadu_ps((const float*)&left), vec4_neg)); + return z; +} + +inline float_t quat::dot(const quat& left, const quat& right) { + __m128 zt; + zt = _mm_mul_ps(_mm_loadu_ps((const float*)&(left)), _mm_loadu_ps((const float*)&(right))); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t quat::length(const quat& left) { + __m128 xt; + __m128 zt; + xt = _mm_loadu_ps((const float*)&left); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t quat::length_squared(const quat& left) { + __m128 xt; + __m128 zt; + xt = _mm_loadu_ps((const float*)&left); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t quat::distance(const quat& left, const quat& right) { + __m128 zt; + zt = _mm_sub_ps(_mm_loadu_ps((const float*)&(left)), _mm_loadu_ps((const float*)&(right))); + zt = _mm_mul_ps(zt, zt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t quat::distance_squared(const quat& left, const quat& right) { + __m128 zt; + zt = _mm_sub_ps(_mm_loadu_ps((const float*)&(left)), _mm_loadu_ps((const float*)&(right))); + zt = _mm_mul_ps(zt, zt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline quat quat::slerp(const quat& left, const quat& right, const float_t blend) { + quat x_t; + quat y_t; + quat z_t; + x_t = quat::normalize(left); + y_t = quat::normalize(right); + + float_t dot = quat::dot(x_t, y_t); + if (dot < 0.0f) { + z_t = -y_t; + dot = -dot; + } + else + z_t = y_t; + + const float_t DOT_THRESHOLD = 0.9995f; + float_t s0, s1; + if (dot <= DOT_THRESHOLD) { + float_t theta_0 = acosf(dot); + float_t theta = theta_0 * blend; + float_t sin_theta = sinf(theta); + float_t sin_theta_0 = sinf(theta_0); + + s0 = cosf(theta) - dot * sin_theta / sin_theta_0; + s1 = sin_theta / sin_theta_0; + } + else { + s0 = (1.0f - blend); + s1 = blend; + } + return quat::normalize(left * s0 + z_t * s0); +} + +inline quat quat::normalize(const quat& left) { + __m128 xt; + __m128 zt; + quat z; + xt = _mm_loadu_ps((const float*)&left); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); + if (zt.m128_f32[0] != 0.0f) + zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; + _mm_storeu_ps((float*)&z, _mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0))); + return z; +} + +inline quat quat::rcp(const quat& left) { + quat z; + _mm_storeu_ps((float*)&z, _mm_div_ps(_mm_loadu_ps((const float*)&(quat_identity)), _mm_loadu_ps((const float*)&left))); + return z; +} + +inline quat quat::min(const quat& left, const quat& right) { + quat z; + _mm_storeu_ps((float*)&z, _mm_min_ps(_mm_loadu_ps((const float*)&(left)), _mm_loadu_ps((const float*)&(right)))); + return z; +} + +inline quat quat::max(const quat& left, const quat& right) { + quat z; + _mm_storeu_ps((float*)&z, _mm_max_ps(_mm_loadu_ps((const float*)&(left)), _mm_loadu_ps((const float*)&(right)))); + return z; +} + +inline quat quat::clamp(const quat& left, const quat& min, const quat& max) { + quat w; + _mm_storeu_ps((float*)&w, _mm_min_ps(_mm_max_ps(_mm_loadu_ps((const float*)&left), + _mm_loadu_ps((const float*)&(min))), _mm_loadu_ps((const float*)&(max)))); + return w; +} + +inline quat quat::clamp(const quat& left, const float_t min, const float_t max) { + __m128 yt; + __m128 zt; + quat w; + yt = _mm_set_ss(min); + zt = _mm_set_ss(max); + _mm_storeu_ps((float*)&w, _mm_min_ps(_mm_max_ps(_mm_loadu_ps((const float*)&left), + _mm_shuffle_ps(yt, yt, 0)), _mm_shuffle_ps(zt, zt, 0))); + return w; +} + +inline quat quat::mult_min_max(const quat& left, const quat& min, const quat& max) { + __m128 xt; + __m128 yt; + __m128 wt; + quat w; + xt = _mm_loadu_ps((const float*)&left); + yt = _mm_xor_ps(_mm_loadu_ps((const float*)&(min)), vec4_neg); + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((const float*)&(vec4_null)))), + _mm_and_ps(_mm_loadu_ps((const float*)&(max)), _mm_cmpge_ps(xt, _mm_loadu_ps((const float*)&(vec4_null))))); + _mm_storeu_ps((float*)&w, _mm_mul_ps(xt, wt)); + return w; +} + +inline quat quat::mult_min_max(const quat& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + __m128 wt; + quat w; + xt = _mm_loadu_ps((const float*)&left); + yt = _mm_set_ss(min); + yt = _mm_shuffle_ps(yt, yt, 0); + zt = _mm_set_ss(max); + zt = _mm_shuffle_ps(zt, zt, 0); + yt = _mm_xor_ps(yt, vec4_neg); + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((const float*)&(vec4_null)))), + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((const float*)&(vec4_null))))); + _mm_storeu_ps((float*)&w, _mm_mul_ps(xt, wt)); + return w; +} + +inline quat quat::div_min_max(const quat& left, const quat& min, const quat& max) { + __m128 xt; + __m128 yt; + __m128 wt; + quat w; + xt = _mm_loadu_ps((const float*)&left); + yt = _mm_xor_ps(_mm_loadu_ps((const float*)&(min)), vec4_neg); + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((const float*)&(vec4_null)))), + _mm_and_ps(_mm_loadu_ps((const float*)&(max)), _mm_cmpge_ps(xt, _mm_loadu_ps((const float*)&(vec4_null))))); + _mm_storeu_ps((float*)&w, _mm_div_ps(xt, wt)); + return w; +} + +inline quat quat::div_min_max(const quat& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + __m128 wt; + quat w; + xt = _mm_loadu_ps((const float*)&left); + yt = _mm_set_ss(min); + yt = _mm_shuffle_ps(yt, yt, 0); + zt = _mm_set_ss(max); + zt = _mm_shuffle_ps(zt, zt, 0); + yt = _mm_xor_ps(yt, vec4_neg); + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((const float*)&(vec4_null)))), + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((const float*)&(vec4_null))))); + _mm_storeu_ps((float*)&w, _mm_div_ps(xt, wt)); + return w; +} + extern void quat_mult(const quat* x, const quat* y, quat* z); -extern void quat_slerp(const quat* x, const quat* y, quat* z, const float_t blend); extern void quat_from_mat3(float_t m00, float_t m01, float_t m02, float_t m10, float_t m11, float_t m12, float_t m20, float_t m21, float_t m22, quat* quat); extern void quat_from_axis_angle(const vec3* axis, const float_t angle, quat* quat); diff --git a/src/KKdLib/quat_trans.cpp b/src/KKdLib/quat_trans.cpp index 80227df4..8953f521 100644 --- a/src/KKdLib/quat_trans.cpp +++ b/src/KKdLib/quat_trans.cpp @@ -11,7 +11,7 @@ void lerp_quat_trans(quat_trans* x, quat_trans* y, quat_trans* z, float_t blend) else if (blend < 0.0f) blend = 0.0f; - quat_slerp(&x->quat, &y->quat, &z->quat, blend); - vec3_lerp_scalar(x->trans, y->trans, z->trans, blend); - z->time = lerp(x->time, y->time, blend); + z->quat = quat::slerp(x->quat, y->quat, blend); + z->trans = vec3::lerp(x->trans, y->trans, blend); + z->time = lerp_def(x->time, y->time, blend); } diff --git a/src/KKdLib/sort.cpp b/src/KKdLib/sort.cpp index fb825313..170b30f6 100644 --- a/src/KKdLib/sort.cpp +++ b/src/KKdLib/sort.cpp @@ -26,8 +26,9 @@ static int quicksort_char_ptr_compare(void const* src1, void const* src2); static int quicksort_wchar_t_ptr_compare(void const* src1, void const* src2); static int quicksort_std_string_compare(void const* src1, void const* src2); static int quicksort_std_wstring_compare(void const* src1, void const* src2); +static int quicksort_string_hash_compare(void const* src1, void const* src2); -inline void radix_sort_int8_t(int8_t* arr, size_t n) { +void radix_sort_int8_t(int8_t* arr, size_t n) { if (n <= 1) return; @@ -71,10 +72,10 @@ void radix_sort_uint8_t(uint8_t* arr, size_t n) { memmove(arr, o, sizeof(uint8_t) * n); } - free(o); + free_def(o); } -inline void radix_sort_int16_t(int16_t* arr, size_t n) { +void radix_sort_int16_t(int16_t* arr, size_t n) { if (n <= 1) return; @@ -118,10 +119,10 @@ void radix_sort_uint16_t(uint16_t* arr, size_t n) { memmove(arr, o, sizeof(uint16_t) * n); } - free(o); + free_def(o); } -inline void radix_sort_int32_t(int32_t* arr, size_t n) { +void radix_sort_int32_t(int32_t* arr, size_t n) { if (n <= 1) return; @@ -165,10 +166,10 @@ void radix_sort_uint32_t(uint32_t* arr, size_t n) { memmove(arr, o, sizeof(uint32_t) * n); } - free(o); + free_def(o); } -inline void radix_sort_int64_t(int64_t* arr, size_t n) { +void radix_sort_int64_t(int64_t* arr, size_t n) { if (n <= 1) return; @@ -212,10 +213,10 @@ void radix_sort_uint64_t(uint64_t* arr, size_t n) { memmove(arr, o, sizeof(uint64_t) * n); } - free(o); + free_def(o); } -inline void radix_sort_ssize_t(ssize_t* arr, size_t n) { +void radix_sort_ssize_t(ssize_t* arr, size_t n) { if (n <= 1) return; @@ -259,7 +260,7 @@ void radix_sort_size_t(size_t* arr, size_t n) { memmove(arr, o, sizeof(size_t) * n); } - free(o); + free_def(o); } void radix_sort_custom(void* arr, size_t n, size_t size, size_t idx_len, radix_index_func idx_func) { @@ -298,46 +299,46 @@ void radix_sort_custom(void* arr, size_t n, size_t size, size_t idx_len, radix_i memmove(a, o, size * n); } - free(o); + free_def(o); } -inline void quicksort_int8_t(int8_t* arr, size_t n) { +void quicksort_int8_t(int8_t* arr, size_t n) { qsort(arr, n, sizeof(int8_t), quicksort_int8_t_compare); } -inline void quicksort_uint8_t(uint8_t* arr, size_t n) { +void quicksort_uint8_t(uint8_t* arr, size_t n) { qsort(arr, n, sizeof(uint8_t), quicksort_uint8_t_compare); } -inline void quicksort_int16_t(int16_t* arr, size_t n) { +void quicksort_int16_t(int16_t* arr, size_t n) { qsort(arr, n, sizeof(int16_t), quicksort_int16_t_compare); } -inline void quicksort_uint16_t(uint16_t* arr, size_t n) { +void quicksort_uint16_t(uint16_t* arr, size_t n) { qsort(arr, n, sizeof(uint16_t), quicksort_uint16_t_compare); } -inline void quicksort_int32_t(int32_t* arr, size_t n) { +void quicksort_int32_t(int32_t* arr, size_t n) { qsort(arr, n, sizeof(int32_t), quicksort_int32_t_compare); } -inline void quicksort_uint32_t(uint32_t* arr, size_t n) { +void quicksort_uint32_t(uint32_t* arr, size_t n) { qsort(arr, n, sizeof(uint32_t), quicksort_uint32_t_compare); } -inline void quicksort_int64_t(int64_t* arr, size_t n) { +void quicksort_int64_t(int64_t* arr, size_t n) { qsort(arr, n, sizeof(int64_t), quicksort_int64_t_compare); } -inline void quicksort_uint64_t(uint64_t* arr, size_t n) { +void quicksort_uint64_t(uint64_t* arr, size_t n) { qsort(arr, n, sizeof(uint64_t), quicksort_uint64_t_compare); } -inline void quicksort_ssize_t(ssize_t* arr, size_t n) { +void quicksort_ssize_t(ssize_t* arr, size_t n) { qsort(arr, n, sizeof(ssize_t), quicksort_ssize_t_compare); } -inline void quicksort_size_t(size_t* arr, size_t n) { +void quicksort_size_t(size_t* arr, size_t n) { qsort(arr, n, sizeof(size_t), quicksort_size_t_compare); } @@ -349,15 +350,19 @@ void quicksort_wchar_t_ptr(wchar_t** arr, size_t n) { qsort(arr, n, sizeof(wchar_t*), quicksort_wchar_t_ptr_compare); } -inline void quicksort_string(std::string* arr, size_t n) { +void quicksort_string(std::string* arr, size_t n) { qsort(arr, n, sizeof(std::string), quicksort_std_string_compare); } -inline void quicksort_wstring(std::wstring* arr, size_t n) { +void quicksort_wstring(std::wstring* arr, size_t n) { qsort(arr, n, sizeof(std::wstring), quicksort_std_wstring_compare); } -inline void quicksort_custom(void* arr, size_t n, size_t s, quicksort_compare_func comp_finc) { +void quicksort_string_hash(string_hash* arr, size_t n) { + qsort(arr, n, sizeof(string_hash), quicksort_string_hash_compare); +} + +void quicksort_custom(void* arr, size_t n, size_t s, quicksort_compare_func comp_finc) { qsort(arr, n, s, comp_finc); } @@ -436,11 +441,17 @@ static int quicksort_wchar_t_ptr_compare(void const* src1, void const* src2) { static int quicksort_std_string_compare(void const* src1, void const* src2) { std::string* str1 = (std::string*)src1; std::string* str2 = (std::string*)src2; - return str_utils_compare_length(str1->c_str(), str1->size(), str2->c_str(), str2->size()); + return str_utils_compare(str1->c_str(), str2->c_str()); } static int quicksort_std_wstring_compare(void const* src1, void const* src2) { std::wstring* str1 = (std::wstring*)src1; std::wstring* str2 = (std::wstring*)src2; - return str_utils_compare_length(str1->c_str(), str1->size(), str2->c_str(), str2->size()); + return str_utils_compare(str1->c_str(), str2->c_str()); +} + +static int quicksort_string_hash_compare(void const* src1, void const* src2) { + string_hash* str1 = (string_hash*)src1; + string_hash* str2 = (string_hash*)src2; + return str_utils_compare(str1->c_str(), str2->c_str()); } diff --git a/src/KKdLib/sort.hpp b/src/KKdLib/sort.hpp index c4fb73d9..422ac707 100644 --- a/src/KKdLib/sort.hpp +++ b/src/KKdLib/sort.hpp @@ -9,6 +9,7 @@ #include #include "default.hpp" +#include "hash.hpp" typedef size_t(*radix_index_func)(void* data, size_t index); typedef int(*quicksort_compare_func)(void const* src1, void const* src2); @@ -77,4 +78,5 @@ extern void quicksort_char_ptr(char** arr, size_t n); extern void quicksort_wchar_t_ptr(wchar_t** arr, size_t n); extern void quicksort_string(std::string* arr, size_t n); extern void quicksort_wstring(std::wstring* arr, size_t n); +extern void quicksort_string_hash(string_hash* arr, size_t n); extern void quicksort_custom(void* arr, size_t n, size_t s, quicksort_compare_func comp_finc); diff --git a/src/KKdLib/sound/diva.cpp b/src/KKdLib/sound/diva.cpp index 4d600a6b..945e92ad 100644 --- a/src/KKdLib/sound/diva.cpp +++ b/src/KKdLib/sound/diva.cpp @@ -5,7 +5,8 @@ #include "diva.hpp" #include "wav.hpp" -#include "../io/stream.hpp" +#include "../io/file_stream.hpp" +#include "../io/path.hpp" #include "../str_utils.hpp" struct ima_storage { @@ -16,6 +17,7 @@ struct ima_storage { static const int8_t ima_index_table[] = { -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8, }; static const int16_t ima_step_table[] = { @@ -33,196 +35,235 @@ static const int16_t ima_step_table[] = { 32767 }; -static void diva_read_wav(diva* d, const wchar_t* path, float_t** data); +static bool diva_read_inner(diva* d, stream& s, float_t*& data); +static void diva_write_inner(diva* d, stream& s, float_t* data); +static void diva_read_wav(diva* d, const wchar_t* path, float_t*& data); static void diva_write_wav(diva* d, const wchar_t* path, float_t* data); static void ima_decode(uint8_t value, ima_storage* storage); static uint8_t ima_encode(int32_t sample, ima_storage* storage); -diva* diva_init() { - diva* d = force_malloc_s(diva, 1); - return d; +diva::diva() : size(), sample_rate(), samples_count(), loop_start(), loop_end(), channels() { + } -void diva_read(diva* d, const char* path) { - wchar_t* path_buf = utf8_to_utf16(path); - diva_read(d, path_buf); - free(path_buf); +diva::~diva() { + } -void diva_read(diva* d, const wchar_t* path) { - wchar_t* path_diva = str_utils_add(path, L".diva"); - stream s; - s.open(path_diva, L"rb"); - if (s.io.stream) { - uint32_t signature = s.read_uint32_t_reverse_endianness(true); - if (signature != 'DIVA') - goto End; +void diva::read(const char* path) { + if (!path) + return; - s.read_uint32_t(); - d->size = s.read_uint32_t(); - d->sample_rate = s.read_uint32_t(); - d->samples_count = s.read_uint32_t(); - d->loop_start = s.read_uint32_t(); - d->loop_end = s.read_uint32_t(); - d->channels = s.read_uint32_t(); - s.set_position(s.get_position() + 0x20, SEEK_SET); - - uint8_t nibble = 0; - uint8_t value = 0; - size_t current_sample = 0; - size_t ch = d->channels; - size_t samples_count = d->samples_count; - - float_t* data = force_malloc_s(float_t, samples_count * ch); - ima_storage* storage = force_malloc_s(ima_storage, ch); - - float_t* temp_data = data; - for (size_t i = 0; i < samples_count; i++) - for (size_t c = 0; c < ch; c++, current_sample++) { - if (~current_sample & 0x01) - value = s.read_uint8_t(); - - nibble = (current_sample & 1 ? value : value >> 4) & 0x0F; - ima_decode(nibble, &storage[c]); - *temp_data++ = (float_t)(storage[c].current / 32768.0); - } - free(storage); - - diva_write_wav(d, path, data); - free(data); + char* path_diva = str_utils_add(path, ".diva"); + file_stream s; + s.open(path_diva, "rb"); + if (s.check_not_null()) { + float_t* data = 0; + if (diva_read_inner(this, s, data)) { + wchar_t* path_temp = utf8_to_utf16(path); + diva_write_wav(this, path_temp, data); + free_def(path_temp); + free_def(data); + } } -End: - free(path_diva); + free_def(path_diva); } -void diva_write(diva* d, const char* path) { - wchar_t* path_buf = utf8_to_utf16(path); - diva_write(d, path_buf); - free(path_buf); +void diva::read(const wchar_t* path) { + if (!path) + return; + + wchar_t* path_diva = str_utils_add(path, L".diva"); + file_stream s; + s.open(path_diva, L"rb"); + if (s.check_not_null()) { + float_t* data = 0; + if (diva_read_inner(this, s, data)) { + diva_write_wav(this, path, data); + free_def(data); + } + } + free_def(path_diva); } -void diva_write(diva* d, const wchar_t* path) { - float_t* data; +void diva::write(const char* path) { + if (!path) + return; - diva_read_wav(d, path, &data); + wchar_t* path_temp = utf8_to_utf16(path); + float_t* data = 0; + diva_read_wav(this, path_temp, data); + if (!data) { + free_def(path_temp); + return; + } + + char* path_diva = str_utils_add(path, ".diva"); + file_stream s; + s.open(path_diva, "wb"); + if (s.check_not_null()) + diva_write_inner(this, s, data); + free_def(path_diva); + free_def(data); + free_def(path_temp); +} + +void diva::write(const wchar_t* path) { + if (!path) + return; + + float_t* data = 0; + diva_read_wav(this, path, data); if (!data) return; wchar_t* path_diva = str_utils_add(path, L".diva"); - stream s; + file_stream s; s.open(path_diva, L"wb"); - if (s.io.stream) { - s.write_uint32_t_reverse_endianness('DIVA', true); - s.write_uint32_t(0); - s.write_uint32_t(align_val_divide(d->samples_count * d->channels, 2, 2)); - s.write_uint32_t(d->sample_rate); - s.write_uint32_t(d->samples_count); - s.write_uint32_t(0); - s.write_uint32_t(0); - s.write_uint32_t(d->channels); - s.write_uint64_t(0); - s.write_uint64_t(0); - s.write_uint64_t(0); - s.write_uint64_t(0); - - uint8_t nibble = 0; - uint8_t value = 0; - size_t current_sample = 0; - size_t ch = d->channels; - size_t samples_count = d->samples_count; - - ima_storage* storage = force_malloc_s(ima_storage, ch); - - float_t* temp_data = data; - for (size_t i = 0; i < samples_count; i++) - for (size_t c = 0; c < ch; c++, current_sample++) { - nibble = ima_encode((int32_t)round(*temp_data++ * 32768.0), &storage[c]); - value |= current_sample & 1 ? nibble : nibble << 4; - if (current_sample & 1) { - s.write_uint8_t(value); - value = 0; - } - } - - if (current_sample & 1) - s.write_uint8_t(value); - free(storage); - } - free(path_diva); - free(data); + if (s.check_not_null()) + diva_write_inner(this, s, data); + free_def(path_diva); + free_def(data); } void diva_dispose(diva* d) { - free(d); + free_def(d); } -static void diva_read_wav(diva* d, const wchar_t* path, float_t** data) { - *data = 0; +static bool diva_read_inner(diva* d, stream& s, float_t*& data) { + uint32_t signature = s.read_uint32_t_reverse_endianness(true); + if (signature != 'DIVA') + return false; + + s.read_uint32_t(); + d->size = s.read_uint32_t(); + d->sample_rate = s.read_uint32_t(); + d->samples_count = s.read_uint32_t(); + d->loop_start = s.read_uint32_t(); + d->loop_end = s.read_uint32_t(); + d->channels = s.read_uint32_t(); + s.set_position(s.get_position() + 0x20, SEEK_SET); + + uint8_t nibble = 0; + uint8_t value = 0; + size_t current_sample = 0; + size_t ch = d->channels; + size_t samples_count = d->samples_count; + + data = force_malloc_s(float_t, samples_count * ch); + ima_storage* storage = force_malloc_s(ima_storage, ch); + + float_t* temp_data = data; + for (size_t i = 0; i < samples_count; i++) + for (size_t c = 0; c < ch; c++, current_sample++) { + if (~current_sample & 0x01) + value = s.read_uint8_t(); + + nibble = (current_sample & 1 ? value : value >> 4) & 0x0F; + ima_decode(nibble, &storage[c]); + *temp_data++ = (float_t)(storage[c].current / 32768.0); + } + free_def(storage); + return true; +} + +static void diva_write_inner(diva* d, stream& s, float_t* data) { + s.write_uint32_t_reverse_endianness('DIVA', true); + s.write_uint32_t(0); + s.write_uint32_t(align_val_divide(d->samples_count * d->channels, 2, 2)); + s.write_uint32_t(d->sample_rate); + s.write_uint32_t(d->samples_count); + s.write_uint32_t(0); + s.write_uint32_t(0); + s.write_uint32_t(d->channels); + s.write_uint64_t(0); + s.write_uint64_t(0); + s.write_uint64_t(0); + s.write_uint64_t(0); + + uint8_t nibble = 0; + uint8_t value = 0; + size_t current_sample = 0; + size_t ch = d->channels; + size_t samples_count = d->samples_count; + + ima_storage* storage = force_malloc_s(ima_storage, ch); + + float_t* temp_data = data; + for (size_t i = 0; i < samples_count; i++) + for (size_t c = 0; c < ch; c++, current_sample++) { + nibble = ima_encode((int32_t)round(*temp_data++ * 32768.0), &storage[c]); + value |= current_sample & 1 ? nibble : nibble << 4; + if (current_sample & 1) { + s.write_uint8_t(value); + value = 0; + } + } + + if (current_sample & 1) + s.write_uint8_t(value); + free_def(storage); +} + +static void diva_read_wav(diva* d, const wchar_t* path, float_t*& data) { + data = 0; size_t samples = 0; wchar_t* path_av = str_utils_add(path, L".wav"); - wav* w = wav_init(); - wav_read(w, path_av, data, &samples); - d->channels = w->channels; - d->sample_rate = w->sample_rate; + wav w; + w.read(path_av, data, samples); + d->channels = w.channels; + d->sample_rate = w.sample_rate; d->samples_count = (uint32_t)samples; - wav_dispose(w); - free(path_av); + free_def(path_av); } static void diva_write_wav(diva* d, const wchar_t* path, float_t* data) { wchar_t* path_av = str_utils_add(path, L".wav"); - wav* w = wav_init(); - w->bytes = 4; - w->channels = d->channels; - w->format = 0x03; - w->sample_rate = d->sample_rate; - wav_write(w, path_av, data, d->samples_count); - wav_dispose(w); - free(path_av); + wav w; + w.bytes = 4; + w.channels = d->channels; + w.format = 0x03; + w.sample_rate = d->sample_rate; + w.write(path_av, data, d->samples_count); + free_def(path_av); } static void ima_decode(uint8_t value, ima_storage* storage) { - int32_t c = storage->current; - int32_t cc = storage->current_clamp; - int32_t si = storage->step_index; - int16_t step = ima_step_table[si]; + int32_t current = storage->current; + int32_t current_clamp = storage->current_clamp; + int32_t step_index = storage->step_index; + int16_t step = ima_step_table[step_index]; int32_t diff = step >> 3; - if ((value & 1) == 1) diff += step >> 2; - if ((value & 2) == 2) diff += step >> 1; - if ((value & 4) == 4) diff += step; + if (value & 1) + diff += step >> 2; + if (value & 2) + diff += step >> 1; + if (value & 4) + diff += step; + if ((value & 8) == 8) + diff = -diff; - if ((value & 8) == 8) { - cc -= diff; - c = cc; - if (cc < -0x8000) - cc = -0x8000; - } - else { - cc += diff; - c = cc; - if (cc > 0x7FFF) - cc = 0x7FFF; - } + current_clamp += diff; + current = current_clamp; + current_clamp = clamp_def(current_clamp, -0x8000, 0x7FFF); - si += ima_index_table[value & 0x07]; - if (si < 0) - si = 0; - if (si > 88) - si = 88; - storage->current = c; - storage->current_clamp = cc; - storage->step_index = si; + step_index += ima_index_table[value]; + step_index = clamp_def(step_index, 0, 88); + + storage->current = current; + storage->current_clamp = current_clamp; + storage->step_index = step_index; } static uint8_t ima_encode(int32_t sample, ima_storage* storage) { - int32_t c = storage->current; - int32_t cc = storage->current_clamp; - int32_t si = storage->step_index; + int32_t current = storage->current; + int32_t current_clamp = storage->current_clamp; + int32_t step_index = storage->step_index; uint8_t value = 0; - int16_t step = ima_step_table[si]; + int16_t step = ima_step_table[step_index]; - int32_t delta = sample - c; + int32_t delta = sample - current; if (delta < 0) { value |= 8; @@ -249,26 +290,18 @@ static uint8_t ima_encode(int32_t sample, ima_storage* storage) { diff += step; } - if ((value & 8) == 8) { - cc -= diff; - c = cc; - if (cc < -0x8000) - cc = -0x8000; - } - else { - cc += diff; - c = cc; - if (cc > 0x7FFF) - cc = 0x7FFF; - } + if ((value & 8) == 8) + diff = -diff; - si += ima_index_table[value & 0x07]; - if (si < 0) - si = 0; - if (si > 88) - si = 88; - storage->current = c; - storage->current_clamp = cc; - storage->step_index = si; + current_clamp += diff; + current = current_clamp; + current_clamp = clamp_def(current_clamp, -0x8000, 0x7FFF); + + step_index += ima_index_table[value]; + step_index = clamp_def(step_index, 0, 88); + + storage->current = current; + storage->current_clamp = current_clamp; + storage->step_index = step_index; return value; } diff --git a/src/KKdLib/sound/diva.hpp b/src/KKdLib/sound/diva.hpp index 9c0c0914..af4ec496 100644 --- a/src/KKdLib/sound/diva.hpp +++ b/src/KKdLib/sound/diva.hpp @@ -14,11 +14,12 @@ struct diva { uint32_t loop_start; uint32_t loop_end; uint32_t channels; -}; -extern diva* diva_init(); -extern void diva_read(diva* d, const char* path); -extern void diva_read(diva* d, const wchar_t* path); -extern void diva_write(diva* d, const char* path); -extern void diva_write(diva* d, const wchar_t* path); -extern void diva_dispose(diva* d); + diva(); + virtual ~diva(); + + void read(const char* path); + void read(const wchar_t* path); + void write(const char* path); + void write(const wchar_t* path); +}; diff --git a/src/KKdLib/sound/vag.cpp b/src/KKdLib/sound/vag.cpp index e220cf70..e60ea372 100644 --- a/src/KKdLib/sound/vag.cpp +++ b/src/KKdLib/sound/vag.cpp @@ -5,96 +5,154 @@ #include "vag.hpp" #include "wav.hpp" +#include "../io/file_stream.hpp" #include "../io/path.hpp" -#include "../io/stream.hpp" #include "../str_utils.hpp" +#include static const int8_t shift_factor_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1 }; -static const int16_t hevag1_table[] = { - 0, 7680, 14720, 12544, 15616, 14731, 14507, 13920, - 13133, 12028, 10764, 9359, 7832, 6201, 4488, 2717, - 910, -910, -2717, -4488, -6201, -7832, -9359, -10764, - -12028, -13133, -13920, -14507, -14731, 5376, -6400, -10496, - -167, -7430, -8001, 6018, 3798, -8237, 9199, 13021, - 13112, -1668, 7819, 9571, 10032, -4745, -5896, -1193, - 2783, -7334, 6127, 9457, 7876, -7172, -7358, -9170, - -2638, 1873, 9214, 13204, 12437, -2653, 9331, 1642, - 4246, -8988, -2562, 3182, 7937, 10069, 8400, -8529, - 9477, 75, -9143, -7270, -2740, 8993, 13101, 9543, - 5272, -7696, 7309, 10275, 10940, 24, -8122, -8511, - 326, 8895, 12073, 8729, 12950, 10038, 9385, -4720, - 7869, 2450, 10192, 11313, 10154, 9638, 3854, 6699, - 11082, -1026, 10396, 10287, 7953, 12689, 6641, -2348, - 9290, 4633, 11247, 9807, 9736, 8440, 9307, 1698, - 10214, 8390, 7201, -88, 6193, 12325, 13064, 5333, -}; - -static const int16_t hevag2_table[] = { - 0, 0, -6656, -7040, -7680, -7059, -7366, -7522, - -7680, -7680, -7680, -7680, -7680, -7680, -7680, -7680, - -7680, -7680, -7680, -7680, -7680, -7680, -7680, -7680, - -7680, -7680, -7522, -7366, -7059, -9216, -7168, -7424, - -2722, -2221, -3166, -4750, -6946, -2596, 1982, -3044, - -4487, -3744, -4328, -1336, -2562, -4122, 2378, -9117, - -7108, -2062, -2577, -1858, -4483, -1795, -2102, -3509, - -2647, 9183, 1859, -3012, -4792, -1144, -1048, -620, - -7585, -3891, -2735, -483, -3844, -2609, -3297, -2775, - -1882, -2241, -4160, -1958, 3745, 1948, -2835, -1961, - -4270, -3383, 2523, -2867, -3721, -310, -2411, -3067, - -3846, 2194, -1876, -3423, -3847, -2570, -2757, -5006, - -4326, -8597, -2763, -4213, -2716, -1417, -4554, -5659, - -3908, -9810, -3746, 988, 3878, -3375, 3166, -7354, - -4039, -6403, -4125, -2284, -1536, -3436, -1021, -9025, - -2791, 3248, 3316, -7809, -5189, -1290, -4075, 2999, -}; - -static const int16_t hevag3_table[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3328, -3328, -3584, - -494, -2298, -2814, 2649, 3875, -2071, -1382, -3792, - -2250, -6456, 2111, -757, 300, -5486, -4787, -1237, - -1575, -2212, -315, 102, 2126, -2069, -2233, -2674, - -1929, 1860, -1124, -4139, -256, -3182, -828, -946, - -533, -2807, -1730, -714, 2821, 314, 1551, -2432, - 108, -298, -2963, -2156, 5936, -683, -3854, 130, - 3124, -2907, 434, 391, 665, -1262, -2311, -2337, - 419, -541, -2017, 1674, -3007, 302, 1008, -2852, - 2135, 1299, 360, 833, 345, -737, 2843, 2249, - 728, -805, 1367, -1915, -764, -3354, 231, -1944, - 1885, 1748, 802, 219, -706, 1562, -835, 688, - 368, -758, 46, -538, 2760, -3284, -2824, 775, -}; - -static const int16_t hevag4_table[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -3072, -2304, -1024, - -541, 424, 289, -1298, -1216, 227, -2316, 1267, - 1665, 840, -506, 487, 199, -1493, -6947, -3114, - -1447, 446, -18, 258, -538, 482, 440, -391, - -1637, -5746, -2427, 1370, 622, -6878, 507, -4229, - -2259, 44, -1899, -1421, -1019, 195, -155, -336, - 256, -6937, 5, 460, -1089, -2704, 1055, 250, - -3157, -456, -2461, 172, 97, 320, -271, 163, - -933, -2880, -601, -169, 1946, 198, 41, -1161, - -501, -2780, 181, 53, 185, 482, -3397, -1074, - 80, -3462, -96, -1437, -3263, 2079, -2089, -4122, - -246, -1619, 61, 222, 473, -176, 509, -3037, - 179, -2989, -2614, -4571, -1245, 253, 1877, -1132, +static const int16_t hevag_table[128][4] = { + { 0, 0, 0, 0 }, + { 7680, 0, 0, 0 }, + { 14720, -6656, 0, 0 }, + { 12544, -7040, 0, 0 }, + { 15616, -7680, 0, 0 }, + { 14731, -7059, 0, 0 }, + { 14507, -7366, 0, 0 }, + { 13920, -7522, 0, 0 }, + { 13133, -7680, 0, 0 }, + { 12028, -7680, 0, 0 }, + { 10764, -7680, 0, 0 }, + { 9359, -7680, 0, 0 }, + { 7832, -7680, 0, 0 }, + { 6201, -7680, 0, 0 }, + { 4488, -7680, 0, 0 }, + { 2717, -7680, 0, 0 }, + { 910, -7680, 0, 0 }, + { -910, -7680, 0, 0 }, + { -2717, -7680, 0, 0 }, + { -4488, -7680, 0, 0 }, + { -6201, -7680, 0, 0 }, + { -7832, -7680, 0, 0 }, + { -9359, -7680, 0, 0 }, + { -10764, -7680, 0, 0 }, + { -12028, -7680, 0, 0 }, + { -13133, -7680, 0, 0 }, + { -13920, -7522, 0, 0 }, + { -14507, -7366, 0, 0 }, + { -14731, -7059, 0, 0 }, + { 5376, -9216, 3328, -3072 }, + { -6400, -7168, -3328, -2304 }, + { -10496, -7424, -3584, -1024 }, + { -167, -2722, -494, -541 }, + { -7430, -2221, -2298, 424 }, + { -8001, -3166, -2814, 289 }, + { 6018, -4750, 2649, -1298 }, + { 3798, -6946, 3875, -1216 }, + { -8237, -2596, -2071, 227 }, + { 9199, 1982, -1382, -2316 }, + { 13021, -3044, -3792, 1267 }, + { 13112, -4487, -2250, 1665 }, + { -1668, -3744, -6456, 840 }, + { 7819, -4328, 2111, -506 }, + { 9571, -1336, -757, 487 }, + { 10032, -2562, 300, 199 }, + { -4745, -4122, -5486, -1493 }, + { -5896, 2378, -4787, -6947 }, + { -1193, -9117, -1237, -3114 }, + { 2783, -7108, -1575, -1447 }, + { -7334, -2062, -2212, 446 }, + { 6127, -2577, -315, -18 }, + { 9457, -1858, 102, 258 }, + { 7876, -4483, 2126, -538 }, + { -7172, -1795, -2069, 482 }, + { -7358, -2102, -2233, 440 }, + { -9170, -3509, -2674, -391 }, + { -2638, -2647, -1929, -1637 }, + { 1873, 9183, 1860, -5746 }, + { 9214, 1859, -1124, -2427 }, + { 13204, -3012, -4139, 1370 }, + { 12437, -4792, -256, 622 }, + { -2653, -1144, -3182, -6878 }, + { 9331, -1048, -828, 507 }, + { 1642, -620, -946, -4229 }, + { 4246, -7585, -533, -2259 }, + { -8988, -3891, -2807, 44 }, + { -2562, -2735, -1730, -1899 }, + { 3182, -483, -714, -1421 }, + { 7937, -3844, 2821, -1019 }, + { 10069, -2609, 314, 195 }, + { 8400, -3297, 1551, -155 }, + { -8529, -2775, -2432, -336 }, + { 9477, -1882, 108, 256 }, + { 75, -2241, -298, -6937 }, + { -9143, -4160, -2963, 5 }, + { -7270, -1958, -2156, 460 }, + { -2740, 3745, 5936, -1089 }, + { 8993, 1948, -683, -2704 }, + { 13101, -2835, -3854, 1055 }, + { 9543, -1961, 130, 250 }, + { 5272, -4270, 3124, -3157 }, + { -7696, -3383, -2907, -456 }, + { 7309, 2523, 434, -2461 }, + { 10275, -2867, 391, 172 }, + { 10940, -3721, 665, 97 }, + { 24, -310, -1262, 320 }, + { -8122, -2411, -2311, -271 }, + { -8511, -3067, -2337, 163 }, + { 326, -3846, 419, -933 }, + { 8895, 2194, -541, -2880 }, + { 12073, -1876, -2017, -601 }, + { 8729, -3423, 1674, -169 }, + { 12950, -3847, -3007, 1946 }, + { 10038, -2570, 302, 198 }, + { 9385, -2757, 1008, 41 }, + { -4720, -5006, -2852, -1161 }, + { 7869, -4326, 2135, -501 }, + { 2450, -8597, 1299, -2780 }, + { 10192, -2763, 360, 181 }, + { 11313, -4213, 833, 53 }, + { 10154, -2716, 345, 185 }, + { 9638, -1417, -737, 482 }, + { 3854, -4554, 2843, -3397 }, + { 6699, -5659, 2249, -1074 }, + { 11082, -3908, 728, 80 }, + { -1026, -9810, -805, -3462 }, + { 10396, -3746, 1367, -96 }, + { 10287, 988, -1915, -1437 }, + { 7953, 3878, -764, -3263 }, + { 12689, -3375, -3354, 2079 }, + { 6641, 3166, 231, -2089 }, + { -2348, -7354, -1944, -4122 }, + { 9290, -4039, 1885, -246 }, + { 4633, -6403, 1748, -1619 }, + { 11247, -4125, 802, 61 }, + { 9807, -2284, 219, 222 }, + { 9736, -1536, -706, 473 }, + { 8440, -3436, 1562, -176 }, + { 9307, -1021, -835, 509 }, + { 1698, -9025, 688, -3037 }, + { 10214, -2791, 368, 179 }, + { 8390, 3248, -758, -2989 }, + { 7201, 3316, 46, -2614 }, + { -88, -7809, -538, -4571 }, + { 6193, -5189, 2760, -1245 }, + { 12325, -1290, -3284, 253 }, + { 13064, -4075, -2824, 1877 }, + { 5333, 2999, 775, -1132 }, }; #define BLOCK_SIZE 28 -static void vag_read_wav_straight(vag* v, const wchar_t* path, float_t** data, size_t* samples); -static void vag_read_wav(vag* v, const wchar_t* path, float_t** data, size_t* samples, uint8_t** flags); -static void vag_write_wav_straight(vag* v, const wchar_t* path, float_t* data, size_t num_blocks, uint8_t* flags); -static void vag_write_wav(vag* v, const wchar_t* path, float_t* data, size_t num_blocks, uint8_t* flags); +static bool vag_read_inner(vag* v, stream& s, float_t*& data, size_t& num_blocks, uint8_t*& flags); +static void vag_write_inner(vag* v, stream& s, const float_t* data, const uint8_t* flags, vag_option option); +static void vag_read_wav_straight(vag* v, const wchar_t* path, float_t*& data, size_t& samples); +static void vag_read_wav(vag* v, const wchar_t* path, float_t*& data, size_t& samples, uint8_t*& flags); +static void vag_write_wav_straight(vag* v, const wchar_t* path, const float_t* data, size_t num_blocks, const uint8_t* flags); +static void vag_write_wav(vag* v, const wchar_t* path, const float_t* data, size_t num_blocks, const uint8_t* flags); static void calculate_4_bits_vag(int32_t* data, int8_t* four_bit, int32_t* coef_index, int32_t* shift_factor, int32_t* v, int32_t* tv, int32_t coef_index_count); static void calculate_4_bits_hevag(int32_t* data, int8_t* four_bit, int32_t* coef_index, @@ -104,297 +162,335 @@ static void calculate_4_bits_vag_inner(int32_t* data, int8_t* four_bit, int32_t static void calculate_4_bits_hevag_inner(int32_t* data, int8_t* four_bit, int32_t coef_index, int32_t* shift_factor, int32_t* v, int32_t* tv, int32_t* os, int32_t* ots); -vag* vag_init() { - vag* v = force_malloc_s(vag, 1); - return v; +vag::vag() : version(), sample_rate(), channels(), size() { + } -void vag_read(vag* v, const char* path) { - wchar_t* path_buf = utf8_to_utf16(path); - vag_read(v, path_buf); - free(path_buf); +vag::~vag() { + } -void vag_read(vag* v, const wchar_t* path) { - wchar_t* path_vag = str_utils_add(path, L".vag"); - stream s; - s.open(path_vag, L"rb"); - if (s.io.stream) { - uint32_t signature = s.read_uint32_t_reverse_endianness(true); - if (signature != 'VAGp') - goto End; - - v->version = s.read_uint32_t_reverse_endianness(true); - s.read_uint32_t(); - v->size = s.read_uint32_t_reverse_endianness(true); - v->sample_rate = s.read_uint32_t_reverse_endianness(true); - s.read_uint32_t(); - s.read_uint32_t(); - s.read_uint16_t(); - v->channels = s.read_uint16_t(); - if (v->channels < 2) - v->channels = 1; - s.read_uint64_t(); - s.read_uint64_t(); - - bool hevag = v->version == 0x00020001 || v->version == 0x00030000; - if (!hevag) - v->channels = 1; - - size_t ch = v->channels; - size_t vag_block_size = BLOCK_SIZE * ch; - - size_t num_blocks = (v->size / v->channels) >> 4; - int32_t* samp = force_malloc_s(int32_t, ch * 4); - float_t* data = force_malloc_s(float_t, num_blocks * vag_block_size); - uint8_t* flags = force_malloc_s(uint8_t, num_blocks); - - uint8_t nibble[BLOCK_SIZE]; - float_t* temp_data = data; - int16_t hevag1, hevag2, hevag3, hevag4; - int32_t s1, s2, s3, s4, sample; - size_t c, i, i1, i2; - uint8_t coef_index, d, shift_factor; - for (i1 = 0; i1 < num_blocks; i1++, temp_data += vag_block_size) - for (c = 0; c < ch; c++) { - d = s.read_uint8_t(); - coef_index = (d & 0xF0) >> 4; - shift_factor = d & 0x0F; - d = s.read_uint8_t(); - coef_index = (d & 0xF0) | coef_index; - flags[i1] = d & 0x0F; - - if (coef_index > 127) - coef_index = 0; - - for (i = 0, i2 = 1; i < BLOCK_SIZE; i += 2, i2 += 2) { - d = s.read_uint8_t(); - nibble[i] = d & 0x0F; - nibble[i2] = (d & 0xF0) >> 4; - } - - hevag1 = hevag1_table[coef_index]; - hevag2 = hevag2_table[coef_index]; - hevag3 = hevag3_table[coef_index]; - hevag4 = hevag4_table[coef_index]; - s1 = samp[c * 4 + 0]; - s2 = samp[c * 4 + 1]; - s3 = samp[c * 4 + 2]; - s4 = samp[c * 4 + 3]; - shift_factor = 20 - shift_factor; - for (i = 0; i < BLOCK_SIZE; i++) { - sample = shift_factor_table[nibble[i]] << shift_factor; - sample += (s1 * hevag1 + s2 * hevag2 + s3 * hevag3 + s4 * hevag4) >> 5; - s4 = s3; - s3 = s2; - s2 = s1; - s1 = sample >> 8; - temp_data[i * ch + c] = (float_t)(sample / 8388608.0); - } - samp[c * 4 + 0] = s1; - samp[c * 4 + 1] = s2; - samp[c * 4 + 2] = s3; - samp[c * 4 + 3] = s4; - } - free(samp); - - vag_write_wav(v, path, data, num_blocks, flags); - free(flags); - free(data); +void vag::read(const char* path) { + char* path_vag = str_utils_add(path, ".vag"); + file_stream s; + s.open(path_vag, "rb"); + if (s.check_not_null()) { + float_t* data; + size_t num_blocks; + uint8_t* flags; + if (vag_read_inner(this, s, data, num_blocks, flags)) { + wchar_t* path_temp = utf8_to_utf16(path); + vag_write_wav(this, path_temp, data, num_blocks, flags); + free_def(path_temp); + free_def(flags); + free_def(data); + } } -End: - free(path_vag); + free_def(path_vag); } -void vag_write(vag* v, const char* path, vag_option option) { - wchar_t* path_buf = utf8_to_utf16(path); - vag_write(v, path_buf, option); - free(path_buf); +void vag::read(const wchar_t* path) { + wchar_t* path_vag = str_utils_add(path, L".vag"); + file_stream s; + s.open(path_vag, L"rb"); + if (s.check_not_null()) { + float_t* data; + size_t num_blocks; + uint8_t* flags; + if (vag_read_inner(this, s, data, num_blocks, flags)) { + vag_write_wav(this, path, data, num_blocks, flags); + free_def(flags); + free_def(data); + } + } + free_def(path_vag); } -void vag_write(vag* v, const wchar_t* path, vag_option option) { - size_t num_samples; +void vag::write(const char* path, vag_option option) { float_t* data; + size_t num_samples; uint8_t* flags; - vag_read_wav(v, path, &data, &num_samples, &flags); + wchar_t* path_temp = utf8_to_utf16(path); + vag_read_wav(this, path_temp, data, num_samples, flags); + free_def(path_temp); if (!data || !num_samples) return; - v->size = align_val_divide(num_samples, BLOCK_SIZE, BLOCK_SIZE); + size = align_val_divide(num_samples, BLOCK_SIZE, BLOCK_SIZE); - wchar_t* temp_path = str_utils_get_without_extension(path); - wchar_t* path_vag = str_utils_add(temp_path, L".vag"); - stream s; + char* path_vag = str_utils_add(path, ".vag"); + file_stream s; + s.open(path_vag, "wb"); + if (s.check_not_null()) + vag_write_inner(this, s, data, flags, option); + free_def(path_vag); + free_def(flags); + free_def(data); +} + +void vag::write(const wchar_t* path, vag_option option) { + float_t* data; + size_t num_samples; + uint8_t* flags; + + vag_read_wav(this, path, data, num_samples, flags); + if (!data || !num_samples) + return; + + size = align_val_divide(num_samples, BLOCK_SIZE, BLOCK_SIZE); + + wchar_t* path_vag = str_utils_add(path, L".vag"); + file_stream s; s.open(path_vag, L"wb"); - if (s.io.stream) { - int32_t coef_index_count; - switch (option) { - case VAG_OPTION_HEVAG_FAST: - coef_index_count = 16; - break; - case VAG_OPTION_HEVAG_MEDIUM: - coef_index_count = 32; - break; - case VAG_OPTION_HEVAG_SLOW: - coef_index_count = 64; - break; - case VAG_OPTION_HEVAG_SLOWEST: - coef_index_count = 96; - break; - case VAG_OPTION_HEVAG_SLOWASHELL: - coef_index_count = 128; - break; - default: - coef_index_count = 5; - break; - } + if (s.check_not_null()) + vag_write_inner(this, s, data, flags, option); + free_def(path_vag); + free_def(flags); + free_def(data); +} - bool hevag = option != VAG_OPTION_VAG; - s.write_uint32_t_reverse_endianness('VAGp', true); - s.write_uint32_t_reverse_endianness(hevag ? 0x00020001 : 0x00000020, true); - s.write_uint32_t(0); - s.write_uint32_t_reverse_endianness((uint32_t)(((v->size + 1) * (hevag ? v->channels : 1)) << 4), true); - s.write_uint32_t_reverse_endianness(v->sample_rate, true); - s.write_uint32_t(0); - s.write_uint32_t(0); - s.write_uint16_t(0); - s.write_uint16_t(hevag ? v->channels : 1); - s.write_uint64_t(0); - s.write_uint64_t(0); +static bool vag_read_inner(vag* v, stream& s, float_t*& data, size_t& num_blocks, uint8_t*& flags) { + data = 0; + num_blocks = 0; + flags = 0; - size_t c, i, i1, i2; - int32_t ch = v->channels; - int32_t* samp = force_malloc_s(int32_t, hevag ? v->channels * 8ULL : 4ULL); - if (hevag && coef_index_count > 29) { - uint8_t flag, sample; - int32_t temp_data[BLOCK_SIZE]; - int8_t four_bit[BLOCK_SIZE]; - int32_t coef_index, shift_factor; - size_t size = v->size; - for (i1 = 0; i1 < size; i1++) - for (c = 0; c < ch; c++) { - for (i = 0; i < BLOCK_SIZE; i++) { - float_t t_s = data[i1 * BLOCK_SIZE * ch + i * ch + c]; - temp_data[i] = (int32_t)round(t_s * 8388608.0); - } + uint32_t signature = s.read_uint32_t_reverse_endianness(true); + if (signature != 'VAGp') + return false; - calculate_4_bits_hevag(temp_data, four_bit, &coef_index, - &shift_factor, samp + c * 8, samp + c * 8 + 4, coef_index_count); + v->version = s.read_uint32_t_reverse_endianness(true); + s.read_uint32_t(); + v->size = s.read_uint32_t_reverse_endianness(true); + v->sample_rate = s.read_uint32_t_reverse_endianness(true); + s.read_uint32_t(); + s.read_uint32_t(); + s.read_uint16_t(); + v->channels = s.read_uint16_t(); + if (v->channels < 2) + v->channels = 1; + s.read_uint64_t(); + s.read_uint64_t(); - flag = flags ? (flags[i1] & 0x0F) : (i1 + 1 == size) ? 0x01 : 0; - sample = ((coef_index & 0x0F) << 4) | (shift_factor & 0x0F); - s.write_uint8_t(sample); - sample = (coef_index & 0xF0) | flag; - s.write_uint8_t(sample); - for (i = 0, i2 = 1; i < BLOCK_SIZE; i += 2, i2 += 2) { - sample = ((four_bit[i2] & 0x0F) << 4) | (four_bit[i] & 0x0F); - s.write_uint8_t(sample); - } - } - for (c = 0; c < ch; c++) { - s.write_uint64_t(0x7777777777770700); - s.write_uint64_t(0x7777777777777777); + bool is_hevag = v->version == 0x00020001 || v->version == 0x00030000; + if (!is_hevag) + v->channels = 1; + + size_t ch = v->channels; + size_t vag_block_size = BLOCK_SIZE * ch; + + num_blocks = (v->size / v->channels) >> 4; + int32_t* samp = force_malloc_s(int32_t, ch * 4); + data = force_malloc_s(float_t, num_blocks * vag_block_size); + flags = force_malloc_s(uint8_t, num_blocks); + + uint8_t nibble[BLOCK_SIZE]; + float_t* temp_data = data; + int16_t hevag1, hevag2, hevag3, hevag4; + int32_t s1, s2, s3, s4, sample; + size_t c, i, i1, i2, j; + uint8_t coef_index, d, shift_factor; + for (i1 = 0; i1 < num_blocks; i1++, temp_data += vag_block_size) + for (c = 0; c < ch; c++) { + d = s.read_uint8_t(); + coef_index = (d & 0xF0) >> 4; + shift_factor = d & 0x0F; + d = s.read_uint8_t(); + coef_index = (d & 0x70) | coef_index; + flags[i1] = d & 0x0F; + + if (coef_index > 127) + coef_index = 0; + + for (i = 0, i2 = 1, j = BLOCK_SIZE; j; i += 2, i2 += 2, j -= 2) { + d = s.read_uint8_t(); + nibble[i] = d & 0x0F; + nibble[i2] = (d & 0xF0) >> 4; } - } - else if (hevag) { - uint8_t flag, sample; - int32_t temp_data[BLOCK_SIZE]; - int8_t four_bit[BLOCK_SIZE]; - int32_t coef_index, shift_factor; - size_t size = v->size; - for (i1 = 0; i1 < size; i1++) - for (c = 0; c < ch; c++) { - for (i = 0; i < BLOCK_SIZE; i++) { - float_t t_s = data[i1 * BLOCK_SIZE * ch + i * ch + c]; - temp_data[i] = (int32_t)round(t_s * 8388608.0); - } - calculate_4_bits_vag(temp_data, four_bit, &coef_index, - &shift_factor, samp + c * 4, samp + c * 4 + 2, coef_index_count); - - flag = flags ? (flags[i1] & 0x0F) : (i1 + 1 == size) ? 0x01 : 0; - sample = ((coef_index & 0x0F) << 4) | (shift_factor & 0x0F); - s.write_uint8_t(sample); - sample = (coef_index & 0xF0) | flag; - s.write_uint8_t(sample); - for (i = 0, i2 = 1; i < BLOCK_SIZE; i += 2, i2 += 2) { - sample = ((four_bit[i2] & 0x0F) << 4) | (four_bit[i] & 0x0F); - s.write_uint8_t(sample); - } - } - - for (c = 0; c < ch; c++) { - s.write_uint64_t(0x7777777777770700); - s.write_uint64_t(0x7777777777777777); + hevag1 = hevag_table[coef_index][0]; + hevag2 = hevag_table[coef_index][1]; + hevag3 = hevag_table[coef_index][2]; + hevag4 = hevag_table[coef_index][3]; + s1 = samp[c * 4 + 0]; + s2 = samp[c * 4 + 1]; + s3 = samp[c * 4 + 2]; + s4 = samp[c * 4 + 3]; + shift_factor = 20 - shift_factor; + for (i = 0, j = BLOCK_SIZE; j; i++, j--) { + sample = shift_factor_table[nibble[i]] << shift_factor; + sample += (s1 * hevag1 + s2 * hevag2 + s3 * hevag3 + s4 * hevag4) >> 5; + s4 = s3; + s3 = s2; + s2 = s1; + s1 = sample >> 8; + temp_data[i * ch + c] = (float_t)((double_t)sample / 8388608.0); } - } - else { - uint8_t flag, sample; - int32_t temp_data[BLOCK_SIZE]; - int8_t four_bit[BLOCK_SIZE]; - int32_t coef_index, shift_factor; - size_t size = v->size; - for (i1 = 0; i1 < size; i1++) { - for (i = 0; i < BLOCK_SIZE; i++) { - float_t t_s = 0.0f; - for (c = 0; c < ch; c++) - t_s += data[i1 * BLOCK_SIZE * ch + i * ch + c]; - t_s /= ch; + samp[c * 4 + 0] = s1; + samp[c * 4 + 1] = s2; + samp[c * 4 + 2] = s3; + samp[c * 4 + 3] = s4; + } + free_def(samp); + return true; +} + +static void vag_write_inner(vag* v, stream& s, const float_t* data, const uint8_t* flags, vag_option option) { + int32_t coef_index_count; + switch (option) { + case VAG_OPTION_HEVAG_FAST: + coef_index_count = 16; + break; + case VAG_OPTION_HEVAG_MEDIUM: + coef_index_count = 32; + break; + case VAG_OPTION_HEVAG_SLOW: + coef_index_count = 64; + break; + case VAG_OPTION_HEVAG_SLOWEST: + coef_index_count = 96; + break; + case VAG_OPTION_HEVAG_SLOWASHELL: + coef_index_count = 128; + break; + default: + coef_index_count = 5; + break; + } + + bool hevag = option != VAG_OPTION_VAG; + s.write_uint32_t_reverse_endianness('VAGp', true); + s.write_uint32_t_reverse_endianness(hevag ? 0x00020001 : 0x00000020, true); + s.write_uint32_t(0); + s.write_uint32_t_reverse_endianness((uint32_t)(((v->size + 1) * (hevag ? v->channels : 1)) << 4), true); + s.write_uint32_t_reverse_endianness(v->sample_rate, true); + s.write_uint32_t(0); + s.write_uint32_t(0); + s.write_uint16_t(0); + s.write_uint16_t(hevag ? v->channels : 1); + s.write_uint64_t(0); + s.write_uint64_t(0); + + size_t c, i, i1, i2, j; + int32_t ch = v->channels; + int32_t* samp = force_malloc_s(int32_t, hevag ? v->channels * 8ULL : 4ULL); + if (hevag && coef_index_count > 29) { + uint8_t flag, sample; + int32_t temp_data[BLOCK_SIZE]; + int8_t four_bit[BLOCK_SIZE]; + int32_t coef_index, shift_factor; + size_t size = v->size; + for (i1 = 0; i1 < size; i1++) + for (c = 0; c < ch; c++) { + for (i = 0, j = BLOCK_SIZE; j; i++, j--) { + float_t t_s = data[i1 * BLOCK_SIZE * ch + i * ch + c]; temp_data[i] = (int32_t)round(t_s * 8388608.0); } - calculate_4_bits_vag(temp_data, four_bit, &coef_index, - &shift_factor, samp, samp + 2, coef_index_count); - - for (i = 0, i2 = 0; i < BLOCK_SIZE; i++) - if (!four_bit[i]) - i2++; + calculate_4_bits_hevag(temp_data, four_bit, &coef_index, + &shift_factor, samp + c * 8, samp + c * 8 + 4, coef_index_count); flag = flags ? (flags[i1] & 0x0F) : (i1 + 1 == size) ? 0x01 : 0; sample = ((coef_index & 0x0F) << 4) | (shift_factor & 0x0F); s.write_uint8_t(sample); sample = (coef_index & 0xF0) | flag; s.write_uint8_t(sample); - for (i = 0, i2 = 1; i < BLOCK_SIZE; i += 2, i2 += 2) { + for (i = 0, i2 = 1, j = BLOCK_SIZE; j; i += 2, i2 += 2, j -= 2) { sample = ((four_bit[i2] & 0x0F) << 4) | (four_bit[i] & 0x0F); s.write_uint8_t(sample); } } + + for (c = 0; c < ch; c++) { s.write_uint64_t(0x7777777777770700); s.write_uint64_t(0x7777777777777777); } - s.write_uint64_t(0x1010101010101010); - s.write_uint64_t(0x1010101010101010); - free(samp); } - free(path_vag); - free(temp_path); - free(flags); - free(data); + else if (hevag) { + uint8_t flag, sample; + int32_t temp_data[BLOCK_SIZE]; + int8_t four_bit[BLOCK_SIZE]; + int32_t coef_index, shift_factor; + size_t size = v->size; + for (i1 = 0; i1 < size; i1++) + for (c = 0; c < ch; c++) { + for (i = 0, j = BLOCK_SIZE; j; i++, j--) { + float_t t_s = data[i1 * BLOCK_SIZE * ch + i * ch + c]; + temp_data[i] = (int32_t)round(t_s * 8388608.0); + } + + calculate_4_bits_vag(temp_data, four_bit, &coef_index, + &shift_factor, samp + c * 4, samp + c * 4 + 2, coef_index_count); + + flag = flags ? (flags[i1] & 0x0F) : (i1 + 1 == size) ? 0x01 : 0; + sample = ((coef_index & 0x0F) << 4) | (shift_factor & 0x0F); + s.write_uint8_t(sample); + sample = (coef_index & 0xF0) | flag; + s.write_uint8_t(sample); + for (i = 0, i2 = 1, j = BLOCK_SIZE; j; i += 2, i2 += 2, j -= 2) { + sample = ((four_bit[i2] & 0x0F) << 4) | (four_bit[i] & 0x0F); + s.write_uint8_t(sample); + } + } + + for (c = 0; c < ch; c++) { + s.write_uint64_t(0x7777777777770700); + s.write_uint64_t(0x7777777777777777); + } + } + else { + uint8_t flag, sample; + int32_t temp_data[BLOCK_SIZE]; + int8_t four_bit[BLOCK_SIZE]; + int32_t coef_index, shift_factor; + size_t size = v->size; + for (i1 = 0; i1 < size; i1++) { + for (i = 0, j = BLOCK_SIZE; j; i++, j--) { + float_t t_s = 0.0f; + for (c = 0; c < ch; c++) + t_s += data[i1 * BLOCK_SIZE * ch + i * ch + c]; + t_s /= ch; + temp_data[i] = (int32_t)round(t_s * 8388608.0); + } + + calculate_4_bits_vag(temp_data, four_bit, &coef_index, + &shift_factor, samp, samp + 2, coef_index_count); + + flag = flags ? (flags[i1] & 0x0F) : (i1 + 1 == size) ? 0x01 : 0; + sample = ((coef_index & 0x0F) << 4) | (shift_factor & 0x0F); + s.write_uint8_t(sample); + sample = (coef_index & 0xF0) | flag; + s.write_uint8_t(sample); + for (i = 0, i2 = 1, j = BLOCK_SIZE; j; i += 2, i2 += 2, j -= 2) { + sample = ((four_bit[i2] & 0x0F) << 4) | (four_bit[i] & 0x0F); + s.write_uint8_t(sample); + } + } + s.write_uint64_t(0x7777777777770700); + s.write_uint64_t(0x7777777777777777); + } + s.write_uint64_t(0x1010101010101010); + s.write_uint64_t(0x1010101010101010); + free_def(samp); } -void vag_dispose(vag* v) { - free(v); +static void vag_read_wav_straight(vag* v, const wchar_t* path, float_t*& data, size_t& samples) { + data = 0; + samples = 0; + wchar_t* path_wav = str_utils_add(path, L".wav"); + wav w; + w.read(path_wav, data, samples); + v->channels = w.channels; + v->sample_rate = w.sample_rate; + free_def(path_wav); } -static void vag_read_wav_straight(vag* v, const wchar_t* path, float_t** data, size_t* samples) { - *data = 0; - *samples = 0; - wchar_t* path_av = str_utils_add(path, L".wav"); - wav* w = wav_init(); - wav_read(w, path_av, data, samples); - v->channels = w->channels; - v->sample_rate = w->sample_rate; - wav_dispose(w); - free(path_av); -} +static void vag_read_wav(vag* v, const wchar_t* path, float_t*& data, size_t& samples, uint8_t*& flags) { + data = 0; + samples = 0; + flags = 0; -static void vag_read_wav(vag* v, const wchar_t* path, float_t** data, size_t* samples, uint8_t** flags) { - *data = 0; - *samples = 0; - *flags = 0; if (!str_utils_check_ends_with(path, L".0")) { vag_read_wav_straight(v, path, data, samples); return; @@ -425,7 +521,7 @@ static void vag_read_wav(vag* v, const wchar_t* path, float_t** data, size_t* sa } if (!count) { - free(temp_path); + free_def(temp_path); return; } @@ -433,42 +529,39 @@ static void vag_read_wav(vag* v, const wchar_t* path, float_t** data, size_t* sa float_t** wav_data = force_malloc_s(float_t*, count); size_t* wav_samples = force_malloc_s(size_t, count); - wav* w = wav_init(); for (size_t i = 0; i < count; i++) { if (add_loop && i + 1 == count) continue; swprintf_s(temp, MAX_PATH, loop[i] ? L"%ls.%llu.loop.wav" : L"%ls.%llu.wav", temp_path, i); - wav_read(w, temp, &wav_data[i], &wav_samples[i]); + wav w; + w.read(temp, wav_data[i], wav_samples[i]); if (i == 0) { - v->channels = w->channels; - v->sample_rate = w->sample_rate; + v->channels = w.channels; + v->sample_rate = w.sample_rate; } - else if (v->channels != w->channels || v->sample_rate != w->sample_rate) { - wav_dispose(w); - + else if (v->channels != w.channels || v->sample_rate != w.sample_rate) { for (size_t i1 = 0; i1 <= i; i1++) - free(wav_data[i1]); + free_def(wav_data[i1]); - free(wav_samples); - free(wav_data); - free(temp_path); + free_def(wav_samples); + free_def(wav_data); + free_def(temp_path); return; } } - wav_dispose(w); - *samples = 0; + samples = 0; for (size_t i = 0; i < count; i++) if (add_loop && i + 1 == count) - *samples += BLOCK_SIZE; + samples += BLOCK_SIZE; else - *samples += align_val(wav_samples[i], BLOCK_SIZE); + samples += align_val(wav_samples[i], BLOCK_SIZE); l = false; size_t ch = v->channels; - *data = force_malloc_s(float_t, *samples * ch); - float_t* data_temp = *data; + data = force_malloc_s(float_t, samples * ch); + float_t* data_temp = data; for (size_t i = 0; i < count; i++) { size_t i3; if (add_loop && i + 1 == count) @@ -486,8 +579,8 @@ static void vag_read_wav(vag* v, const wchar_t* path, float_t** data, size_t* sa } l = false; - *flags = force_malloc_s(uint8_t, *samples / BLOCK_SIZE); - uint8_t* f = *flags; + flags = force_malloc_s(uint8_t, samples / BLOCK_SIZE); + uint8_t* f = flags; for (size_t i = 0; i < count; i++) { size_t num_blocks; if (add_loop && i + 1 == count) @@ -521,14 +614,14 @@ static void vag_read_wav(vag* v, const wchar_t* path, float_t** data, size_t* sa } for (size_t i = 0; i < count; i++) - free(wav_data[i]); + free_def(wav_data[i]); - free(wav_samples); - free(wav_data); - free(temp_path); + free_def(wav_samples); + free_def(wav_data); + free_def(temp_path); } -static void vag_write_wav_straight(vag* v, const wchar_t* path, float_t* data, size_t num_blocks, uint8_t* flags) { +static void vag_write_wav_straight(vag* v, const wchar_t* path, const float_t* data, size_t num_blocks, const uint8_t* flags) { size_t i = 0; for (i = 0; i < num_blocks; i++) { uint8_t flag = flags[i]; @@ -540,34 +633,28 @@ static void vag_write_wav_straight(vag* v, const wchar_t* path, float_t* data, s break; } - wchar_t* path_av = str_utils_add(path, L".wav"); - wav* w = wav_init(); - w->bytes = 4; - w->channels = v->channels; - w->format = 0x03; - w->sample_rate = v->sample_rate; - wav_write(w, path_av, data, i * BLOCK_SIZE); - wav_dispose(w); - free(path_av); + wchar_t* path_wav = str_utils_add(path, L".wav"); + wav w; + w.bytes = 4; + w.channels = v->channels; + w.format = 0x03; + w.sample_rate = v->sample_rate; + w.write(path_wav, data, i * BLOCK_SIZE); + free_def(path_wav); } -static void vag_write_wav(vag* v, const wchar_t* path, float_t* data, size_t num_blocks, uint8_t* flags) { +static void vag_write_wav(vag* v, const wchar_t* path, const float_t* data, size_t num_blocks, const uint8_t* flags) { uint8_t flag = flags[0]; if (flag == 5 || flag == 7) return; wchar_t temp[MAX_PATH]; - wav* w = wav_init(); - w->bytes = 4; - w->channels = v->channels; - w->format = 0x03; - w->sample_rate = v->sample_rate; bool loop = false; size_t i = 0, i2 = 0; size_t ch = v->channels; size_t vag_block_size = BLOCK_SIZE * ch; - float_t* temp_data = data; - float_t* temp_data_last = data; + const float_t* temp_data = data; + const float_t* temp_data_last = data; for (size_t i1 = 0; i1 < num_blocks; i1++, temp_data += vag_block_size) { flag = flags[i1]; if (flag == 5 || flag == 7) @@ -575,7 +662,12 @@ static void vag_write_wav(vag* v, const wchar_t* path, float_t* data, size_t num else if (flag == 3 || flag == 6) { if (i) { swprintf_s(temp, MAX_PATH, loop ? L"%ls.%llu.loop.wav" : L"%ls.%llu.wav", path, i2); - wav_write(w, temp, temp_data_last, i * BLOCK_SIZE); + wav w; + w.bytes = 4; + w.channels = v->channels; + w.format = 0x03; + w.sample_rate = v->sample_rate; + w.write(temp, temp_data_last, i * BLOCK_SIZE); i2++; } @@ -592,29 +684,34 @@ static void vag_write_wav(vag* v, const wchar_t* path, float_t* data, size_t num if (i) { swprintf_s(temp, MAX_PATH, L"%ls.%llu.wav", path, i2); - wav_write(w, temp, temp_data_last, i * BLOCK_SIZE); + wav w; + w.bytes = 4; + w.channels = v->channels; + w.format = 0x03; + w.sample_rate = v->sample_rate; + w.write(temp, temp_data_last, i * BLOCK_SIZE); } - wav_dispose(w); } static void calculate_4_bits_vag(int32_t* data, int8_t* four_bit, int32_t* coef_index, int32_t* shift_factor, int32_t* v, int32_t* tv, int32_t coef_index_count) { - int32_t d0, e, g, i, j; + int32_t d0, e, g, i, j, k, l; int32_t err, min, s1, s2, c_f; c_f = 0; min = 0x7FFFFFFF; - for (j = 0; j < coef_index_count; j++) { + for (j = 0, l = coef_index_count; l; j++, l--) { calculate_4_bits_vag_inner(data, four_bit, j, shift_factor, v, tv, 0, 0); - int32_t vag1 = hevag1_table[j]; - int32_t vag2 = hevag2_table[j]; + int32_t vag1 = hevag_table[j][0]; + int32_t vag2 = hevag_table[j][1]; + int32_t _shift_factor = *shift_factor; s1 = v[0]; s2 = v[1]; err = 0; - for (i = 0; i < BLOCK_SIZE; i++) { - d0 = four_bit[i] << *shift_factor; + for (i = 0, k = BLOCK_SIZE; k; i++, k--) { + d0 = four_bit[i] << _shift_factor; g = ((s1 * vag1 + s2 * vag2) >> 5) + d0; s2 = s1; @@ -637,15 +734,15 @@ static void calculate_4_bits_vag(int32_t* data, int8_t* four_bit, int32_t* coef_ static void calculate_4_bits_vag_inner(int32_t* data, int8_t* four_bit, int32_t coef_index, int32_t* shift_factor, int32_t* v, int32_t* tv, int32_t* os, int32_t* ots) { - int32_t d0, d1, e, g, i, s_f, t_s_f, m, shift_max; + int32_t d0, d1, e, g, i, j, s_f, t_s_f, m, shift_max; int32_t temp[BLOCK_SIZE]; - int32_t vag1 = hevag1_table[coef_index]; - int32_t vag2 = hevag2_table[coef_index]; + int32_t vag1 = hevag_table[coef_index][0]; + int32_t vag2 = hevag_table[coef_index][1]; int32_t s1 = v[0]; int32_t s2 = v[1]; - for (i = 0, m = 0; i < BLOCK_SIZE; i++) { + for (i = 0, j = BLOCK_SIZE, m = 0; j; i++, j--) { g = data[i]; e = (s1 * vag1 + s2 * vag2) >> 5; e = g - e; @@ -670,7 +767,7 @@ static void calculate_4_bits_vag_inner(int32_t* data, int8_t* four_bit, int32_t os[1] = s2; } - for (s_f = 12, shift_max = 0x400000; s_f > 0; s_f--, shift_max >>= 1) + for (s_f = 12, shift_max = 0x400000; s_f; s_f--, shift_max >>= 1) if ((shift_max & (m + (shift_max >> 4))) == shift_max) break; @@ -679,7 +776,7 @@ static void calculate_4_bits_vag_inner(int32_t* data, int8_t* four_bit, int32_t int32_t ts1 = tv[0]; int32_t ts2 = tv[1]; - for (i = 0; i < BLOCK_SIZE; i++) { + for (i = 0, j = BLOCK_SIZE; j; i++, j--) { g = temp[i]; e = (ts1 * vag1 + ts2 * vag2) >> 5; e = g - e; @@ -708,26 +805,26 @@ static void calculate_4_bits_vag_inner(int32_t* data, int8_t* four_bit, int32_t static void calculate_4_bits_hevag(int32_t* data, int8_t* four_bit, int32_t* coef_index, int32_t* shift_factor, int32_t* v, int32_t* tv, int32_t coef_index_count) { - int32_t d0, e, g, i, j; + int32_t d0, e, g, i, j, k, l; int32_t err, min, s1, s2, s3, s4, c_f; c_f = 0; min = 0x7FFFFFFF; - for (j = 0; j < coef_index_count; j++) { + for (j = 0, l = coef_index_count; l; j++, l--) { calculate_4_bits_hevag_inner(data, four_bit, j, shift_factor, v, tv, 0, 0); - int32_t hevag1 = hevag1_table[j]; - int32_t hevag2 = hevag2_table[j]; - int32_t hevag3 = hevag3_table[j]; - int32_t hevag4 = hevag4_table[j]; - + int32_t hevag1 = hevag_table[j][0]; + int32_t hevag2 = hevag_table[j][1]; + int32_t hevag3 = hevag_table[j][2]; + int32_t hevag4 = hevag_table[j][3]; s1 = v[0]; s2 = v[1]; s3 = v[2]; s4 = v[3]; + int32_t _shift_factor = *shift_factor; err = 0; - for (i = 0; i < BLOCK_SIZE; i++) { - d0 = four_bit[i] << *shift_factor; + for (i = 0, k = BLOCK_SIZE; k; i++, k--) { + d0 = four_bit[i] << _shift_factor; g = ((s1 * hevag1 + s2 * hevag2 + s3 * hevag3 + s4 * hevag4) >> 5) + d0; s4 = s3; @@ -752,22 +849,21 @@ static void calculate_4_bits_hevag(int32_t* data, int8_t* four_bit, int32_t* coe static void calculate_4_bits_hevag_inner(int32_t* data, int8_t* four_bit, int32_t coef_index, int32_t* shift_factor, int32_t* v, int32_t* tv, int32_t* os, int32_t* ots) { - int32_t d0, d1, e, g, i, s_f, t_s_f, m, shift_max; + int32_t d0, d1, e, g, i, j, s_f, t_s_f, m, shift_max; int32_t temp[BLOCK_SIZE]; - int32_t hevag1 = hevag1_table[coef_index]; - int32_t hevag2 = hevag2_table[coef_index]; - int32_t hevag3 = hevag3_table[coef_index]; - int32_t hevag4 = hevag4_table[coef_index]; + int32_t hevag1 = hevag_table[coef_index][0]; + int32_t hevag2 = hevag_table[coef_index][1]; + int32_t hevag3 = hevag_table[coef_index][2]; + int32_t hevag4 = hevag_table[coef_index][3]; int32_t s1 = v[0]; int32_t s2 = v[1]; int32_t s3 = v[2]; int32_t s4 = v[3]; - for (i = 0, m = 0; i < BLOCK_SIZE; i++) { + for (i = 0, j = BLOCK_SIZE, m = 0; j; i++, j--) { g = data[i]; - e = (s1 * hevag1 + s2 * hevag2 + s3 * hevag3 + s4 * hevag4) >> 5; - e = g - e; + e = g - ((s1 * hevag1 + s2 * hevag2 + s3 * hevag3 + s4 * hevag4) >> 5); s4 = s3; s3 = s2; s2 = s1; @@ -793,7 +889,7 @@ static void calculate_4_bits_hevag_inner(int32_t* data, int8_t* four_bit, int32_ os[3] = s4; } - for (s_f = 12, shift_max = 0x400000; s_f > 0; s_f--, shift_max >>= 1) + for (s_f = 12, shift_max = 0x400000; s_f; s_f--, shift_max >>= 1) if ((shift_max & (m + (shift_max >> 4))) == shift_max) break; @@ -804,10 +900,10 @@ static void calculate_4_bits_hevag_inner(int32_t* data, int8_t* four_bit, int32_ int32_t ts2 = tv[1]; int32_t ts3 = tv[2]; int32_t ts4 = tv[3]; - for (i = 0; i < BLOCK_SIZE; i++) { + + for (i = 0, j = BLOCK_SIZE; j; i++, j--) { g = temp[i]; - e = (ts1 * hevag1 + ts2 * hevag2 + ts3 * hevag3 + ts4 * hevag4) >> 5; - e = g - e; + e = g - ((ts1 * hevag1 + ts2 * hevag2 + ts3 * hevag3 + ts4 * hevag4) >> 5); d1 = e << s_f; d0 = (d1 + 0x80000) >> 20; @@ -825,6 +921,7 @@ static void calculate_4_bits_hevag_inner(int32_t* data, int8_t* four_bit, int32_ ts2 = ts1; ts1 = (d0 - e) >> 8; } + *shift_factor = t_s_f; if (ots) { diff --git a/src/KKdLib/sound/vag.hpp b/src/KKdLib/sound/vag.hpp index 9198d0b0..b068e4de 100644 --- a/src/KKdLib/sound/vag.hpp +++ b/src/KKdLib/sound/vag.hpp @@ -22,11 +22,12 @@ struct vag { uint32_t sample_rate; uint32_t channels; size_t size; -}; -extern vag* vag_init(); -extern void vag_read(vag* v, const char* path); -extern void vag_read(vag* v, const wchar_t* path); -extern void vag_write(vag* v, const char* path, vag_option option); -extern void vag_write(vag* v, const wchar_t* path, vag_option option); -extern void vag_dispose(vag* f); + vag(); + virtual ~vag(); + + void read(const char* path); + void read(const wchar_t* path); + void write(const char* path, vag_option option); + void write(const wchar_t* path, vag_option option); +}; diff --git a/src/KKdLib/sound/wav.cpp b/src/KKdLib/sound/wav.cpp index 08eee041..13fcb5d9 100644 --- a/src/KKdLib/sound/wav.cpp +++ b/src/KKdLib/sound/wav.cpp @@ -4,211 +4,241 @@ */ #include "wav.hpp" -#include "../io/stream.hpp" +#include "../io/file_stream.hpp" + +static void wav_read_inner(wav* w, stream& s, float_t*& data, size_t& samples); +static void wav_write_inner(wav* w, stream& s, const float_t* data, size_t samples); + +wav::wav() : size(), sample_rate(), header_size(), +channel_mask(), is_supported(), bytes(), format(), channels() { + +} + +wav::~wav() { + +} + +void wav::read(const char* path, float_t*& data, size_t& samples) { + data = 0; + samples = 0; + + if (!path) + return; + + file_stream s; + s.open(path, "rb"); + if (s.check_not_null()) + wav_read_inner(this, s, data, samples); +} + +void wav::read(const wchar_t* path, float_t*& data, size_t& samples) { + data = 0; + samples = 0; + + if (!path) + return; + + file_stream s; + s.open(path, L"rb"); + if (s.check_not_null()) + wav_read_inner(this, s, data, samples); +} + +void wav::write(const char* path, const float_t* data, size_t samples) { + if (!data || !samples || !path) + return; + + file_stream s; + s.open(path, "wb"); + if (s.check_not_null()) + wav_write_inner(this, s, data, samples); +} + +void wav::write(const wchar_t* path, const float_t* data, size_t samples) { + if (!data || !samples || !path) + return; + + file_stream s; + s.open(path, L"wb"); + if (s.check_not_null()) + wav_write_inner(this, s, data, samples); +} wav* wav_init() { wav* w = force_malloc_s(wav, 1); return w; } -void wav_read(wav* w, const char* path, float_t** data, size_t* samples) { - wchar_t* path_buf = utf8_to_utf16(path); - wav_read(w, path_buf, data, samples); - free(path_buf); -} +static void wav_read_inner(wav* w, stream& s, float_t*& data, size_t& samples) { + wav w_t; + if (s.read_uint32_t() != 0x46464952) + return; + s.read_uint32_t(); + if (s.read_uint32_t() != 0x45564157 || s.read_uint32_t() != 0x20746D66) + return; + size_t offset = s.read_uint32_t(); + w_t.format = s.read_uint16_t(); + if (w_t.format != 0x01 && w_t.format != 0x03 && w_t.format != 0xFFFE) + return; -void wav_read(wav* w, const wchar_t* path, float_t** data, size_t* samples) { - *data = 0; - *samples = 0; - memset(w, 0, sizeof(wav)); - - stream s; - s.open(path, L"rb"); - if (s.io.stream) { - wav w_t; - if (s.read_uint32_t() != 0x46464952) - return; + w_t.channels = s.read_uint16_t(); + w_t.sample_rate = s.read_uint32_t(); + s.read_uint32_t(); + s.read_uint16_t(); + w_t.bytes = s.read_uint16_t(); + if (w_t.bytes % 8 || !(w_t.bytes / 8)) + return; + if (w_t.format == 0xFFFE) { s.read_uint32_t(); - if (s.read_uint32_t() != 0x45564157 || s.read_uint32_t() != 0x20746D66) - return; - size_t offset = s.read_uint32_t(); + w_t.channel_mask = s.read_uint32_t(); w_t.format = s.read_uint16_t(); - if (w_t.format != 0x01 && w_t.format != 0x03 && w_t.format != 0xFFFE) - return; - - w_t.channels = s.read_uint16_t(); - w_t.sample_rate = s.read_uint32_t(); - s.read_uint32_t(); - s.read_uint16_t(); - w_t.bytes = s.read_uint16_t(); - if (w_t.bytes % 8 || !(w_t.bytes / 8)) - return; - if (w_t.format == 0xFFFE) { - s.read_uint32_t(); - w_t.channel_mask = s.read_uint32_t(); - w_t.format = s.read_uint16_t(); - } - - w_t.bytes >>= 3; - if (w_t.bytes < 1 || (w_t.bytes > 4 && w_t.bytes != 8)) - return; - else if (w_t.bytes > 0 && w_t.bytes < 4 && w_t.format == 3) - return; - else if (w_t.bytes == 8 && w_t.format == 1) - return; - - s.set_position(offset + 0x14, SEEK_SET); - if (s.read_uint32_t() != 0x61746164) - return; - w_t.size = s.read_uint32_t(); - w_t.header_size = (int32_t)s.get_position(); - w_t.is_supported = true; - *w = w_t; - - *samples = w->size / w->channels / w->bytes; - *data = force_malloc_s(float_t, w->size / w->bytes); - - size_t t_s = *samples; - float_t* t_d = *data; - - size_t ch = w->channels; - if (w->bytes == 0x01 && w->format == 0x01) - for (size_t i = 0; i < t_s; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = s.read_int8_t(); - sample = div_min_max(sample, -128.0, 127.0); - t_d[i * ch + c] = (float_t)sample; - } - else if (w->bytes == 0x02 && (w->format == 0x01 || w->format == 0xFFFE)) - for (size_t i = 0; i < t_s; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = s.read_int16_t(); - sample = div_min_max(sample, -32768.0, 32767.0); - t_d[i * ch + c] = (float_t)sample; - } - else if (w->bytes == 0x03 && w->format == 0x01) - for (size_t i = 0; i < t_s; i++) - for (size_t c = 0; c < ch; c++) { - int32_t samp; - s.read(&samp, 3); - double_t sample = (samp << 8) >> 8; - sample = div_min_max(sample, -8388608.0, 8388607.0); - t_d[i * ch + c] = (float_t)sample; - } - else if (w->bytes == 0x04 && w->format == 0x01) - for (size_t i = 0; i < t_s; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = s.read_int32_t(); - sample = div_min_max(sample, -2147483648.0, 2147483647.0); - t_d[i * ch + c] = (float_t)sample; - } - else if (w->bytes == 0x04 && (w->format == 0x03 || w->format == 0xFFFE)) - for (size_t i = 0; i < t_s; i++) - for (size_t c = 0; c < ch; c++) { - float_t sample = s.read_float_t(); - t_d[i * ch + c] = sample; - } - else if (w->bytes == 0x08 && (w->format == 0x03 || w->format == 0xFFFE)) - for (size_t i = 0; i < t_s; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = s.read_double_t(); - t_d[i * ch + c] = (float_t)sample; - } } + + w_t.bytes >>= 3; + if (w_t.bytes < 1 || (w_t.bytes > 4 && w_t.bytes != 8)) + return; + else if (w_t.bytes > 0 && w_t.bytes < 4 && w_t.format == 3) + return; + else if (w_t.bytes == 8 && w_t.format == 1) + return; + + s.set_position(offset + 0x14, SEEK_SET); + if (s.read_uint32_t() != 0x61746164) + return; + w_t.size = s.read_uint32_t(); + w_t.header_size = (int32_t)s.get_position(); + w_t.is_supported = true; + *w = w_t; + + samples = w->size / w->channels / w->bytes; + data = force_malloc_s(float_t, w->size / w->bytes); + + size_t t_s = samples; + float_t* t_d = data; + + size_t ch = w->channels; + if (w->bytes == 0x01 && w->format == 0x01) + for (size_t i = 0; i < t_s; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = s.read_int8_t(); + sample = div_min_max_def(sample, -128.0, 127.0); + t_d[i * ch + c] = (float_t)sample; + } + else if (w->bytes == 0x02 && (w->format == 0x01 || w->format == 0xFFFE)) + for (size_t i = 0; i < t_s; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = s.read_int16_t(); + sample = div_min_max_def(sample, -32768.0, 32767.0); + t_d[i * ch + c] = (float_t)sample; + } + else if (w->bytes == 0x03 && w->format == 0x01) + for (size_t i = 0; i < t_s; i++) + for (size_t c = 0; c < ch; c++) { + int32_t samp; + s.read(&samp, 3); + double_t sample = (samp << 8) >> 8; + sample = div_min_max_def(sample, -8388608.0, 8388607.0); + t_d[i * ch + c] = (float_t)sample; + } + else if (w->bytes == 0x04 && w->format == 0x01) + for (size_t i = 0; i < t_s; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = s.read_int32_t(); + sample = div_min_max_def(sample, -2147483648.0, 2147483647.0); + t_d[i * ch + c] = (float_t)sample; + } + else if (w->bytes == 0x04 && (w->format == 0x03 || w->format == 0xFFFE)) + for (size_t i = 0; i < t_s; i++) + for (size_t c = 0; c < ch; c++) { + float_t sample = s.read_float_t(); + t_d[i * ch + c] = sample; + } + else if (w->bytes == 0x08 && (w->format == 0x03 || w->format == 0xFFFE)) + for (size_t i = 0; i < t_s; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = s.read_double_t(); + t_d[i * ch + c] = (float_t)sample; + } } -void wav_write(wav* w, const char* path, float_t* data, size_t samples) { - wchar_t* path_buf = utf8_to_utf16(path); - wav_write(w, path_buf, data, samples); - free(path_buf); -} +static void wav_write_inner(wav* w, stream& s, const float_t* data, size_t samples) { + w->size = (int32_t)(samples * w->channels * w->bytes); -void wav_write(wav* w, const wchar_t* path, float_t* data, size_t samples) { - stream s; - s.open(path, L"wb"); - if (s.io.stream && data) { - w->size = (int32_t)(samples * w->channels * w->bytes); + if (w->bytes == 0x01 && w->format == 0x01); + else if (w->bytes == 0x02 && w->format == 0x01); + else if (w->bytes == 0x04 && w->format == 0x01); + else if (w->bytes == 0x04 && (w->format == 0x03 || w->format == 0xFFFE)); + else if (w->bytes == 0x08 && (w->format == 0x03 || w->format == 0xFFFE)); + else + w->size = 0; - if (w->bytes == 0x01 && w->format == 0x01); - else if (w->bytes == 0x02 && w->format == 0x01); - else if (w->bytes == 0x04 && w->format == 0x01); - else if (w->bytes == 0x04 && (w->format == 0x03 || w->format == 0xFFFE)); - else if (w->bytes == 0x08 && (w->format == 0x03 || w->format == 0xFFFE)); - else - w->size = 0; - - s.write_uint32_t(0x46464952); - s.write_uint32_t(w->size + (w->format != 0xFFFE ? 0x24 : 0x3C)); - s.write_uint32_t(0x45564157); - s.write_uint32_t(0x20746D66); - s.write_uint32_t(w->format != 0xFFFE ? 0x10 : 0x28); - s.write_uint16_t(w->format); - s.write_uint16_t(w->channels); - s.write_uint32_t(w->sample_rate); - s.write_uint32_t(w->sample_rate * w->channels * w->bytes); - s.write_uint16_t((uint16_t)(w->channels * w->bytes)); + s.write_uint32_t(0x46464952); + s.write_uint32_t(w->size + (w->format != 0xFFFE ? 0x24 : 0x3C)); + s.write_uint32_t(0x45564157); + s.write_uint32_t(0x20746D66); + s.write_uint32_t(w->format != 0xFFFE ? 0x10 : 0x28); + s.write_uint16_t(w->format); + s.write_uint16_t(w->channels); + s.write_uint32_t(w->sample_rate); + s.write_uint32_t(w->sample_rate * w->channels * w->bytes); + s.write_uint16_t((uint16_t)(w->channels * w->bytes)); + s.write_uint16_t((uint16_t)(w->bytes << 3)); + if (w->format == 0xFFFE) { + s.write_uint16_t(0x16); s.write_uint16_t((uint16_t)(w->bytes << 3)); - if (w->format == 0xFFFE) { - s.write_uint16_t(0x16); - s.write_uint16_t((uint16_t)(w->bytes << 3)); - s.write_uint32_t(w->channel_mask); - s.write_uint32_t(w->bytes == 2 ? 0x01 : 0x03); - s.write_uint32_t(0x00100000); - s.write_uint32_t(0xAA000080); - s.write_uint32_t(0x719B3800); - } - s.write_uint32_t(0x61746164); - s.write_uint32_t(w->size); - - size_t ch = w->channels; - if (w->bytes == 0x01 && w->format == 0x01) - for (size_t i = 0; i < samples; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = data[i * ch + c]; - sample = clamp(sample, -1.0, 1.0); - sample = mult_min_max(sample, -128.0, 127.0); - s.write_int8_t((int8_t)round(sample)); - } - else if (w->bytes == 0x02 && (w->format == 0x01 || w->format == 0xFFFE)) - for (size_t i = 0; i < samples; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = data[i * ch + c]; - sample = clamp(sample, -1.0, 1.0); - sample = mult_min_max(sample, -32768.0, 32767.0); - s.write_int16_t((int16_t)round(sample)); - } - else if (w->bytes == 0x03 && w->format == 0x01) - for (size_t i = 0; i < samples; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = data[i * ch + c]; - sample = clamp(sample, -1.0, 1.0); - sample = mult_min_max(sample, -8388608.0, 8388607.0); - int32_t samp = (int32_t)round(sample); - s.write(&samp, 3); - } - else if (w->bytes == 0x04 && w->format == 0x01) - for (size_t i = 0; i < samples; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = data[i * ch + c]; - sample = clamp(sample, -1.0, 1.0); - sample = mult_min_max(sample, -2147483648.0, 2147483647.0); - s.write_int32_t((int32_t)round(sample)); - } - else if (w->bytes == 0x04 && (w->format == 0x03 || w->format == 0xFFFE)) - for (size_t i = 0; i < samples; i++) - for (size_t c = 0; c < ch; c++) { - float_t sample = data[i * ch + c]; - s.write_float_t(sample); - } - else if (w->bytes == 0x08 && (w->format == 0x03 || w->format == 0xFFFE)) - for (size_t i = 0; i < samples; i++) - for (size_t c = 0; c < ch; c++) { - double_t sample = data[i * ch + c]; - s.write_double_t(sample); - } + s.write_uint32_t(w->channel_mask); + s.write_uint32_t(w->bytes == 2 ? 0x01 : 0x03); + s.write_uint32_t(0x00100000); + s.write_uint32_t(0xAA000080); + s.write_uint32_t(0x719B3800); } -} + s.write_uint32_t(0x61746164); + s.write_uint32_t(w->size); -void wav_dispose(wav* f) { - free(f); -} \ No newline at end of file + size_t ch = w->channels; + if (w->bytes == 0x01 && w->format == 0x01) + for (size_t i = 0; i < samples; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = data[i * ch + c]; + sample = clamp_def(sample, -1.0, 1.0); + sample = mult_min_max_def(sample, -128.0, 127.0); + s.write_int8_t((int8_t)round(sample)); + } + else if (w->bytes == 0x02 && (w->format == 0x01 || w->format == 0xFFFE)) + for (size_t i = 0; i < samples; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = data[i * ch + c]; + sample = clamp_def(sample, -1.0, 1.0); + sample = mult_min_max_def(sample, -32768.0, 32767.0); + s.write_int16_t((int16_t)round(sample)); + } + else if (w->bytes == 0x03 && w->format == 0x01) + for (size_t i = 0; i < samples; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = data[i * ch + c]; + sample = clamp_def(sample, -1.0, 1.0); + sample = mult_min_max_def(sample, -8388608.0, 8388607.0); + int32_t samp = (int32_t)round(sample); + s.write(&samp, 3); + } + else if (w->bytes == 0x04 && w->format == 0x01) + for (size_t i = 0; i < samples; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = data[i * ch + c]; + sample = clamp_def(sample, -1.0, 1.0); + sample = mult_min_max_def(sample, -2147483648.0, 2147483647.0); + s.write_int32_t((int32_t)round(sample)); + } + else if (w->bytes == 0x04 && (w->format == 0x03 || w->format == 0xFFFE)) + for (size_t i = 0; i < samples; i++) + for (size_t c = 0; c < ch; c++) { + float_t sample = data[i * ch + c]; + s.write_float_t(sample); + } + else if (w->bytes == 0x08 && (w->format == 0x03 || w->format == 0xFFFE)) + for (size_t i = 0; i < samples; i++) + for (size_t c = 0; c < ch; c++) { + double_t sample = data[i * ch + c]; + s.write_double_t(sample); + } +} diff --git a/src/KKdLib/sound/wav.hpp b/src/KKdLib/sound/wav.hpp index ba35244e..e39d0f8d 100644 --- a/src/KKdLib/sound/wav.hpp +++ b/src/KKdLib/sound/wav.hpp @@ -16,11 +16,12 @@ struct wav { uint16_t bytes; uint16_t format; uint16_t channels; -}; -extern wav* wav_init(); -extern void wav_read(wav* w, const char* path, float_t** data, size_t* samples); -extern void wav_read(wav* w, const wchar_t* path, float_t** data, size_t* samples); -extern void wav_write(wav* w, const char* path, float_t* data, size_t samples); -extern void wav_write(wav* w, const wchar_t* path, float_t* data, size_t samples); -extern void wav_dispose(wav* w); + wav(); + virtual ~wav(); + + void read(const char* path, float_t*& data, size_t& samples); + void read(const wchar_t* path, float_t*& data, size_t& samples); + void write(const char* path, const float_t* data, size_t samples); + void write(const wchar_t* path, const float_t* data, size_t samples); +}; diff --git a/src/KKdLib/str_utils.cpp b/src/KKdLib/str_utils.cpp index 32f40127..fc06153e 100644 --- a/src/KKdLib/str_utils.cpp +++ b/src/KKdLib/str_utils.cpp @@ -419,14 +419,6 @@ wchar_t* str_utils_copy(const wchar_t* str) { return p; } -inline int32_t str_utils_compare(const char* str0, const char* str1) { - return strcmp(str0, str1); -} - -inline int32_t str_utils_compare(const wchar_t* str0, const wchar_t* str1) { - return wcscmp(str0, str1); -} - inline int32_t str_utils_compare_length(const char* str0, size_t str0_len, const char* str1, size_t str1_len) { if (!str0_len) return -*str1; @@ -550,16 +542,16 @@ size_t str_utils_get_substring_offset(const wchar_t* str0, size_t str0_len, } bool str_utils_text_file_parse(const void* data, size_t size, - char** buf, char*** lines, size_t* count) { - if (!data || !size || !buf || !lines || !count) + char*& buf, char**& lines, size_t& count) { + if (!data || !size) return false; const char* d = (const char*)data; bool del = false; size_t c; - *buf = 0; - *lines = 0; - *count = 0; + buf = 0; + lines = 0; + count = 0; if ((uint8_t)d[0] == 0x00) return false; else if (d[0] == 0xFF) { @@ -584,7 +576,7 @@ bool str_utils_text_file_parse(const void* data, size_t size, d = utf16_to_utf8(w_d); size = utf8_length(d); del = true; - free(w_d); + free_def(w_d); goto decode_utf8_ansi; } else if ((uint8_t)d[0] == 0xEF) { @@ -681,14 +673,14 @@ bool str_utils_text_file_parse(const void* data, size_t size, } } - *buf = temp_buf; - *lines = temp_lines; - *count = c; + buf = temp_buf; + lines = temp_lines; + count = c; } if (del) { void* data = (void*)d; - free(data); + free_def(data); } return true; } diff --git a/src/KKdLib/str_utils.hpp b/src/KKdLib/str_utils.hpp index 021d34e0..798c01e8 100644 --- a/src/KKdLib/str_utils.hpp +++ b/src/KKdLib/str_utils.hpp @@ -8,6 +8,14 @@ #include #include "default.hpp" +inline int32_t str_utils_compare(const char* str0, const char* str1) { + return strcmp(str0, str1); +} + +inline int32_t str_utils_compare(const wchar_t* str0, const wchar_t* str1) { + return wcscmp(str0, str1); +} + extern bool str_utils_check_ends_with(const char* str, const char* mask); extern bool str_utils_check_ends_with(const wchar_t* str, const wchar_t* mask); extern const char* str_utils_get_next_int32_t(const char* str, int32_t& value, char separator); @@ -40,8 +48,6 @@ extern char* str_utils_add(const char* str0, const char* str1); extern wchar_t* str_utils_add(const wchar_t* str0, const wchar_t* str1); extern char* str_utils_copy(const char* str); extern wchar_t* str_utils_copy(const wchar_t* str); -extern int32_t str_utils_compare(const char* str0, const char* str1); -extern int32_t str_utils_compare(const wchar_t* str0, const wchar_t* str1); extern int32_t str_utils_compare_length(const char* str0, size_t str0_len, const char* str1, size_t str1_len); extern int32_t str_utils_compare_length(const wchar_t* str0, size_t str0_len, const wchar_t* str1, size_t str1_len); extern size_t str_utils_get_substring_offset(const char* str0, size_t str0_len, @@ -49,4 +55,4 @@ extern size_t str_utils_get_substring_offset(const char* str0, size_t str0_len, extern size_t str_utils_get_substring_offset(const wchar_t* str0, size_t str0_len, size_t str0_off, const wchar_t* str1, size_t str1_len); extern bool str_utils_text_file_parse(const void* data, size_t size, - char** buf, char*** lines, size_t* count); + char*& buf, char**& lines, size_t& count); diff --git a/src/KKdLib/txp.cpp b/src/KKdLib/txp.cpp index 873392ac..198ec97e 100644 --- a/src/KKdLib/txp.cpp +++ b/src/KKdLib/txp.cpp @@ -5,7 +5,7 @@ #include "txp.hpp" #include "f2/struct.hpp" -#include "io/stream.hpp" +#include "io/memory_stream.hpp" txp_mipmap::txp_mipmap() : width(), height(), format(), size() { @@ -116,9 +116,9 @@ bool txp_set::pack_file(void** data, size_t* size, bool big_endian) { } } - stream s; + memory_stream s; s.open(0, l); - s.is_big_endian = big_endian; + s.big_endian = big_endian; s.write_uint32_t_reverse_endianness(0x03505854); s.write_uint32_t_reverse_endianness((uint32_t)count); s.write_uint32_t_reverse_endianness((uint8_t)count | 0x01010100); @@ -157,9 +157,9 @@ bool txp_set::pack_file(void** data, size_t* size, bool big_endian) { s.copy(data, size); for (size_t i = 0; i < count; i++) - free(txp2_offset[i]); - free(txp2_offset); - free(txp4_offset); + free_def(txp2_offset[i]); + free_def(txp2_offset); + free_def(txp4_offset); return true; } @@ -198,9 +198,9 @@ bool txp_set::pack_file(std::vector& data, bool big_endian) { } } - stream s; + memory_stream s; s.open(0, l); - s.is_big_endian = big_endian; + s.big_endian = big_endian; s.write_uint32_t_reverse_endianness(0x03505854); s.write_uint32_t_reverse_endianness((uint32_t)count); s.write_uint32_t_reverse_endianness((uint8_t)count | 0x01010100); @@ -239,9 +239,9 @@ bool txp_set::pack_file(std::vector& data, bool big_endian) { s.copy(data); for (size_t i = 0; i < count; i++) - free(txp2_offset[i]); - free(txp2_offset); - free(txp4_offset); + free_def(txp2_offset[i]); + free_def(txp2_offset); + free_def(txp4_offset); return true; } @@ -405,7 +405,7 @@ bool txp_set::unpack_file(const void* data, bool big_endian) { } ssize_t size = txp::get_size(tex_mipmap->format, tex_mipmap->width, tex_mipmap->height); - tex_mipmap->data.resize(max(size, tex_mipmap->size)); + tex_mipmap->data.resize(max_def(size, tex_mipmap->size)); memcpy(tex_mipmap->data.data(), (void*)(mipmap_d + 24), tex_mipmap->size); size -= tex_mipmap->size; if (size > 0) diff --git a/src/KKdLib/vec.cpp b/src/KKdLib/vec.cpp index 19ea7c26..774d38d8 100644 --- a/src/KKdLib/vec.cpp +++ b/src/KKdLib/vec.cpp @@ -5,9 +5,9 @@ #include "vec.hpp" -const __m128 vec2_negate = { -0.0f, -0.0f, 0.0f, 0.0f }; -const __m128 vec3_negate = { -0.0f, -0.0f, -0.0f, 0.0f }; -const __m128 vec4_negate = { -0.0f, -0.0f, -0.0f, -0.0f }; +const __m128 vec2_neg = { -0.0f, -0.0f, 0.0f, 0.0f }; +const __m128 vec3_neg = { -0.0f, -0.0f, -0.0f, 0.0f }; +const __m128 vec4_neg = { -0.0f, -0.0f, -0.0f, -0.0f }; const vec4i vec4_mask_vec2 = { (int32_t)0xFFFFFFFF, (int32_t)0xFFFFFFFF, (int32_t)0x00000000, (int32_t)0x00000000 }; const vec4i vec4_mask_vec3 = { (int32_t)0xFFFFFFFF, (int32_t)0xFFFFFFFF, (int32_t)0xFFFFFFFF, (int32_t)0x00000000 }; diff --git a/src/KKdLib/vec.hpp b/src/KKdLib/vec.hpp index bbfbbffd..543b1d91 100644 --- a/src/KKdLib/vec.hpp +++ b/src/KKdLib/vec.hpp @@ -9,6 +9,8 @@ #include "half_t.hpp" #include #include +#include +#include struct vec2i8 { int8_t x; @@ -284,17 +286,34 @@ struct vec2 { float_t x; float_t y; - inline vec2() : x(), y() { + vec2(); + vec2(float_t value); + vec2(float_t x, float_t y); - } + static __m128 load_xmm(const float_t data); + static __m128 load_xmm(const vec2& data); + static __m128 load_xmm(const vec2&& data); + static vec2 store_xmm(const __m128& data); + static vec2 store_xmm(const __m128&& data); - inline vec2(float_t value) : x(value), y(value) { - - } - - inline vec2(float_t x, float_t y) : x(x), y(y) { - - } + static float_t angle(const vec2& left, const vec2& right); + static float_t dot(const vec2& left, const vec2& right); + static float_t length(const vec2& left); + static float_t length_squared(const vec2& left); + static float_t distance(const vec2& left, const vec2& right); + static float_t distance_squared(const vec2& left, const vec2& right); + static vec2 lerp(const vec2& left, const vec2& right, const vec2& blend); + static vec2 lerp(const vec2& left, const vec2& right, const float_t blend); + static vec2 normalize(const vec2& left); + static vec2 rcp(const vec2& left); + static vec2 min(const vec2& left, const vec2& right); + static vec2 max(const vec2& left, const vec2& right); + static vec2 clamp(const vec2& left, const vec2& min, const vec2& max); + static vec2 clamp(const vec2& left, const float_t min, const float_t max); + static vec2 mult_min_max(const vec2& left, const vec2& min, const vec2& max); + static vec2 mult_min_max(const vec2& left, const float_t min, const float_t max); + static vec2 div_min_max(const vec2& left, const vec2& min, const vec2& max); + static vec2 div_min_max(const vec2& left, const float_t min, const float_t max); }; struct vec3 { @@ -302,17 +321,35 @@ struct vec3 { float_t y; float_t z; - inline vec3() : x(), y(), z() { + vec3(); + vec3(float_t value); + vec3(float_t x, float_t y, float_t z); - } + static __m128 load_xmm(const float_t data); + static __m128 load_xmm(const vec3& data); + static __m128 load_xmm(const vec3&& data); + static vec3 store_xmm(const __m128& data); + static vec3 store_xmm(const __m128&& data); - inline vec3(float_t value) : x(value), y(value), z(value) { - - } - - inline vec3(float_t x, float_t y, float_t z) : x(x), y(y), z(z) { - - } + static float_t angle(const vec3& left, const vec3& right); + static float_t dot(const vec3& left, const vec3& right); + static float_t length(const vec3& left); + static float_t length_squared(const vec3& left); + static float_t distance(const vec3& left, const vec3& right); + static float_t distance_squared(const vec3& left, const vec3& right); + static vec3 lerp(const vec3& left, const vec3& right, const vec3& blend); + static vec3 lerp(const vec3& left, const vec3& right, const float_t blend); + static vec3 normalize(const vec3& left); + static vec3 rcp(const vec3& left); + static vec3 min(const vec3& left, const vec3& right); + static vec3 max(const vec3& left, const vec3& right); + static vec3 clamp(const vec3& left, const vec3& min, const vec3& max); + static vec3 clamp(const vec3& left, const float_t min, const float_t max); + static vec3 mult_min_max(const vec3& left, const vec3& min, const vec3& max); + static vec3 mult_min_max(const vec3& left, const float_t min, const float_t max); + static vec3 div_min_max(const vec3& left, const vec3& min, const vec3& max); + static vec3 div_min_max(const vec3& left, const float_t min, const float_t max); + static vec3 cross(const vec3& left, const vec3& right); }; struct vec4 { @@ -321,34 +358,54 @@ struct vec4 { float_t z; float_t w; - inline vec4() : x(), y(), z(), w() { + vec4(); + vec4(float_t value); + vec4(float_t x, float_t y, float_t z, float_t w); - } + static __m128 load_xmm(const float_t data); + static __m128 load_xmm(const vec4& data); + static __m128 load_xmm(const vec4&& data); + static vec4 store_xmm(const __m128& data); + static vec4 store_xmm(const __m128&& data); - inline vec4(float_t value) : x(value), y(value), z(value), w(value) { - - } - - inline vec4(float_t x, float_t y, float_t z, float_t w) : x(x), y(y), z(z), w(w) { - - } + static float_t angle(const vec4& left, const vec4& right); + static float_t dot(const vec4& left, const vec4& right); + static float_t length(const vec4& left); + static float_t length_squared(const vec4& left); + static float_t distance(const vec4& left, const vec4& right); + static float_t distance_squared(const vec4& left, const vec4& right); + static vec4 lerp(const vec4& left, const vec4& right, const vec4& blend); + static vec4 lerp(const vec4& left, const vec4& right, const float_t blend); + static vec4 normalize(const vec4& left); + static vec4 rcp(const vec4& left); + static vec4 min(const vec4& min, const vec4& max); + static vec4 max(const vec4& min, const vec4& max); + static vec4 clamp(const vec4& left, const vec4& min, const vec4& max); + static vec4 clamp(const vec4& left, const float_t min, const float_t max); + static vec4 mult_min_max(const vec4& left, const vec4& min, const vec4& max); + static vec4 mult_min_max(const vec4& left, const float_t min, const float_t max); + static vec4 div_min_max(const vec4& left, const vec4& min, const vec4& max); + static vec4 div_min_max(const vec4& left, const float_t min, const float_t max); }; struct vec2i { int32_t x; int32_t y; - inline vec2i() : x(), y() { + vec2i(); + vec2i(int32_t value); + vec2i(int32_t x, int32_t y); - } + static __m128i load_xmm(const int32_t data); + static __m128i load_xmm(const vec2i& data); + static __m128i load_xmm(const vec2i&& data); + static vec2i store_xmm(const __m128i& data); + static vec2i store_xmm(const __m128i&& data); - inline vec2i(int32_t value) : x(value), y(value) { - - } - - inline vec2i(int32_t x, int32_t y) : x(x), y(y) { - - } + static vec2i min(const vec2i& left, const vec2i& right); + static vec2i max(const vec2i& left, const vec2i& right); + static vec2i clamp(const vec2i& left, const vec2i& min, const vec2i& max); + static vec2i clamp(const vec2i& left, const int32_t min, const int32_t max); }; struct vec3i { @@ -356,17 +413,20 @@ struct vec3i { int32_t y; int32_t z; - inline vec3i() : x(), y(), z() { + vec3i(); + vec3i(int32_t value); + vec3i(int32_t x, int32_t y, int32_t z); - } + static __m128i load_xmm(const int32_t data); + static __m128i load_xmm(const vec3i& data); + static __m128i load_xmm(const vec3i&& data); + static vec3i store_xmm(const __m128i& data); + static vec3i store_xmm(const __m128i&& data); - inline vec3i(int32_t value) : x(value), y(value), z(value) { - - } - - inline vec3i(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z) { - - } + static vec3i min(const vec3i& left, const vec3i& right); + static vec3i max(const vec3i& left, const vec3i& right); + static vec3i clamp(const vec3i& left, const vec3i& min, const vec3i& max); + static vec3i clamp(const vec3i& left, const int32_t min, const int32_t max); }; struct vec4i { @@ -375,28 +435,29 @@ struct vec4i { int32_t z; int32_t w; - inline vec4i() : x(), y(), z(), w() { + vec4i(); + vec4i(int32_t value); + vec4i(int32_t x, int32_t y, int32_t z, int32_t w); - } + static __m128i load_xmm(const int32_t data); + static __m128i load_xmm(const vec4i& data); + static __m128i load_xmm(const vec4i&& data); + static vec4i store_xmm(const __m128i& data); + static vec4i store_xmm(const __m128i&& data); - inline vec4i(int32_t value) : x(value), y(value), z(value), w(value) { - - } - - inline vec4i(int32_t x, int32_t y, int32_t z, int32_t w) : x(x), y(y), z(z), w(w) { - - } + static vec4i min(const vec4i& left, const vec4i& right); + static vec4i max(const vec4i& left, const vec4i& right); + static vec4i clamp(const vec4i& left, const vec4i& min, const vec4i& max); + static vec4i clamp(const vec4i& left, const int32_t min, const int32_t max); }; -extern const __m128 vec2_negate; -extern const __m128 vec3_negate; -extern const __m128 vec4_negate; +extern const __m128 vec2_neg; +extern const __m128 vec3_neg; +extern const __m128 vec4_neg; extern const vec4i vec4_mask_vec2; extern const vec4i vec4_mask_vec3; -extern const __m128 vec4_negate; - extern const vec2 vec2_identity; extern const vec3 vec3_identity; extern const vec4 vec4_identity; @@ -408,1463 +469,1922 @@ extern const vec4 vec4_null; extern const vec2i vec2i_null; extern const vec3i vec3i_null; extern const vec4i vec4i_null; -#define vec2i8_to_vec2(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; - -#define vec3i8_to_vec3(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; - -#define vec4i8_to_vec4(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; \ -(dst).w = (float_t)(src).w; - -#define vec2_to_vec2i8(src, dst) \ -(dst).x = (int8_t)(src).x; \ -(dst).y = (int8_t)(src).y; - -#define vec3_to_vec3i8(src, dst) \ -(dst).x = (int8_t)(src).x; \ -(dst).y = (int8_t)(src).y; \ -(dst).z = (int8_t)(src).z; - -#define vec4_to_vec4i8(src, dst) \ -(dst).x = (int8_t)(src).x; \ -(dst).y = (int8_t)(src).y; \ -(dst).z = (int8_t)(src).z; \ -(dst).w = (int8_t)(src).w; - -#define vec2u8_to_vec2(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; - -#define vec3u8_to_vec3(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; - -#define vec4u8_to_vec4(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; \ -(dst).w = (float_t)(src).w; - -#define vec2_to_vec2u8(src, dst) \ -(dst).x = (uint8_t)(src).x; \ -(dst).y = (uint8_t)(src).y; - -#define vec3_to_vec3u8(src, dst) \ -(dst).x = (uint8_t)(src).x; \ -(dst).y = (uint8_t)(src).y; \ -(dst).z = (uint8_t)(src).z; - -#define vec4_to_vec4u8(src, dst) \ -(dst).x = (uint8_t)(src).x; \ -(dst).y = (uint8_t)(src).y; \ -(dst).z = (uint8_t)(src).z; \ -(dst).w = (uint8_t)(src).w; - -#define vec2i16_to_vec2(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; - -#define vec3i16_to_vec3(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; - -#define vec4i16_to_vec4(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; \ -(dst).w = (float_t)(src).w; - -#define vec2_to_vec2i16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; - -#define vec3_to_vec3i16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; - -#define vec4_to_vec4i16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; \ -(dst).w = (uint16_t)(src).w; - -#define vec2u16_to_vec2(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; - -#define vec3u16_to_vec3(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; - -#define vec4u16_to_vec4(src, dst) \ -(dst).x = (float_t)(src).x; \ -(dst).y = (float_t)(src).y; \ -(dst).z = (float_t)(src).z; \ -(dst).w = (float_t)(src).w; - -#define vec2_to_vec2u16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; - -#define vec3_to_vec3u16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; - -#define vec4_to_vec4u16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; \ -(dst).w = (uint16_t)(src).w; - -#define vec2h_to_vec2(src, dst) \ -(dst).x = half_to_float((src).x); \ -(dst).y = half_to_float((src).y); - -#define vec3h_to_vec3(src, dst) \ -(dst).x = half_to_float((src).x); \ -(dst).y = half_to_float((src).y); \ -(dst).z = half_to_float((src).z); - -#define vec4h_to_vec4(src, dst) \ -(dst).x = half_to_float((src).x); \ -(dst).y = half_to_float((src).y); \ -(dst).z = half_to_float((src).z); \ -(dst).w = half_to_float((src).w); - -#define vec2_to_vec2h(src, dst) \ -(dst).x = float_to_half((src).x); \ -(dst).y = float_to_half((src).y); - -#define vec3_to_vec3h(src, dst) \ -(dst).x = float_to_half((src).x); \ -(dst).y = float_to_half((src).y); \ -(dst).z = float_to_half((src).z); - -#define vec4_to_vec4h(src, dst) \ -(dst).x = float_to_half((src).x); \ -(dst).y = float_to_half((src).y); \ -(dst).z = float_to_half((src).z); \ -(dst).w = float_to_half((src).w); - -#define vec2i8_to_vec2i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; - -#define vec3i8_to_vec3i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; - -#define vec4i8_to_vec4i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; \ -(dst).w = (int32_t)(src).w; - -#define vec2i_to_vec2i8(src, dst) \ -(dst).x = (int8_t)(src).x; \ -(dst).y = (int8_t)(src).y; - -#define vec3i_to_vec3i8(src, dst) \ -(dst).x = (int8_t)(src).x; \ -(dst).y = (int8_t)(src).y; \ -(dst).z = (int8_t)(src).z; - -#define vec4i_to_vec4i8(src, dst) \ -(dst).x = (int8_t)(src).x; \ -(dst).y = (int8_t)(src).y; \ -(dst).z = (int8_t)(src).z; \ -(dst).w = (int8_t)(src).w; - -#define vec2u8_to_vec2i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; - -#define vec3u8_to_vec3i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; - -#define vec4u8_to_vec4i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; \ -(dst).w = (int32_t)(src).w; - -#define vec2i_to_vec2u8(src, dst) \ -(dst).x = (uint8_t)(src).x; \ -(dst).y = (uint8_t)(src).y; - -#define vec3i_to_vec3u8(src, dst) \ -(dst).x = (uint8_t)(src).x; \ -(dst).y = (uint8_t)(src).y; \ -(dst).z = (uint8_t)(src).z; - -#define vec4i_to_vec4u8(src, dst) \ -(dst).x = (uint8_t)(src).x; \ -(dst).y = (uint8_t)(src).y; \ -(dst).z = (uint8_t)(src).z; \ -(dst).w = (uint8_t)(src).w; - -#define vec2i16_to_vec2i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; - -#define vec3i16_to_vec3i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; - -#define vec4i16_to_vec4i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; \ -(dst).w = (int32_t)(src).w; - -#define vec2i_to_vec2i16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; - -#define vec3i_to_vec3i16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; - -#define vec4i_to_vec4i16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; \ -(dst).w = (uint16_t)(src).w; - -#define vec2u16_to_vec2i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; - -#define vec3u16_to_vec3i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; - -#define vec4u16_to_vec4i(src, dst) \ -(dst).x = (int32_t)(src).x; \ -(dst).y = (int32_t)(src).y; \ -(dst).z = (int32_t)(src).z; \ -(dst).w = (int32_t)(src).w; - -#define vec2i_to_vec2u16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; - -#define vec3i_to_vec3u16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; - -#define vec4i_to_vec4u16(src, dst) \ -(dst).x = (uint16_t)(src).x; \ -(dst).y = (uint16_t)(src).y; \ -(dst).z = (uint16_t)(src).z; \ -(dst).w = (uint16_t)(src).w; - -#define vec2_add(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_add_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_add_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_add_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_sub(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_sub_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_sub_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_sub_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_mult(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_mul_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_mult_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_div(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_div_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_div_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_div_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_and(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_and_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_and_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_and_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_xor(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_xor_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_xor_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_xor_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_negate(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - zt = _mm_xor_ps(xt, vec2_negate); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_dot(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_mul_ps(xt, yt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ -} - -#define vec2_length(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - zt = _mm_mul_ps(xt, xt); \ - (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ -} - -#define vec2_length_squared(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - zt = _mm_mul_ps(xt, xt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ -} - -#define vec2_distance(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_sub_ps(xt, yt); \ - zt = _mm_mul_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ -} - -#define vec2_distance_squared(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_sub_ps(xt, yt); \ - zt = _mm_mul_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ -} - -#define vec2_lerp(x, y, z, blend) \ -{ \ - __m128 b1; \ - __m128 b2; \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - *(vec3*)&b1 = (blend); \ - *(vec3*)&b2 = vec3_identity; \ - b2 = _mm_sub_ps(b2, b1); \ - zt = _mm_add_ps(_mm_mul_ps(xt, b2), _mm_mul_ps(yt, b1)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_lerp_scalar(x, y, z, blend) \ -{ \ - __m128 b1; \ - __m128 b2; \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - b1 = _mm_set_ss(blend); \ - b1 = _mm_shuffle_ps(b1, b1, 0); \ - *(vec2*)&b2 = vec2_identity; \ - b2 = _mm_sub_ps(b2, b1); \ - zt = _mm_add_ps(_mm_mul_ps(xt, b2), _mm_mul_ps(yt, b1)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_normalize(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - zt = _mm_mul_ps(xt, xt); \ - zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); \ - if (zt.m128_f32[0] != 0.0f) \ - zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; \ - zt = _mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0)); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_rcp(x, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = vec2_identity; \ - zt = _mm_div_ps(yt, xt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_min(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_min_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_max(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - zt = _mm_max_ps(xt, yt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec2_clamp(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - *(vec2*)&zt = (z); \ - wt = _mm_min_ps(_mm_max_ps(xt, yt), zt); \ - (w) = *(vec2*)&wt; \ -} - -#define vec2_clamp_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_set_ss(z); \ - wt = _mm_min_ps(_mm_max_ps(xt, _mm_shuffle_ps(yt, yt, 0)), _mm_shuffle_ps(zt, zt, 0)); \ - (w) = *(vec2*)&wt; \ -} - -#define vec2_mult_min_max(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - *(vec2*)&zt = (z); \ - yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_mul_ps(xt, wt); \ - (w) = *(vec2*)&wt; \ -} - -#define vec2_mult_min_max_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - yt = _mm_shuffle_ps(yt, yt, 0); \ - zt = _mm_set_ss(z); \ - zt = _mm_shuffle_ps(zt, zt, 0); \ - yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_mul_ps(xt, wt); \ - (w) = *(vec2*)&wt; \ -} - -#define vec2_div_min_max(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec2*)&xt = (x); \ - *(vec2*)&yt = (y); \ - *(vec2*)&zt = (z); \ - yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_div_ps(xt, wt); \ - (w) = *(vec2*)&wt; \ -} - -#define vec2_div_min_max_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec2*)&xt = (x); \ - yt = _mm_set_ss(y); \ - yt = _mm_shuffle_ps(yt, yt, 0); \ - zt = _mm_set_ss(z); \ - zt = _mm_shuffle_ps(zt, zt, 0); \ - yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_div_ps(xt, wt); \ - (w) = *(vec2*)&wt; \ -} - -#define vec3_add(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_add_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_add_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_add_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_sub(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_sub_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_sub_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_sub_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_mult(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_mul_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_mult_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_div(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_div_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_div_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_div_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_and(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_and_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_and_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_and_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_xor(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_xor_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_xor_scalar(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_xor_ps(xt, _mm_shuffle_ps(yt, yt, 0)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_negate(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - zt = _mm_xor_ps(xt, vec3_negate); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_dot(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - *(vec3*)&yt = (y); \ - yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - zt = _mm_mul_ps(xt, yt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ -} - -#define vec3_length(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - zt = _mm_mul_ps(xt, xt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ -} - -#define vec3_length_squared(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - zt = _mm_mul_ps(xt, xt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ -} - -#define vec3_distance(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - *(vec3*)&yt = (y); \ - yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - zt = _mm_sub_ps(xt, yt); \ - zt = _mm_mul_ps(zt, zt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ -} - -#define vec3_distance_squared(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - *(vec3*)&yt = (y); \ - yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - zt = _mm_sub_ps(xt, yt); \ - zt = _mm_mul_ps(zt, zt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ -} - -#define vec3_lerp(x, y, z, blend) \ -{ \ - __m128 b1; \ - __m128 b2; \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - *(vec3*)&b1 = (blend); \ - *(vec3*)&b2 = vec3_identity; \ - b2 = _mm_sub_ps(b2, b1); \ - zt = _mm_add_ps(_mm_mul_ps(xt, b2), _mm_mul_ps(yt, b1)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_lerp_scalar(x, y, z, blend) \ -{ \ - __m128 b1; \ - __m128 b2; \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - b1 = _mm_set_ss(blend); \ - b1 = _mm_shuffle_ps(b1, b1, 0); \ - *(vec3*)&b2 = vec3_identity; \ - b2 = _mm_sub_ps(b2, b1); \ - zt = _mm_add_ps(_mm_mul_ps(xt, b2), _mm_mul_ps(yt, b1)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_normalize(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ - zt = _mm_mul_ps(xt, xt); \ - zt = _mm_hadd_ps(zt, zt); \ - zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); \ - if (zt.m128_f32[0] != 0.0f) \ - zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; \ - zt = _mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0)); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_rcp(x, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = vec3_identity; \ - zt = _mm_div_ps(yt, xt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_min(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_min_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_max(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_max_ps(xt, yt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec3_clamp(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - *(vec3*)&zt = (z); \ - wt = _mm_min_ps(_mm_max_ps(xt, yt), zt); \ - (w) = *(vec3*)&wt; \ -} - -#define vec3_clamp_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - zt = _mm_set_ss(z); \ - wt = _mm_min_ps(_mm_max_ps(xt, _mm_shuffle_ps(yt, yt, 0)), _mm_shuffle_ps(zt, zt, 0)); \ - (w) = *(vec3*)&wt; \ -} - -#define vec3_mult_min_max(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - *(vec3*)&zt = (z); \ - yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_mul_ps(xt, wt); \ - (w) = *(vec3*)&wt; \ -} - -#define vec3_mult_min_max_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - yt = _mm_shuffle_ps(yt, yt, 0); \ - zt = _mm_set_ss(z); \ - zt = _mm_shuffle_ps(zt, zt, 0); \ - yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_mul_ps(xt, wt); \ - (w) = *(vec3*)&wt; \ -} - -#define vec3_div_min_max(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - *(vec3*)&zt = (z); \ - yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_div_ps(xt, wt); \ - (w) = *(vec3*)&wt; \ -} - -#define vec3_div_min_max_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - *(vec3*)&xt = (x); \ - yt = _mm_set_ss(y); \ - yt = _mm_shuffle_ps(yt, yt, 0); \ - zt = _mm_set_ss(z); \ - zt = _mm_shuffle_ps(zt, zt, 0); \ - yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - wt = _mm_div_ps(xt, wt); \ - (w) = *(vec3*)&wt; \ -} - -#define vec3_cross(x, y, z) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - *(vec3*)&xt = (x); \ - *(vec3*)&yt = (y); \ - zt = _mm_sub_ps( \ - _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x09)), \ - _mm_mul_ps(yt, _mm_shuffle_ps(xt, xt, 0x09)) \ - ); \ - zt = _mm_shuffle_ps(zt, zt, 0x09); \ - (z) = *(vec3*)&zt; \ -} - -#define vec4_add(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ -} - -#define vec4_add_scalar(x, y, z) \ -{ \ - __m128 yt; \ - yt = _mm_set_ss(y); \ - _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ -} - -#define vec4_sub(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ -} - -#define vec4_sub_scalar(x, y, z) \ -{ \ - __m128 yt; \ - yt = _mm_set_ss(y); \ - _mm_storeu_ps((float*)&(z), _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ -} - -#define vec4_mult(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_mul_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ -} - -#define vec4_mult_scalar(x, y, z) \ -{ \ - __m128 yt; \ - yt = _mm_set_ss(y); \ - _mm_storeu_ps((float*)&(z), _mm_mul_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ -} - -#define vec4_div(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_div_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ -} - -#define vec4_div_scalar(x, y, z) \ -{ \ - __m128 yt; \ - yt = _mm_set_ss(y); \ - _mm_storeu_ps((float*)&(z), _mm_div_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ -} - -#define vec4_and(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_and_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ -} - -#define vec4_and_scalar(x, y, z) \ -{ \ - __m128 yt; \ - yt = _mm_set_ss(y); \ - _mm_storeu_ps((float*)&(z), _mm_and_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ -} - -#define vec4_xor(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_xor_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ + +inline vec2::vec2() : x(), y() { + +} + +inline vec2::vec2(float_t value) : x(value), y(value) { + +} + +inline vec2::vec2(float_t x, float_t y) : x(x), y(y) { + +} + +inline __m128 vec2::load_xmm(const float_t data) { + __m128 _data = _mm_set_ss(data); + return _mm_shuffle_ps(_data, _data, 0); +} + +inline __m128 vec2::load_xmm(const vec2& data) { + return _mm_castsi128_ps(_mm_loadl_epi64((const __m128i*) & data)); +} + +inline __m128 vec2::load_xmm(const vec2&& data) { + return _mm_castsi128_ps(_mm_loadl_epi64((const __m128i*) & data)); +} + +inline vec2 vec2::store_xmm(const __m128& data) { + vec2 _data; + _mm_storel_epi64((__m128i*) & _data, _mm_castps_si128(data)); + return _data; +} + +inline vec2 vec2::store_xmm(const __m128&& data) { + vec2 _data; + _mm_storel_epi64((__m128i*) & _data, _mm_castps_si128(data)); + return _data; +} + +inline __m128 vec3::load_xmm(const float_t data) { + __m128 _data = _mm_set_ss(data); + return _mm_shuffle_ps(_data, _data, 0); +} + +inline __m128 vec3::load_xmm(const vec3& data) { + return _mm_movelh_ps(_mm_castsi128_ps(_mm_loadl_epi64((const __m128i*) & data)), _mm_set_ss(data.z)); +} + +inline __m128 vec3::load_xmm(const vec3&& data) { + return _mm_movelh_ps(_mm_castsi128_ps(_mm_loadl_epi64((const __m128i*) & data)), _mm_set_ss(data.z)); +} + +inline vec3 vec3::store_xmm(const __m128& data) { + vec3 _data; + _mm_storel_epi64((__m128i*) & _data, _mm_castps_si128(data)); + *(int32_t*)&_data.z = _mm_cvtsi128_si32(_mm_srli_si128(_mm_castps_si128(data), 8)); + return _data; +} + +inline vec3 vec3::store_xmm(const __m128&& data) { + vec3 _data; + _mm_storel_epi64((__m128i*) & _data, _mm_castps_si128(data)); + *(int32_t*)&_data.z = _mm_cvtsi128_si32(_mm_srli_si128(_mm_castps_si128(data), 8)); + return _data; +} + +inline __m128 vec4::load_xmm(const float_t data) { + __m128 _data = _mm_set_ss(data); + return _mm_shuffle_ps(_data, _data, 0); +} + +inline __m128 vec4::load_xmm(const vec4& data) { + return _mm_loadu_ps((const float*)&data); +} + +inline __m128 vec4::load_xmm(const vec4&& data) { + return _mm_loadu_ps((const float*)&data); +} + +inline vec4 vec4::store_xmm(const __m128& data) { + vec4 _data; + _mm_storeu_ps((float*)&_data, data); + return _data; +} + +inline vec4 vec4::store_xmm(const __m128&& data) { + vec4 _data; + _mm_storeu_ps((float*)&_data, data); + return _data; +} + +inline __m128i vec2i::load_xmm(const int32_t data) { + __m128i _data = _mm_cvtsi32_si128(data); + return _mm_shuffle_epi32(_data, 0); +} + +inline __m128i vec2i::load_xmm(const vec2i& data) { + return _mm_loadl_epi64((const __m128i*) & data); +} + +inline __m128i vec2i::load_xmm(const vec2i&& data) { + return _mm_loadl_epi64((const __m128i*) & data); +} + +inline vec2i vec2i::store_xmm(const __m128i& data) { + vec2i _data; + _mm_storel_epi64((__m128i*) & _data, data); + return _data; +} + +inline vec2i vec2i::store_xmm(const __m128i&& data) { + vec2i _data; + _mm_storel_epi64((__m128i*) & _data, data); + return _data; +} + +inline __m128i vec3i::load_xmm(const int32_t data) { + __m128i _data = _mm_cvtsi32_si128(data); + return _mm_shuffle_epi32(_data, 0); +} + +inline __m128i vec3i::load_xmm(const vec3i& data) { + return _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*) & data), _mm_cvtsi32_si128(data.z)); +} + +inline __m128i vec3i::load_xmm(const vec3i&& data) { + return _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*) & data), _mm_cvtsi32_si128(data.z)); +} + +inline vec3i vec3i::store_xmm(const __m128i& data) { + vec3i _data; + _mm_storel_epi64((__m128i*) & _data, data); + _data.z = _mm_cvtsi128_si32(_mm_srli_si128(data, 8)); + return _data; +} + +inline vec3i vec3i::store_xmm(const __m128i&& data) { + vec3i _data; + _mm_storel_epi64((__m128i*) & _data, data); + _data.z = _mm_cvtsi128_si32(_mm_srli_si128(data, 8)); + return _data; +} + +inline __m128i vec4i::load_xmm(const int32_t data) { + __m128i _data = _mm_cvtsi32_si128(data); + return _mm_shuffle_epi32(_data, 0); +} + +inline __m128i vec4i::load_xmm(const vec4i& data) { + return _mm_loadu_si128((const __m128i*)&data); +} + +inline __m128i vec4i::load_xmm(const vec4i&& data) { + return _mm_loadu_si128((const __m128i*)&data); +} + +inline vec4i vec4i::store_xmm(const __m128i& data) { + vec4i _data; + _mm_storeu_si128((__m128i*)&_data, data); + return _data; +} + +inline vec4i vec4i::store_xmm(const __m128i&& data) { + vec4i _data; + _mm_storeu_si128((__m128i*)&_data, data); + return _data; +} + +inline vec2 operator +(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_add_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator +(const vec2& left, const float_t right) { + return vec2::store_xmm(_mm_add_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator +(const float_t left, const vec2& right) { + return vec2::store_xmm(_mm_add_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator +=(vec2& left, const vec2& right) { + left = vec2::store_xmm(_mm_add_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator +=(vec2& left, const float_t right) { + left = vec2::store_xmm(_mm_add_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator -(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_sub_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator -(const vec2& left, const float_t right) { + return vec2::store_xmm(_mm_sub_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator -(const float_t left, const vec2& right) { + return vec2::store_xmm(_mm_sub_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator -=(vec2& left, const vec2& right) { + left = vec2::store_xmm(_mm_sub_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator -=(vec2& left, const float_t right) { + left = vec2::store_xmm(_mm_sub_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator *(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_mul_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator *(const vec2& left, const float_t right) { + return vec2::store_xmm(_mm_mul_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator *(const float_t left, const vec2& right) { + return vec2::store_xmm(_mm_mul_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator *=(vec2& left, const vec2& right) { + left = vec2::store_xmm(_mm_mul_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator *=(vec2& left, const float_t right) { + left = vec2::store_xmm(_mm_mul_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator /(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_div_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator /(const vec2& left, const float_t right) { + return vec2::store_xmm(_mm_div_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator /(const float_t left, const vec2& right) { + return vec2::store_xmm(_mm_div_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator /=(vec2& left, const vec2& right) { + left = vec2::store_xmm(_mm_div_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator /=(vec2& left, const float_t right) { + left = vec2::store_xmm(_mm_div_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator &(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_and_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator &(const vec2& left, const float_t right) { + return vec2::store_xmm(_mm_and_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator &(const float_t left, const vec2& right) { + return vec2::store_xmm(_mm_and_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator &=(vec2& left, const vec2& right) { + left = vec2::store_xmm(_mm_and_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator &=(vec2& left, const float_t right) { + left = vec2::store_xmm(_mm_and_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator ^(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_xor_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator ^(const vec2& left, const float_t right) { + return vec2::store_xmm(_mm_xor_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator ^(const float_t left, const vec2& right) { + return vec2::store_xmm(_mm_xor_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator ^=(vec2& left, const vec2& right) { + left = vec2::store_xmm(_mm_xor_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline void operator ^=(vec2& left, const float_t right) { + left = vec2::store_xmm(_mm_xor_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 operator -(const vec2& left) { + return vec2::store_xmm(_mm_xor_ps(vec2::load_xmm(left), vec2_neg)); +} + +inline float_t vec2::angle(const vec2& left, const vec2& right) { + return acosf(vec2::dot(left, right) / (vec2::length(left) * vec2::length(right))); +} + +inline float_t vec2::dot(const vec2& left, const vec2& right) { + __m128 zt; + zt = _mm_mul_ps(vec2::load_xmm(left), vec2::load_xmm(right)); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t vec2::length(const vec2& left) { + __m128 xt; + __m128 zt; + xt = vec2::load_xmm(left); + zt = _mm_mul_ps(xt, xt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t vec2::length_squared(const vec2& left) { + __m128 xt; + __m128 zt; + xt = vec2::load_xmm(left); + zt = _mm_mul_ps(xt, xt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t vec2::distance(const vec2& left, const vec2& right) { + __m128 zt; + zt = _mm_sub_ps(vec2::load_xmm(left), vec2::load_xmm(right)); + zt = _mm_mul_ps(zt, zt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t vec2::distance_squared(const vec2& left, const vec2& right) { + __m128 zt; + zt = _mm_sub_ps(vec2::load_xmm(left), vec2::load_xmm(right)); + zt = _mm_mul_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline vec2 vec2::lerp(const vec2& left, const vec2& right, const vec2& blend) { + __m128 b1; + __m128 b2; + b1 = vec2::load_xmm(blend); + b2 = _mm_sub_ps(vec2::load_xmm(1.0f), b1); + return vec2::store_xmm(_mm_add_ps(_mm_mul_ps(vec2::load_xmm(left), b2), + _mm_mul_ps(vec2::load_xmm(right), b1))); +} + +inline vec2 vec2::lerp(const vec2& left, const vec2& right, const float_t blend) { + __m128 b1; + __m128 b2; + b1 = vec2::load_xmm(blend); + b2 = _mm_sub_ps(vec2::load_xmm(1.0f), b1); + return vec2::store_xmm(_mm_add_ps(_mm_mul_ps(vec2::load_xmm(left), b2), + _mm_mul_ps(vec2::load_xmm(right), b1))); +} + +inline vec2 vec2::normalize(const vec2& left) { + __m128 xt; + __m128 zt; + xt = vec2::load_xmm(left); + zt = _mm_mul_ps(xt, xt); + zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); + if (zt.m128_f32[0] != 0.0f) + zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; + return vec2::store_xmm(_mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0))); +} + +inline vec2 vec2::rcp(const vec2& left) { + return vec2::store_xmm(_mm_div_ps(vec2::load_xmm(1.0f), vec2::load_xmm(left))); +} + +inline vec2 vec2::min(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_min_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 vec2::max(const vec2& left, const vec2& right) { + return vec2::store_xmm(_mm_max_ps(vec2::load_xmm(left), vec2::load_xmm(right))); +} + +inline vec2 vec2::clamp(const vec2& left, const vec2& min, const vec2& max) { + return vec2::store_xmm(_mm_min_ps(_mm_max_ps(vec2::load_xmm(left), + vec2::load_xmm(min)), vec2::load_xmm(max))); +} + +inline vec2 vec2::clamp(const vec2& left, const float_t min, const float_t max) { + return vec2::store_xmm(_mm_min_ps(_mm_max_ps(vec2::load_xmm(left), + vec2::load_xmm(min)), vec2::load_xmm(max))); +} + +inline vec2 vec2::mult_min_max(const vec2& left, const vec2& min, const vec2& max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec2::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(max)); + return vec2::store_xmm(_mm_mul_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec2 vec2::mult_min_max(const vec2& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec2::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(max)); + return vec2::store_xmm(_mm_mul_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec2 vec2::div_min_max(const vec2& left, const vec2& min, const vec2& max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec2::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(max)); + return vec2::store_xmm(_mm_div_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec2 vec2::div_min_max(const vec2& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec2::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec2::load_xmm(max)); + return vec2::store_xmm(_mm_div_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec3::vec3() : x(), y(), z() { + +} + +inline vec3::vec3(float_t value) : x(value), y(value), z(value) { + +} + +inline vec3::vec3(float_t x, float_t y, float_t z) : x(x), y(y), z(z) { + +} + +inline vec3 operator +(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_add_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator +(const vec3& left, const float_t right) { + return vec3::store_xmm(_mm_add_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator +(const float_t left, const vec3& right) { + return vec3::store_xmm(_mm_add_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator +=(vec3& left, const vec3& right) { + left = vec3::store_xmm(_mm_add_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator +=(vec3& left, const float_t right) { + left = vec3::store_xmm(_mm_add_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator -(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_sub_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator -(const vec3& left, const float_t right) { + return vec3::store_xmm(_mm_sub_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator -(const float_t left, const vec3& right) { + return vec3::store_xmm(_mm_sub_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator -=(vec3& left, const vec3& right) { + left = vec3::store_xmm(_mm_sub_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator -=(vec3& left, const float_t right) { + left = vec3::store_xmm(_mm_sub_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator *(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_mul_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator *(const vec3& left, const float_t right) { + return vec3::store_xmm(_mm_mul_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator *(const float_t left, const vec3& right) { + return vec3::store_xmm(_mm_mul_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator *=(vec3& left, const vec3& right) { + left = vec3::store_xmm(_mm_mul_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator *=(vec3& left, const float_t right) { + left = vec3::store_xmm(_mm_mul_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator /(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_div_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator /(const vec3& left, const float_t right) { + return vec3::store_xmm(_mm_div_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator /(const float_t left, const vec3& right) { + return vec3::store_xmm(_mm_div_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator /=(vec3& left, const vec3& right) { + left = vec3::store_xmm(_mm_div_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator /=(vec3& left, const float_t right) { + left = vec3::store_xmm(_mm_div_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator &(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_and_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator &(const vec3& left, const float_t right) { + return vec3::store_xmm(_mm_and_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator &(const float_t left, const vec3& right) { + return vec3::store_xmm(_mm_and_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator &=(vec3& left, const vec3& right) { + left = vec3::store_xmm(_mm_and_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator &=(vec3& left, const float_t right) { + left = vec3::store_xmm(_mm_and_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator ^(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_xor_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator ^(const vec3& left, const float_t right) { + return vec3::store_xmm(_mm_xor_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator ^(const float_t left, const vec3& right) { + return vec3::store_xmm(_mm_xor_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator ^=(vec3& left, const vec3& right) { + left = vec3::store_xmm(_mm_xor_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline void operator ^=(vec3& left, const float_t right) { + left = vec3::store_xmm(_mm_xor_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 operator -(const vec3& left) { + return vec3::store_xmm(_mm_xor_ps(vec3::load_xmm(left), vec3_neg)); +} + +inline float_t vec3::angle(const vec3& left, const vec3& right) { + return acosf(vec3::dot(left, right) / (vec3::length(left) * vec3::length(right))); +} + +inline float_t vec3::dot(const vec3& left, const vec3& right) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec3::load_xmm(left); + xt = _mm_and_ps(xt, _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + yt = vec3::load_xmm(right); + yt = _mm_and_ps(yt, _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + zt = _mm_mul_ps(xt, yt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t vec3::length(const vec3& left) { + __m128 xt; + __m128 zt; + xt = _mm_and_ps(vec3::load_xmm(left), _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t vec3::length_squared(const vec3& left) { + __m128 xt; + __m128 zt; + xt = _mm_and_ps(vec3::load_xmm(left), _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t vec3::distance(const vec3& left, const vec3& right) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = _mm_and_ps(vec3::load_xmm(left), _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + yt = _mm_and_ps(vec3::load_xmm(right), _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + zt = _mm_sub_ps(xt, yt); + zt = _mm_mul_ps(zt, zt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t vec3::distance_squared(const vec3& left, const vec3& right) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = _mm_and_ps(vec3::load_xmm(left), _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + yt = _mm_and_ps(vec3::load_xmm(right), _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + zt = _mm_sub_ps(xt, yt); + zt = _mm_mul_ps(zt, zt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline vec3 vec3::lerp(const vec3& left, const vec3& right, const vec3& blend) { + __m128 b1; + __m128 b2; + b1 = vec3::load_xmm(blend); + b2 = _mm_sub_ps(vec3::load_xmm(1.0f), b1); + return vec3::store_xmm(_mm_add_ps(_mm_mul_ps(vec3::load_xmm(left), b2), + _mm_mul_ps(vec3::load_xmm(right), b1))); +} + +inline vec3 vec3::lerp(const vec3& left, const vec3& right, const float_t blend) { + __m128 b1; + __m128 b2; + b1 = vec3::load_xmm(blend); + b2 = _mm_sub_ps(vec3::load_xmm(1.0f), b1); + return vec3::store_xmm(_mm_add_ps(_mm_mul_ps(vec3::load_xmm(left), b2), + _mm_mul_ps(vec3::load_xmm(right), b1))); +} + +inline vec3 vec3::normalize(const vec3& left) { + __m128 xt; + __m128 zt; + xt = vec3::load_xmm(left); + xt = _mm_and_ps(xt, _mm_castsi128_ps(vec4i::load_xmm(vec4_mask_vec3))); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); + if (zt.m128_f32[0] != 0.0f) + zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; + return vec3::store_xmm(_mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0))); +} + +inline vec3 vec3::rcp(const vec3& left) { + return vec3::store_xmm(_mm_div_ps(vec3::load_xmm(1.0f), vec3::load_xmm(left))); +} + +inline vec3 vec3::min(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_min_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 vec3::max(const vec3& left, const vec3& right) { + return vec3::store_xmm(_mm_max_ps(vec3::load_xmm(left), vec3::load_xmm(right))); +} + +inline vec3 vec3::clamp(const vec3& left, const vec3& min, const vec3& max) { + return vec3::store_xmm(_mm_min_ps(_mm_max_ps(vec3::load_xmm(left), + vec3::load_xmm(min)), vec3::load_xmm(max))); +} + +inline vec3 vec3::clamp(const vec3& left, const float_t min, const float_t max) { + return vec3::store_xmm(_mm_min_ps(_mm_max_ps(vec3::load_xmm(left), + vec3::load_xmm(min)), vec3::load_xmm(max))); +} + +inline vec3 vec3::mult_min_max(const vec3& left, const vec3& min, const vec3& max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec3::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(max)); + return vec3::store_xmm(_mm_mul_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec3 vec3::mult_min_max(const vec3& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec3::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(max)); + return vec3::store_xmm(_mm_mul_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec3 vec3::div_min_max(const vec3& left, const vec3& min, const vec3& max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec3::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(max)); + return vec3::store_xmm(_mm_div_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec3 vec3::div_min_max(const vec3& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec3::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec3::load_xmm(max)); + return vec3::store_xmm(_mm_div_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec3 vec3::cross(const vec3& left, const vec3& right) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec3::load_xmm(left); + yt = vec3::load_xmm(right); + zt = _mm_sub_ps( + _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x09)), + _mm_mul_ps(yt, _mm_shuffle_ps(xt, xt, 0x09)) + ); + return vec3::store_xmm(_mm_shuffle_ps(zt, zt, 0x09)); +} + +inline vec4::vec4() : x(), y(), z(), w() { + +} + +inline vec4::vec4(float_t value) : x(value), y(value), z(value), w(value) { + +} + +inline vec4::vec4(float_t x, float_t y, float_t z, float_t w) : x(x), y(y), z(z), w(w) { + +} + +inline vec4 operator +(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_add_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator +(const vec4& left, const float_t right) { + return vec4::store_xmm(_mm_add_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator +(const float_t left, const vec4& right) { + return vec4::store_xmm(_mm_add_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator +=(vec4& left, const vec4& right) { + left = vec4::store_xmm(_mm_add_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator +=(vec4& left, const float_t right) { + left = vec4::store_xmm(_mm_add_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator -(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_sub_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator -(const vec4& left, const float_t right) { + return vec4::store_xmm(_mm_sub_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator -(const float_t left, const vec4& right) { + return vec4::store_xmm(_mm_sub_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator -=(vec4& left, const vec4& right) { + left = vec4::store_xmm(_mm_sub_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator -=(vec4& left, const float_t right) { + left = vec4::store_xmm(_mm_sub_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator *(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator *(const vec4& left, const float_t right) { + return vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator *(const float_t left, const vec4& right) { + return vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator *=(vec4& left, const vec4& right) { + left = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator *=(vec4& left, const float_t right) { + left = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator /(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_div_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator /(const vec4& left, const float_t right) { + return vec4::store_xmm(_mm_div_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator /(const float_t left, const vec4& right) { + return vec4::store_xmm(_mm_div_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator /=(vec4& left, const vec4& right) { + left = vec4::store_xmm(_mm_div_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator /=(vec4& left, const float_t right) { + left = vec4::store_xmm(_mm_div_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator &(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_and_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator &(const vec4& left, const float_t right) { + return vec4::store_xmm(_mm_and_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator &(const float_t left, const vec4& right) { + return vec4::store_xmm(_mm_and_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator &=(vec4& left, const vec4& right) { + left = vec4::store_xmm(_mm_and_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator &=(vec4& left, const float_t right) { + left = vec4::store_xmm(_mm_and_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator ^(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_xor_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator ^(const vec4& left, const float_t right) { + return vec4::store_xmm(_mm_xor_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator ^(const float_t left, const vec4& right) { + return vec4::store_xmm(_mm_xor_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator ^=(vec4& left, const vec4& right) { + left = vec4::store_xmm(_mm_xor_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline void operator ^=(vec4& left, const float_t right) { + left = vec4::store_xmm(_mm_xor_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 operator -(const vec4& left) { + return vec4::store_xmm(_mm_xor_ps(vec4::load_xmm(left), vec4_neg)); +} + +inline float_t vec4::angle(const vec4& left, const vec4& right) { + return acosf(vec4::dot(left, right) / (vec4::length(left) * vec4::length(right))); +} + +inline float_t vec4::dot(const vec4& left, const vec4& right) { + __m128 zt; + zt = _mm_mul_ps(vec4::load_xmm(left), vec4::load_xmm(right)); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t vec4::length(const vec4& left) { + __m128 xt; + __m128 zt; + xt = vec4::load_xmm(left); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t vec4::length_squared(const vec4& left) { + __m128 xt; + __m128 zt; + xt = vec4::load_xmm(left); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline float_t vec4::distance(const vec4& left, const vec4& right) { + __m128 zt; + zt = _mm_sub_ps(vec4::load_xmm(left), vec4::load_xmm(right)); + zt = _mm_mul_ps(zt, zt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); +} + +inline float_t vec4::distance_squared(const vec4& left, const vec4& right) { + __m128 zt; + zt = _mm_sub_ps(vec4::load_xmm(left), vec4::load_xmm(right)); + zt = _mm_mul_ps(zt, zt); + zt = _mm_hadd_ps(zt, zt); + return _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); +} + +inline vec4 vec4::lerp(const vec4& left, const vec4& right, const vec4& blend) { + __m128 b1; + __m128 b2; + b1 = vec4::load_xmm(blend); + b2 = vec4::load_xmm(1.0f); + b2 = _mm_sub_ps(b2, b1); + return vec4::store_xmm(_mm_add_ps(_mm_mul_ps(vec4::load_xmm(left), b2), + _mm_mul_ps(vec4::load_xmm(right), b1))); +} + +inline vec4 vec4::lerp(const vec4& left, const vec4& right, const float_t blend) { + __m128 b1; + __m128 b2; + b1 = vec4::load_xmm(blend); + b2 = vec4::load_xmm(1.0f); + b2 = _mm_sub_ps(b2, b1); + return vec4::store_xmm(_mm_add_ps(_mm_mul_ps(vec4::load_xmm(left), b2), + _mm_mul_ps(vec4::load_xmm(right), b1))); +} + +inline vec4 vec4::normalize(const vec4& left) { + __m128 xt; + __m128 zt; + xt = vec4::load_xmm(left); + zt = _mm_mul_ps(xt, xt); + zt = _mm_hadd_ps(zt, zt); + zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); + if (zt.m128_f32[0] != 0.0f) + zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; + return vec4::store_xmm(_mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0))); +} + +inline vec4 vec4::rcp(const vec4& left) { + return vec4::store_xmm(_mm_div_ps(vec4::load_xmm(1.0f), vec4::load_xmm(left))); +} + +inline vec4 vec4::min(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_min_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 vec4::max(const vec4& left, const vec4& right) { + return vec4::store_xmm(_mm_max_ps(vec4::load_xmm(left), vec4::load_xmm(right))); +} + +inline vec4 vec4::clamp(const vec4& left, const vec4& min, const vec4& max) { + return vec4::store_xmm(_mm_min_ps(_mm_max_ps(vec4::load_xmm(left), + vec4::load_xmm(min)), vec4::load_xmm(max))); +} + +inline vec4 vec4::clamp(const vec4& left, const float_t min, const float_t max) { + return vec4::store_xmm(_mm_min_ps(_mm_max_ps(vec4::load_xmm(left), + vec4::load_xmm(min)), vec4::load_xmm(max))); +} + +inline vec4 vec4::mult_min_max(const vec4& left, const vec4& min, const vec4& max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec4::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(max)); + return vec4::store_xmm(_mm_mul_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec4 vec4::mult_min_max(const vec4& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec4::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(max)); + return vec4::store_xmm(_mm_mul_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec4 vec4::div_min_max(const vec4& left, const vec4& min, const vec4& max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec4::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(max)); + return vec4::store_xmm(_mm_div_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec4 vec4::div_min_max(const vec4& left, const float_t min, const float_t max) { + __m128 xt; + __m128 yt; + __m128 zt; + xt = vec4::load_xmm(left); + yt = _mm_and_ps(_mm_cmplt_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(-min)); + zt = _mm_and_ps(_mm_cmpge_ps(xt, vec4::load_xmm(vec4_null)), vec4::load_xmm(max)); + return vec4::store_xmm(_mm_div_ps(xt, _mm_or_ps(yt, zt))); +} + +inline vec2i::vec2i() : x(), y() { + +} + +inline vec2i::vec2i(int32_t value) : x(value), y(value) { + +} + +inline vec2i::vec2i(int32_t x, int32_t y) : x(x), y(y) { + +} + +inline vec2i operator +(const vec2i& left, const vec2i& right) { + return vec2i::store_xmm(_mm_add_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i operator +(const vec2i& left, const int32_t right) { + return vec2i::store_xmm(_mm_add_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i operator +(const int32_t left, const vec2i& right) { + return vec2i::store_xmm(_mm_add_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i operator -(const vec2i& left, const vec2i& right) { + return vec2i::store_xmm(_mm_sub_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i operator -(const vec2i& left, const int32_t right) { + return vec2i::store_xmm(_mm_sub_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i operator -(const int32_t left, const vec2i& right) { + return vec2i::store_xmm(_mm_sub_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i vec2i::min(const vec2i& left, const vec2i& right) { + return vec2i::store_xmm(_mm_min_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i vec2i::max(const vec2i& left, const vec2i& right) { + return vec2i::store_xmm(_mm_max_epi32(vec2i::load_xmm(left), vec2i::load_xmm(right))); +} + +inline vec2i vec2i::clamp(const vec2i& left, const vec2i& min, const vec2i& max) { + return vec2i::store_xmm(_mm_min_epi32(_mm_max_epi32(vec2i::load_xmm(left), + vec2i::load_xmm(min)), vec2i::load_xmm(max))); +} + +inline vec2i vec2i::clamp(const vec2i& left, const int32_t min, const int32_t max) { + return vec2i::store_xmm(_mm_min_epi32(_mm_max_epi32(vec2i::load_xmm(left), + vec2i::load_xmm(min)), vec2i::load_xmm(max))); +} + +inline vec3i::vec3i() : x(), y(), z() { + +} + +inline vec3i::vec3i(int32_t value) : x(value), y(value), z(value) { + +} + +inline vec3i::vec3i(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z) { + +} + +inline vec3i operator +(const vec3i& left, const vec3i& right) { + return vec3i::store_xmm(_mm_add_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i operator +(const vec3i& left, const int32_t right) { + return vec3i::store_xmm(_mm_add_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i operator +(const int32_t left, const vec3i& right) { + return vec3i::store_xmm(_mm_add_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i operator -(const vec3i& left, const vec3i& right) { + return vec3i::store_xmm(_mm_sub_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i operator -(const vec3i& left, const int32_t right) { + return vec3i::store_xmm(_mm_sub_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i operator -(const int32_t left, const vec3i& right) { + return vec3i::store_xmm(_mm_sub_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i vec3i::min(const vec3i& left, const vec3i& right) { + return vec3i::store_xmm(_mm_min_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i vec3i::max(const vec3i& left, const vec3i& right) { + return vec3i::store_xmm(_mm_max_epi32(vec3i::load_xmm(left), vec3i::load_xmm(right))); +} + +inline vec3i vec3i::clamp(const vec3i& left, const vec3i& min, const vec3i& max) { + return vec3i::store_xmm(_mm_min_epi32(_mm_max_epi32(vec3i::load_xmm(left), + vec3i::load_xmm(min)), vec3i::load_xmm(max))); +} + +inline vec3i vec3i::clamp(const vec3i& left, const int32_t min, const int32_t max) { + return vec3i::store_xmm(_mm_min_epi32(_mm_max_epi32(vec3i::load_xmm(left), + vec3i::load_xmm(min)), vec3i::load_xmm(max))); +} + +inline vec4i::vec4i() : x(), y(), z(), w() { + +} + +inline vec4i::vec4i(int32_t value) : x(value), y(value), z(value), w(value) { + +} + +inline vec4i::vec4i(int32_t x, int32_t y, int32_t z, int32_t w) : x(x), y(y), z(z), w(w) { + +} + +inline vec4i operator +(const vec4i& left, const vec4i& right) { + return vec4i::store_xmm(_mm_add_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i operator +(const vec4i& left, const int32_t right) { + return vec4i::store_xmm(_mm_add_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i operator +(const int32_t left, const vec4i& right) { + return vec4i::store_xmm(_mm_add_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i operator -(const vec4i& left, const vec4i& right) { + return vec4i::store_xmm(_mm_sub_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i operator -(const vec4i& left, const int32_t right) { + return vec4i::store_xmm(_mm_sub_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i operator -(const int32_t left, const vec4i& right) { + return vec4i::store_xmm(_mm_sub_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i vec4i::min(const vec4i& left, const vec4i& right) { + return vec4i::store_xmm(_mm_min_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i vec4i::max(const vec4i& left, const vec4i& right) { + return vec4i::store_xmm(_mm_max_epi32(vec4i::load_xmm(left), vec4i::load_xmm(right))); +} + +inline vec4i vec4i::clamp(const vec4i& left, const vec4i& min, const vec4i& max) { + return vec4i::store_xmm(_mm_min_epi32(_mm_max_epi32(vec4i::load_xmm(left), + vec4i::load_xmm(min)), vec4i::load_xmm(max))); +} + +inline vec4i vec4i::clamp(const vec4i& left, const int32_t min, const int32_t max) { + return vec4i::store_xmm(_mm_min_epi32(_mm_max_epi32(vec4i::load_xmm(left), + vec4i::load_xmm(min)), vec4i::load_xmm(max))); +} + +inline void vec2i8_to_vec2(vec2i8& src, vec2& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; +} + +inline void vec3i8_to_vec3(vec3i8& src, vec3& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; +} + +inline void vec4i8_to_vec4(vec4i8& src, vec4& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; + dst.w = (float_t)src.w; +} + +inline void vec2_to_vec2i8(vec2& src, vec2i8& dst) { + dst.x = (int8_t)src.x; + dst.y = (int8_t)src.y; +} + +inline void vec3_to_vec3i8(vec3& src, vec3i8& dst) { + dst.x = (int8_t)src.x; + dst.y = (int8_t)src.y; + dst.z = (int8_t)src.z; +} + +inline void vec4_to_vec4i8(vec4& src, vec4i8& dst) { + dst.x = (int8_t)src.x; + dst.y = (int8_t)src.y; + dst.z = (int8_t)src.z; + dst.w = (int8_t)src.w; +} + +inline void vec2u8_to_vec2(vec2u8& src, vec2& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; +} + +inline void vec3u8_to_vec3(vec3u8& src, vec3& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; +} + +inline void vec4u8_to_vec4(vec4u8& src, vec4& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; + dst.w = (float_t)src.w; +} + +inline void vec2_to_vec2u8(vec2& src, vec2u8& dst) { + dst.x = (uint8_t)src.x; + dst.y = (uint8_t)src.y; +} + +inline void vec3_to_vec3u8(vec3& src, vec3u8& dst) { + dst.x = (uint8_t)src.x; + dst.y = (uint8_t)src.y; + dst.z = (uint8_t)src.z; +} + +inline void vec4_to_vec4u8(vec4& src, vec4u8& dst) { + dst.x = (uint8_t)src.x; + dst.y = (uint8_t)src.y; + dst.z = (uint8_t)src.z; + dst.w = (uint8_t)src.w; +} + +inline void vec2i16_to_vec2(vec2i16& src, vec2& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; +} + +inline void vec3i16_to_vec3(vec3i16& src, vec3& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; +} + +inline void vec4i16_to_vec4(vec4i16& src, vec4& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; + dst.w = (float_t)src.w; +} + +inline void vec2_to_vec2i16(vec2& src, vec2i16& dst) { + dst.x = (int16_t)src.x; + dst.y = (int16_t)src.y; +} + +inline void vec3_to_vec3i16(vec3& src, vec3i16& dst) { + dst.x = (int16_t)src.x; + dst.y = (int16_t)src.y; + dst.z = (int16_t)src.z; +} + +inline void vec4_to_vec4i16(vec4& src, vec4i16& dst) { + dst.x = (int16_t)src.x; + dst.y = (int16_t)src.y; + dst.z = (int16_t)src.z; + dst.w = (int16_t)src.w; +} + +inline void vec2u16_to_vec2(vec2u16& src, vec2& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; +} + +inline void vec3u16_to_vec3(vec3u16& src, vec3& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; +} + +inline void vec4u16_to_vec4(vec4u16& src, vec4& dst) { + dst.x = (float_t)src.x; + dst.y = (float_t)src.y; + dst.z = (float_t)src.z; + dst.w = (float_t)src.w; +} + +inline void vec2_to_vec2u16(vec2& src, vec2u16& dst) { + dst.x = (uint16_t)src.x; + dst.y = (uint16_t)src.y; +} + +inline void vec3_to_vec3u16(vec3& src, vec3u16& dst) { + dst.x = (uint16_t)src.x; + dst.y = (uint16_t)src.y; + dst.z = (uint16_t)src.z; +} + +inline void vec4_to_vec4u16(vec4& src, vec4u16& dst) { + dst.x = (uint16_t)src.x; + dst.y = (uint16_t)src.y; + dst.z = (uint16_t)src.z; + dst.w = (uint16_t)src.w; +} + +inline void vec2h_to_vec2(vec2h& src, vec2& dst) { + dst.x = half_to_float(src.x); + dst.y = half_to_float(src.y); +} + +inline void vec3h_to_vec3(vec3h& src, vec3& dst) { + dst.x = half_to_float(src.x); + dst.y = half_to_float(src.y); + dst.z = half_to_float(src.z); +} + +inline void vec4h_to_vec4(vec4h& src, vec4& dst) { + dst.x = half_to_float(src.x); + dst.y = half_to_float(src.y); + dst.z = half_to_float(src.z); + dst.w = half_to_float(src.w); +} + +inline void vec2_to_vec2h(vec2& src, vec2h& dst) { + dst.x = float_to_half(src.x); + dst.y = float_to_half(src.y); +} + +inline void vec3_to_vec3h(vec3& src, vec3h& dst) { + dst.x = float_to_half(src.x); + dst.y = float_to_half(src.y); + dst.z = float_to_half(src.z); +} + +inline void vec4_to_vec4h(vec4& src, vec4h& dst) { + dst.x = float_to_half(src.x); + dst.y = float_to_half(src.y); + dst.z = float_to_half(src.z); + dst.w = float_to_half(src.w); +} + +inline void vec2i8_to_vec2i(vec2i8& src, vec2i& dst) { + dst.x = src.x; + dst.y = src.y; +} + +inline void vec3i8_to_vec3i(vec3i8& src, vec3i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; +} + +inline void vec4i8_to_vec4i(vec4i8& src, vec4i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; + dst.w = src.w; +} + +inline void vec2i_to_vec2i8(vec2i& src, vec2i8& dst) { + dst.x = (int8_t)src.x; + dst.y = (int8_t)src.y; +} + +inline void vec3i_to_vec3i8(vec3i& src, vec3i8& dst) { + dst.x = (int8_t)src.x; + dst.y = (int8_t)src.y; + dst.z = (int8_t)src.z; +} + +inline void vec4i_to_vec4i8(vec4i& src, vec4i8& dst) { + dst.x = (int8_t)src.x; + dst.y = (int8_t)src.y; + dst.z = (int8_t)src.z; + dst.w = (int8_t)src.w; +} + +inline void vec2u8_to_vec2i(vec2u8& src, vec2i& dst) { + dst.x = src.x; + dst.y = src.y; +} + +inline void vec3u8_to_vec4i(vec3u8& src, vec3i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; +} + +inline void vec4u8_to_vec4i(vec4u8& src, vec4i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; + dst.w = src.w; +} + +inline void vec2i_to_vec2u8(vec2i& src, vec2u8& dst) { + dst.x = (uint8_t)src.x; + dst.y = (uint8_t)src.y; +} + +inline void vec3i_to_vec3u8(vec3i& src, vec3u8& dst) { + dst.x = (uint8_t)src.x; + dst.y = (uint8_t)src.y; + dst.z = (uint8_t)src.z; +} + +inline void vec4i_to_vec4u8(vec4i& src, vec4u8& dst) { + dst.x = (uint8_t)src.x; + dst.y = (uint8_t)src.y; + dst.z = (uint8_t)src.z; + dst.w = (uint8_t)src.w; +} + +inline void vec2i16_to_vec2i(vec2i16& src, vec2i& dst) { + dst.x = src.x; + dst.y = src.y; +} + +inline void vec3i16_to_vec4i(vec3i16& src, vec3i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; +} + +inline void vec4i16_to_vec4i(vec4i16& src, vec4i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; + dst.w = src.w; +} + +inline void vec2i_to_vec2i16(vec2i& src, vec2i16& dst) { + dst.x = (int16_t)src.x; + dst.y = (int16_t)src.y; +} + +inline void vec3i_to_vec3i16(vec3i& src, vec3i16& dst) { + dst.x = (int16_t)src.x; + dst.y = (int16_t)src.y; + dst.z = (int16_t)src.z; +} + +inline void vec4i_to_vec4i16(vec4i& src, vec4i16& dst) { + dst.x = (int16_t)src.x; + dst.y = (int16_t)src.y; + dst.z = (int16_t)src.z; + dst.w = (int16_t)src.w; +} + +inline void vec2u16_to_vec2i(vec2u16& src, vec2i& dst) { + dst.x = src.x; + dst.y = src.y; +} + +inline void vec3u16_to_vec4i(vec3u16& src, vec3i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; +} + +inline void vec4u16_to_vec4i(vec4u16& src, vec4i& dst) { + dst.x = src.x; + dst.y = src.y; + dst.z = src.z; + dst.w = src.w; +} + +inline void vec2i_to_vec2u16(vec2i& src, vec2u16& dst) { + dst.x = (uint16_t)src.x; + dst.y = (uint16_t)src.y; +} + +inline void vec3i_to_vec3u16(vec3i& src, vec3u16& dst) { + dst.x = (uint16_t)src.x; + dst.y = (uint16_t)src.y; + dst.z = (uint16_t)src.z; +} + +inline void vec4i_to_vec4u16(vec4i& src, vec4u16& dst) { + dst.x = (uint16_t)src.x; + dst.y = (uint16_t)src.y; + dst.z = (uint16_t)src.z; + dst.w = (uint16_t)src.w; +} + +inline void vec2_add(const vec2& x, const vec2& y, vec2& z) { + z = x + y; +} + +inline void vec2_add_scalar(const vec2& x, const float_t y, vec2& z) { + z = x + y; +} + +inline void vec2_sub(const vec2& x, const vec2& y, vec2& z) { + z = x - y; +} + +inline void vec2_sub_scalar(const vec2& x, const float_t y, vec2& z) { + z = x - y; +} + +inline void vec2_mult(const vec2& x, const vec2& y, vec2& z) { + z = x * y; +} + +inline void vec2_mult_scalar(const vec2& x, const float_t y, vec2& z) { + z = x * y; +} + +inline void vec2_div(const vec2& x, const vec2& y, vec2& z) { + z = x / y; +} + +inline void vec2_div_scalar(const vec2& x, const float_t y, vec2& z) { + z = x / y; +} + +inline void vec2_and(const vec2& x, const vec2& y, vec2& z) { + z = x & y; +} + +inline void vec2_and_scalar(const vec2& x, const float_t y, vec2& z) { + z = x & y; +} + +inline void vec2_xor(const vec2& x, const vec2& y, vec2& z) { + z = x ^ y; +} + +inline void vec2_xor_scalar(const vec2& x, const float_t y, vec2& z) { + z = x ^ y; +} + +inline void vec2_negate(const vec2& x, vec2& z) { + z = -x; +} + +inline void vec2_dot(const vec2& x, const vec2& y, float_t& z) { + z = vec2::dot(x, y); +} + +inline void vec2_length(const vec2& x, float_t& z) { + z = vec2::length(x); +} + +inline void vec2_length_squared(const vec2& x, float_t& z) { + z = vec2::length_squared(x); +} + +inline void vec2_distance(const vec2& x, const vec2& y, float_t& z) { + z = vec2::distance(x, y); +} + +inline void vec2_distance_squared(const vec2& x, const vec2& y, float_t& z) { + z = vec2::distance_squared(x, y); +} + +inline void vec2_lerp(const vec2& x, const vec2& y, vec2& z, const float_t blend) { + z = vec2::lerp(x, y, blend); +} + +inline void vec2_lerp_scalar(const vec2& x, const vec2& y, vec2& z, const float_t blend) { + z = vec2::lerp(x, y, blend); +} + +inline void vec2_normalize(const vec2& x, vec2& z) { + z = vec2::normalize(x); +} + +inline void vec2_rcp(const vec2& x, vec2& z) { + z = vec2::rcp(x); +} + +inline void vec2_min(const vec2& x, const vec2& y, vec2& z) { + z = vec2::min(x, y); +} + +inline void vec2_max(const vec2& x, const vec2& y, vec2& z) { + z = vec2::max(x, y); +} + +inline void vec2_clamp(const vec2& x, const vec2& y, const vec2& z, vec2& w) { + w = vec2::clamp(x, y, z); +} + +inline void vec2_clamp_scalar(const vec2& x, const float_t y, const float_t z, vec2& w) { + w = vec2::clamp(x, y, z); +} + +inline void vec2_mult_min_max(const vec2& x, const vec2& y, const vec2& z, vec2& w) { + w = vec2::mult_min_max(x, y, z); +} + +inline void vec2_mult_min_max_scalar(const vec2& x, const float_t y, const float_t z, vec2& w) { + w = vec2::mult_min_max(x, y, z); +} + +inline void vec2_div_min_max(const vec2& x, const vec2& y, const vec2& z, vec2& w) { + w = vec2::div_min_max(x, y, z); +} + +inline void vec2_div_min_max_scalar(const vec2& x, const float_t y, const float_t z, vec2& w) { + w = vec2::div_min_max(x, y, z); +} + +inline void vec3_add(const vec3& x, const vec3& y, vec3& z) { + z = x + y; +} + +inline void vec3_add_scalar(const vec3& x, const float_t y, vec3& z) { + z = x + y; +} + +inline void vec3_sub(const vec3& x, const vec3& y, vec3& z) { + z = x - y; +} + +inline void vec3_sub_scalar(const vec3& x, const float_t y, vec3& z) { + z = x - y; +} + +inline void vec3_mult(const vec3& x, const vec3& y, vec3& z) { + z = x * y; +} + +inline void vec3_mult_scalar(const vec3& x, const float_t y, vec3& z) { + z = x * y; +} + +inline void vec3_div(const vec3& x, const vec3& y, vec3& z) { + z = x / y; +} + +inline void vec3_div_scalar(const vec3& x, const float_t y, vec3& z) { + z = x / y; +} + +inline void vec3_and(const vec3& x, const vec3& y, vec3& z) { + z = x & y; +} + +inline void vec3_and_scalar(const vec3& x, const float_t y, vec3& z) { + z = x & y; +} + +inline void vec3_xor(const vec3& x, const vec3& y, vec3& z) { + z = x ^ y; +} + +inline void vec3_xor_scalar(const vec3& x, const float_t y, vec3& z) { + z = x ^ y; +} + +inline void vec3_negate(const vec3& x, vec3& z) { + z = -x; +} + +inline void vec3_dot(const vec3& x, const vec3& y, float_t& z) { + z = vec3::dot(x, y); +} + +inline void vec3_length(const vec3& x, float_t& z) { + z = vec3::length(x); +} + +inline void vec3_length_squared(const vec3& x, float_t& z) { + z = vec3::length_squared(x); +} + +inline void vec3_distance(const vec3& x, const vec3& y, float_t& z) { + z = vec3::distance(x, y); +} + +inline void vec3_distance_squared(const vec3& x, const vec3& y, float_t& z) { + z = vec3::distance_squared(x, y); +} + +inline void vec3_lerp(const vec3& x, const vec3& y, vec3& z, const vec3& blend) { + z = vec3::lerp(x, y, blend); +} + +inline void vec3_lerp_scalar(const vec3& x, const vec3& y, vec3& z, const float_t blend) { + z = vec3::lerp(x, y, blend); +} + +inline void vec3_normalize(const vec3& x, vec3& z) { + z = vec3::normalize(x); +} + +inline void vec3_rcp(const vec3& x, vec3& z) { + z = vec3::rcp(x); +} + +inline void vec3_min(const vec3& x, const vec3& y, vec3& z) { + z = vec3::min(x, y); +} + +inline void vec3_max(const vec3& x, const vec3& y, vec3& z) { + z = vec3::max(x, y); +} + +inline void vec3_clamp(const vec3& x, const vec3& y, const vec3& z, vec3& w) { + w = vec3::clamp(x, y, z); +} + +inline void vec3_clamp_scalar(const vec3& x, const vec3& y, const float_t z, vec3& w) { + w = vec3::clamp(x, y, z); +} + +inline void vec3_mult_min_max(const vec3& x, const vec3& y, const vec3& z, vec3& w) { + w = vec3::mult_min_max(x, y, z); +} + +inline void vec3_mult_min_max_scalar(const vec3& x, const vec3& y, const float_t z, vec3& w) { + w = vec3::mult_min_max(x, y, z); +} + +inline void vec3_div_min_max(const vec3& x, const vec3& y, const vec3& z, vec3& w) { + w = vec3::div_min_max(x, y, z); +} + +inline void vec3_div_min_max_scalar(const vec3& x, const vec3& y, const float_t z, vec3& w) { + w = vec3::div_min_max(x, y, z); +} + +inline void vec3_cross(const vec3& x, const vec3& y, vec3& z) { + z = vec3::cross(x, y); +} + +inline void vec4_add(const vec4& x, const vec4& y, vec4& z) { + z = x + y; +} + +inline void vec4_add_scalar(const vec4& x, const float_t y, vec4& z) { + z = x + y; +} + +inline void vec4_sub(const vec4& x, const vec4& y, vec4& z) { + z = x - y; +} + +inline void vec4_sub_scalar(const vec4& x, const float_t y, vec4& z) { + z = x - y; +} + +inline void vec4_mult(const vec4& x, const vec4& y, vec4& z) { + z = x * y; +} + +inline void vec4_mult_scalar(const vec4& x, const float_t y, vec4& z) { + z = x * y; +} + +inline void vec4_div(const vec4& x, const vec4& y, vec4& z) { + z = x / y; +} + +inline void vec4_div_scalar(const vec4& x, const float_t y, vec4& z) { + z = x / y; +} + +inline void vec4_and(const vec4& x, const vec4& y, vec4& z) { + z = x & y; +} + +inline void vec4_and_scalar(const vec4& x, const float_t y, vec4& z) { + z = x & y; +} + +inline void vec4_xor(const vec4& x, const vec4& y, vec4& z) { + z = x ^ y; +} + +inline void vec4_xor_scalar(const vec4& x, const float_t y, vec4& z) { + z = x ^ y; +} + +inline void vec4_negate(const vec4& x, vec4& z) { + z = -x; +} + +inline void vec4_dot(const vec4& x, const vec4& y, float_t& z) { + z = vec4::dot(x, y); +} + +inline void vec4_length(const vec4& x, float_t& z) { + z = vec4::length(x); +} + +inline void vec4_length_squared(const vec4& x, float_t& z) { + z = vec4::length_squared(x); +} + +inline void vec4_distance(const vec4& x, const vec4& y, float_t& z) { + z = vec4::distance(x, y); +} + +inline void vec4_distance_squared(const vec4& x, const vec4& y, float_t& z) { + z = vec4::distance_squared(x, y); +} + +inline void vec4_lerp(const vec4& x, const vec4& y, vec4& z, const vec4& blend) { + z = vec4::lerp(x, y, blend); +} + +inline void vec4_lerp_scalar(const vec4& x, const vec4& y, vec4& z, const float_t blend) { + z = vec4::lerp(x, y, blend); +} + +inline void vec4_normalize(const vec4& x, vec4& z) { + z = vec4::normalize(x); +} + +inline void vec4_rcp(const vec4& x, vec4& z) { + z = vec4::rcp(x); +} + +inline void vec4_min(const vec4& x, const vec4& y, vec4& z) { + z = vec4::min(x, y); +} + +inline void vec4_max(const vec4& x, const vec4& y, vec4& z) { + z = vec4::max(x, y); +} + +inline void vec4_clamp(const vec4& x, const vec4& y, const vec4& z, vec4& w) { + w = vec4::clamp(x, y, z); +} + +inline void vec4_clamp_scalar(const vec4& x, const float_t y, const float_t z, vec4& w) { + w = vec4::clamp(x, y, z); +} + +inline void vec4_mult_min_max(const vec4& x, const vec4& y, const vec4& z, vec4& w) { + w = vec4::mult_min_max(x, y, z); +} + +inline void vec4_mult_min_max_scalar(const vec4& x, const float_t y, const float_t z, vec4& w) { + w = vec4::mult_min_max(x, y, z); +} + +inline void vec4_div_min_max(const vec4& x, const vec4& y, const vec4& z, vec4& w) { + w = vec4::div_min_max(x, y, z); +} + +inline void vec4_div_min_max_scalar(const vec4& x, const float_t y, const float_t z, vec4& w) { + w = vec4::div_min_max(x, y, z); +} + +inline void vec2i_add(const vec2i& x, const vec2i& y, vec2i& z) { + z = x + y; +} + +inline void vec2i_add_scalar(const vec2i& x, const int32_t y, vec2i& z) { + z = x + y; +} + +inline void vec2i_sub(const vec2i& x, const vec2i& y, vec2i& z) { + z = x - y; +} + +inline void vec2i_sub_scalar(const vec2i& x, const int32_t y, vec2i& z) { + z = x - y; +} + +inline void vec3i_add(const vec3i& x, const vec3i& y, vec3i& z) { + z = x + y; +} + +inline void vec3i_add_scalar(const vec3i& x, const int32_t y, vec3i& z) { + z = x + y; +} + +inline void vec3i_sub(const vec3i& x, const vec3i& y, vec3i& z) { + z = x - y; +} + +inline void vec3i_sub_scalar(const vec3i& x, const int32_t y, vec3i& z) { + z = x - y; +} + +inline void vec4i_add(const vec4i& x, const vec4i& y, vec4i& z) { + z = x + y; +} + +inline void vec4i_add_scalar(const vec4i& x, const int32_t y, vec4i& z) { + z = x + y; } -#define vec4_xor_scalar(x, y, z) \ -{ \ - __m128 yt; \ - yt = _mm_set_ss(y); \ - _mm_storeu_ps((float*)&(z), _mm_xor_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ +inline void vec4i_sub(const vec4i& x, const vec4i& y, vec4i& z) { + z = x - y; } -#define vec4_negate(x, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_xor_ps(_mm_loadu_ps((float*)&(x)), vec4_negate)); \ +inline void vec4i_sub_scalar(const vec4i& x, const int32_t y, vec4i& z) { + z = x - y; } -#define vec4_dot(x, y, z) \ -{ \ - __m128 zt; \ - zt = _mm_mul_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y))); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ +inline void vec2_to_vec2i(const vec2& x, vec2i& z) { + z = vec2i::store_xmm(_mm_cvtps_epi32(vec2::load_xmm(x))); } -#define vec4_length(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - xt = _mm_loadu_ps((float*)&(x)); \ - zt = _mm_mul_ps(xt, xt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ +inline void vec2i_to_vec2(const vec2i& x, vec2& z) { + z = vec2::store_xmm(_mm_cvtepi32_ps(vec2i::load_xmm(x))); } -#define vec4_length_squared(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - xt = _mm_loadu_ps((float*)&(x)); \ - zt = _mm_mul_ps(xt, xt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ +inline void vec3_to_vec3i(const vec3& x, vec3i& z) { + z = vec3i::store_xmm(_mm_cvtps_epi32(vec3::load_xmm(x))); } -#define vec4_distance(x, y, z) \ -{ \ - __m128 zt; \ - zt = _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y))); \ - zt = _mm_mul_ps(zt, zt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ +inline void vec3i_to_vec3(const vec3i& x, vec3& z) { + z = vec3::store_xmm(_mm_cvtepi32_ps(vec3i::load_xmm(x))); } -#define vec4_distance_squared(x, y, z) \ -{ \ - __m128 zt; \ - zt = _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y))); \ - zt = _mm_mul_ps(zt, zt); \ - zt = _mm_hadd_ps(zt, zt); \ - (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ +inline void vec4_to_vec4i(const vec4& x, vec4i& z) { + z = vec4i::store_xmm(_mm_cvtps_epi32(vec4::load_xmm(x))); } -#define vec4_lerp(x, y, z, blend) \ -{ \ - __m128 b1; \ - __m128 b2; \ - b1 = _mm_loadu_ps((float*)&(blend)); \ - b2 = _mm_sub_ps(_mm_loadu_ps((float*)&(vec4_identity)), b1); \ - _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_mul_ps(_mm_loadu_ps((float*)&(x)), b2), \ - _mm_mul_ps(_mm_loadu_ps((float*)&(y)), b1))); \ -} - -#define vec4_lerp_scalar(x, y, z, blend) \ -{ \ - __m128 b1; \ - __m128 b2; \ - b1 = _mm_set_ss(blend); \ - b1 = _mm_shuffle_ps(b1, b1, 0); \ - b2 = _mm_sub_ps(_mm_loadu_ps((float*)&(vec4_identity)), b1); \ - _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_mul_ps(_mm_loadu_ps((float*)&(x)), b2), \ - _mm_mul_ps(_mm_loadu_ps((float*)&(y)), b1))); \ -} - -#define vec4_normalize(x, z) \ -{ \ - __m128 xt; \ - __m128 zt; \ - xt = _mm_loadu_ps((float*)&(x)); \ - zt = _mm_mul_ps(xt, xt); \ - zt = _mm_hadd_ps(zt, zt); \ - zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); \ - if (zt.m128_f32[0] != 0.0f) \ - zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; \ - _mm_storeu_ps((float*)&(z), _mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0))); \ -} - -#define vec4_rcp(x, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_div_ps(_mm_loadu_ps((float*)&(vec4_identity)), _mm_loadu_ps((float*)&(x)))); \ -} - -#define vec4_min(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_min_ps(_mm_loadu_ps((float*)&(x)), yt)); \ -} - -#define vec4_max(x, y, z) \ -{ \ - _mm_storeu_ps((float*)&(z), _mm_max_ps(_mm_loadu_ps((float*)&(x)), yt)); \ -} - -#define vec4_clamp(x, y, z, w) \ -{ \ - _mm_storeu_ps((float*)&(w), _mm_min_ps(_mm_max_ps(_mm_loadu_ps((float*)&(x)), yt), zt)); \ -} - -#define vec4_clamp_scalar(x, y, z, w) \ -{ \ - __m128 yt; \ - __m128 zt; \ - yt = _mm_set_ss(y); \ - zt = _mm_set_ss(z); \ - _mm_storeu_ps((float*)&(w), _mm_min_ps(_mm_max_ps(_mm_loadu_ps((float*)&(x)), \ - _mm_shuffle_ps(yt, yt, 0)), _mm_shuffle_ps(zt, zt, 0))); \ -} - -#define vec4_mult_min_max(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 wt; \ - xt = _mm_loadu_ps((float*)&(x)); \ - yt = _mm_xor_ps(_mm_loadu_ps((float*)&(y)), vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(_mm_loadu_ps((float*)&(z)), _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - _mm_storeu_ps((float*)&(w), _mm_mul_ps(xt, wt)); \ -} - -#define vec4_mult_min_max_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - xt = _mm_loadu_ps((float*)&(xt)); \ - yt = _mm_set_ss(y); \ - yt = _mm_shuffle_ps(yt, yt, 0); \ - zt = _mm_set_ss(z); \ - zt = _mm_shuffle_ps(zt, zt, 0); \ - yt = _mm_xor_ps(yt, vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - _mm_storeu_ps((float*)&(w), _mm_mul_ps(xt, wt)); \ -} - -#define vec4_div_min_max(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 wt; \ - xt = _mm_loadu_ps((float*)&(x)); \ - yt = _mm_xor_ps(_mm_loadu_ps((float*)&(y)), vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(_mm_loadu_ps((float*)&(z)), _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - _mm_storeu_ps((float*)&(w), _mm_div_ps(xt, wt)); \ -} - -#define vec4_div_min_max_scalar(x, y, z, w) \ -{ \ - __m128 xt; \ - __m128 yt; \ - __m128 zt; \ - __m128 wt; \ - xt = _mm_loadu_ps((float*)&(x)); \ - yt = _mm_set_ss(y); \ - yt = _mm_shuffle_ps(yt, yt, 0); \ - zt = _mm_set_ss(z); \ - zt = _mm_shuffle_ps(zt, zt, 0); \ - yt = _mm_xor_ps(yt, vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ - _mm_storeu_ps((float*)&(w), _mm_div_ps(xt, wt)); \ -} - -#define vec2i_add(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec2i*)&xt = (x); \ - *(vec2i*)&yt = (y); \ - zt = _mm_add_epi32(xt, yt); \ - (z) = *(vec2i*)&zt; \ -} - -#define vec2i_add_scalar(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec2i*)&xt = (x); \ - yt = _mm_set1_epi32(y); \ - zt = _mm_add_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ - (z) = *(vec2i*)&zt; \ -} - -#define vec2i_sub(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec2i*)&xt = (x); \ - *(vec2i*)&yt = (y); \ - zt = _mm_sub_epi32(xt, yt); \ - (z) = *(vec2i*)&zt; \ -} - -#define vec2i_sub_scalar(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec2i*)&xt = (x); \ - yt = _mm_set1_epi32(y); \ - zt = _mm_sub_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ - (z) = *(vec2i*)&zt; \ -} - -#define vec2_to_vec2i(x, z) \ -{ \ - __m128 xt; \ - __m128i zt; \ - *(vec2*)&xt = (x); \ - zt = _mm_cvtps_epi32(xt); \ - (z) = *(vec2i*)&zt; \ -} - -#define vec2i_to_vec2(x, z) \ -{ \ - __m128i xt; \ - __m128 zt; \ - *(vec2i*)&xt = (x); \ - zt = _mm_cvtepi32_ps(xt); \ - (z) = *(vec2*)&zt; \ -} - -#define vec3i_add(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec3i*)&xt = (x); \ - *(vec3i*)&yt = (y); \ - zt = _mm_add_epi32(xt, yt); \ - (z) = *(vec3i*)&zt; \ -} - -#define vec3i_add_scalar(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec3i*)&xt = (x); \ - yt = _mm_set1_epi32(y); \ - zt = _mm_add_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ - (z) = *(vec3i*)&zt; \ -} - -#define vec3i_sub(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec3i*)&xt = (x); \ - *(vec3i*)&yt = (y); \ - zt = _mm_sub_epi32(xt, yt); \ - (z) = *(vec3i*)&zt; \ -} - -#define vec3i_sub_scalar(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec3i*)&xt = (x); \ - yt = _mm_set1_epi32(y); \ - zt = _mm_sub_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ - (z) = *(vec3i*)&zt; \ -} - -#define vec3_to_vec3i(x, z) \ -{ \ - __m128 xt; \ - __m128i zt; \ - *(vec3*)&xt = (x); \ - zt = _mm_cvtps_epi32(xt); \ - (z) = *(vec3i*)&zt; \ -} - -#define vec3i_to_vec3(x, z) \ -{ \ - __m128i xt; \ - __m128 zt; \ - *(vec3i*)&xt = (x); \ - zt = _mm_cvtepi32_ps(xt); \ - (z) = *(vec3*)&zt; \ -} - -#define vec4i_add(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec4i*)&xt = (x); \ - *(vec4i*)&yt = (y); \ - zt = _mm_add_epi32(xt, yt); \ - (z) = *(vec4i*)&zt; \ -} - -#define vec4i_add_scalar(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec4i*)&xt = (x); \ - yt = _mm_set1_epi32(y); \ - zt = _mm_add_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ - (z) = *(vec4i*)&zt; \ -} - -#define vec4i_sub(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec4i*)&xt = (x); \ - *(vec4i*)&yt = (y); \ - zt = _mm_sub_epi32(xt, yt); \ - (z) = *(vec4i*)&zt; \ -} - -#define vec4i_sub_scalar(x, y, z) \ -{ \ - __m128i xt; \ - __m128i yt; \ - __m128i zt; \ - *(vec4i*)&xt = (x); \ - yt = _mm_set1_epi32(y); \ - zt = _mm_sub_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ - (z) = *(vec4i*)&zt; \ -} - -#define vec4_to_vec4i(x, z) \ -{ \ - __m128i zt; \ - zt = _mm_cvtps_epi32(_mm_loadu_ps((float*)&(x))); \ - (z) = *(vec4i*)&zt; \ -} - -#define vec4i_to_vec4(x, z) \ -{ \ - __m128i xt; \ - *(vec4i*)&xt = (x); \ - _mm_storeu_ps((float*)&(z), _mm_cvtepi32_ps(xt)); \ +inline void vec4i_to_vec4(const vec4i& x, vec4& z) { + z = vec4::store_xmm(_mm_cvtepi32_ps(vec4i::load_xmm(x))); } diff --git a/src/MMPlusDec/MMPlusDec.cpp b/src/MMPlusDec/MMPlusDec.cpp index 22ef33d1..42e48102 100644 --- a/src/MMPlusDec/MMPlusDec.cpp +++ b/src/MMPlusDec/MMPlusDec.cpp @@ -8,8 +8,8 @@ #include #include #include "../KKdLib/default.hpp" +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/io/path.hpp" -#include "../KKdLib/io/stream.hpp" #include "../KKdLib/aes.hpp" #include "../KKdLib/str_utils.hpp" #include @@ -71,20 +71,19 @@ int32_t wmain(int32_t argc, wchar_t** argv) { aes256_init_ctx(&ctx, mmplus_key); { - std::vector files; - path_get_files(&files, indir.c_str()); + std::vector files = path_get_files(indir.c_str()); for (std::wstring& i : files) { std::wstring infile = indir + i; std::wstring outfile = outdir + i; - stream in_file; - stream out_file; + file_stream in_file; + file_stream out_file; in_file.open(infile.c_str(), L"rb"); out_file.open(outfile.c_str(), L"wb"); - if (in_file.io.stream && out_file.io.stream) { + if (in_file.check_not_null() && out_file.check_not_null()) { printf(encrypt ? "Encrypting %ls\n" : "Decrypting %ls\n", i.c_str()); aes256_ctx_set_iv(&ctx, mmplus_iv); @@ -124,8 +123,7 @@ int32_t wmain(int32_t argc, wchar_t** argv) { } } - std::vector directories; - path_get_directories_recursive(&directories, indir.c_str(), 0, 0); + std::vector directories = path_get_directories_recursive(indir.c_str(), 0, 0); for (std::wstring& i : directories) { std::wstring _indir = indir + i + L'\\'; std::wstring _outdir = outdir + i + L'\\'; @@ -134,19 +132,18 @@ int32_t wmain(int32_t argc, wchar_t** argv) { && !CreateDirectoryW(_outdir.c_str(), 0)) continue; - std::vector files; - path_get_files(&files, _indir.c_str()); + std::vector files = path_get_files(_indir.c_str()); for (std::wstring& j : files) { std::wstring infile = _indir + j; std::wstring outfile = _outdir + j; - stream in_file; - stream out_file; + file_stream in_file; + file_stream out_file; in_file.open(infile.c_str(), L"rb"); out_file.open(outfile.c_str(), L"wb"); - if (in_file.io.stream && out_file.io.stream) { + if (in_file.check_not_null() && out_file.check_not_null()) { printf(encrypt ? "Encrypting %ls\\%ls\n" : "Decrypting %ls\\%ls\n", i.c_str(), j.c_str()); aes256_ctx_set_iv(&ctx, mmplus_iv); diff --git a/src/ReDIVA/classes.cpp b/src/ReDIVA/classes.cpp index 7ad79169..255bfe24 100644 --- a/src/ReDIVA/classes.cpp +++ b/src/ReDIVA/classes.cpp @@ -13,10 +13,10 @@ void classes_process_init(classes_data* classes, const size_t classes_count, ren for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - lock_init(&c->data.lock); - if (lock_check_init(&c->data.lock) + c->data.lock = new lock; + if (c->data.lock->check_init() && c->flags & (CLASSES_INIT_AT_STARTUP | CLASSES_SHOW_AT_STARTUP) && c->init) { - lock_lock(&c->data.lock); + lock_lock(c->data.lock); if (c->init(&c->data, rctx)) c->data.flags = CLASS_INIT; else @@ -25,16 +25,16 @@ void classes_process_init(classes_data* classes, const size_t classes_count, ren if (~c->flags & CLASSES_SHOW_AT_STARTUP) enum_or(c->data.flags, CLASS_HIDDEN); - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } - if (lock_check_init(&c->data.lock) + if (c->data.lock->check_init() && c->flags & CLASSES_SHOW_AT_STARTUP) { - lock_lock(&c->data.lock); + lock_lock(c->data.lock); if (c->data.flags & CLASS_INIT && ((c->show && c->show(&c->data)) || !c->show)) { enum_and(c->data.flags, ~(CLASS_HIDE | CLASS_HIDDEN)); } - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } if (c->sub_classes && c->sub_classes_count) @@ -48,20 +48,20 @@ void classes_process_ctrl(classes_data* classes, const size_t classes_count) { for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - if (lock_check_init(&c->data.lock)) { + if (c->data.lock->check_init()) { if (c->data.flags & CLASS_HIDE) { - lock_lock(&c->data.lock); + lock_lock(c->data.lock); if (~c->data.flags & CLASS_HIDDEN && ((c->hide && c->hide(&c->data)) || !c->hide)) { enum_and(c->data.flags, ~CLASS_HIDE); enum_or(c->data.flags, CLASS_HIDDEN); enum_and(c->data.flags, ~CLASS_HAS_PARENT); } - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } if ((c->data.flags & CLASS_DISPOSE || (c->data.flags & CLASS_HIDDEN && c->flags & CLASSES_DISPOSE_AT_HIDE))) { - lock_lock(&c->data.lock); + lock_lock(c->data.lock); if (~c->data.flags & CLASS_HIDDEN && ((c->hide && c->hide(&c->data)) || !c->hide)) { enum_and(c->data.flags, ~CLASS_HIDE); enum_or(c->data.flags, CLASS_HIDDEN); @@ -73,14 +73,14 @@ void classes_process_ctrl(classes_data* classes, const size_t classes_count) { enum_or(c->data.flags, CLASS_DISPOSED); c->data.imgui_focus = false; } - lock_unlock(&c->data.lock); - lock_free(&c->data.lock); + lock_unlock(c->data.lock); + delete c->data.lock; } if (c->data.flags & CLASS_INIT && c->ctrl) { - lock_lock(&c->data.lock); + lock_lock(c->data.lock); c->ctrl(&c->data); - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } } @@ -91,11 +91,11 @@ void classes_process_ctrl(classes_data* classes, const size_t classes_count) { void classes_process_disp(classes_data* classes, size_t classes_count) { for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - if (lock_check_init(&c->data.lock) && c->disp) { - lock_lock(&c->data.lock); + if (c->data.lock->check_init() && c->disp) { + lock_lock(c->data.lock); if (c->data.flags & CLASS_INIT) c->disp(&c->data); - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } if (c->sub_classes && c->sub_classes_count) @@ -109,11 +109,11 @@ void classes_process_drop(classes_data* classes, size_t classes_count, size_t co for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - if (lock_check_init(&c->data.lock) && c->drop) { - lock_lock(&c->data.lock); + if (c->data.lock->check_init() && c->drop) { + lock_lock(c->data.lock); if (c->data.flags & CLASS_INIT) c->drop(&c->data, count, paths); - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } if (c->sub_classes && c->sub_classes_count) @@ -127,14 +127,14 @@ void classes_process_imgui(classes_data* classes, const size_t classes_count) { for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - if (lock_check_init(&c->data.lock)) { - lock_lock(&c->data.lock); + if (c->data.lock->check_init()) { + lock_lock(c->data.lock); if (~c->data.flags & CLASS_HIDDEN) { if (c->imgui) c->imgui(&c->data); input_locked |= c->data.imgui_focus; } - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } classes_process_imgui(c->sub_classes, c->sub_classes_count); @@ -147,14 +147,14 @@ void classes_process_input(classes_data* classes, const size_t classes_count) { for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - if (lock_check_init(&c->data.lock)) { - lock_lock(&c->data.lock); + if (c->data.lock->check_init()) { + lock_lock(c->data.lock); if (c->data.flags & CLASS_INIT) { if (c->input) c->input(&c->data); input_locked |= c->data.imgui_focus; } - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } classes_process_input(c->sub_classes, c->sub_classes_count); @@ -167,11 +167,11 @@ void classes_process_sound(classes_data* classes, const size_t classes_count) { for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - if (lock_check_init(&c->data.lock) && c->sound) { - lock_lock(&c->data.lock); + if (c->data.lock->check_init() && c->sound) { + lock_lock(c->data.lock); if (c->data.flags & CLASS_INIT) c->sound(&c->data); - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } classes_process_sound(c->sub_classes, c->sub_classes_count); @@ -184,8 +184,8 @@ void classes_process_dispose(classes_data* classes, const size_t classes_count) for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - if (lock_check_init(&c->data.lock)) { - lock_lock(&c->data.lock); + if (c->data.lock->check_init()) { + lock_lock(c->data.lock); if (~c->data.flags & CLASS_HIDDEN && ((c->hide && c->hide(&c->data)) || !c->hide)) { enum_and(c->data.flags, ~CLASS_HIDE); enum_or(c->data.flags, CLASS_HIDDEN); @@ -197,9 +197,10 @@ void classes_process_dispose(classes_data* classes, const size_t classes_count) enum_or(c->data.flags, CLASS_DISPOSED); c->data.imgui_focus = false; } - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } - lock_free(&c->data.lock); + delete c->data.lock; + c->data.lock = 0; classes_process_dispose(c->sub_classes, c->sub_classes_count); } diff --git a/src/ReDIVA/classes.hpp b/src/ReDIVA/classes.hpp index f96b1832..a42b9720 100644 --- a/src/ReDIVA/classes.hpp +++ b/src/ReDIVA/classes.hpp @@ -30,7 +30,7 @@ enum classes_enum { }; struct class_data { - lock lock; + lock* lock; class_flags flags; bool imgui_focus; void* data; diff --git a/src/ReDIVA/classes/data_view/auth_3d.cpp b/src/ReDIVA/classes/data_view/auth_3d.cpp index 63344647..c4a8d010 100644 --- a/src/ReDIVA/classes/data_view/auth_3d.cpp +++ b/src/ReDIVA/classes/data_view/auth_3d.cpp @@ -4,6 +4,7 @@ */ #include "auth_3d.hpp" +#include "../../../KKdLib/database/item_table.hpp" #include "../../../CRE/auth_3d.hpp" #include "../../imgui_helper.hpp" #include "../../input.hpp" @@ -66,8 +67,8 @@ void data_view_auth_3d_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 480.0f); - float_t h = min((float_t)height, 540.0f); + float_t w = min_def((float_t)width, 480.0f); + float_t h = min_def((float_t)height, 540.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); @@ -98,7 +99,7 @@ void data_view_auth_3d_imgui(class_data* data) { if (auth->id == -1) continue; - size_t str_len = min(sizeof(buf) - 1, auth->file_name.size()); + size_t str_len = min_def(sizeof(buf) - 1, auth->file_name.size()); memcpy(buf, auth->file_name.c_str(), str_len); buf[str_len] = 0; @@ -122,6 +123,16 @@ void data_view_auth_3d_imgui(class_data* data) { tree_node_flags = tree_node_base_flags; tree_node_flags |= ImGuiTreeNodeFlags_DefaultOpen; + if (auth->chara_id != -1) + ImGui::Text("Chara: %d", auth->chara_id); + else + ImGui::Text("Chara: None"); + + if (auth->src_chara != auth->dst_chara) + ImGui::Text("Chara Replace: %s/%s", + chara_index_get_auth_3d_name((chara_index)auth->src_chara), + chara_index_get_auth_3d_name((chara_index)auth->dst_chara)); + if (auth->ambient.size() > 0 && ImGui::TreeNodeEx("Ambient", tree_node_flags)) { for (auth_3d_ambient& l : auth->ambient) diff --git a/src/ReDIVA/classes/data_view/draw_task.cpp b/src/ReDIVA/classes/data_view/draw_task.cpp index b21e96a8..4537f717 100644 --- a/src/ReDIVA/classes/data_view/draw_task.cpp +++ b/src/ReDIVA/classes/data_view/draw_task.cpp @@ -55,11 +55,11 @@ static const char* draw_task_type_name[] = { "Object Translucent", }; -typedef std::pair> draw_task_sort; +typedef std::pair draw_task_sort; struct data_view_draw_task { render_context* rctx; - std::vector>> draw_tasks; + std::vector draw_tasks; data_view_draw_task(); virtual ~data_view_draw_task(); @@ -70,14 +70,13 @@ extern int32_t height; const char* data_view_draw_task_window_title = "Draw Task##Data Viewer"; -static int draw_task_sort_sort(void const* src1, void const* src2); static void data_view_draw_task_imgui_draw_object(draw_object* object); bool data_view_draw_task_init(class_data* data, render_context* rctx) { - data->data = new data_view_draw_task; - data_view_draw_task* data_view = (data_view_draw_task*)data->data; + data_view_draw_task* data_view = new data_view_draw_task; if (data_view) data_view->rctx = rctx; + data->data = data_view; return true; } @@ -86,8 +85,8 @@ void data_view_draw_task_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 480.0f); - float_t h = min((float_t)height, 542.0f); + float_t w = min_def((float_t)width, 480.0f); + float_t h = min_def((float_t)height, 542.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); @@ -113,7 +112,7 @@ void data_view_draw_task_imgui(class_data* data) { render_context* rctx = data_view->rctx; std::vector* draw_task_array = rctx->object_data.draw_task_array; - std::vector>>& draw_tasks_sort = data_view->draw_tasks; + std::vector& draw_tasks_sort = data_view->draw_tasks; ImGuiTreeNodeFlags tree_node_base_flags = 0; tree_node_base_flags |= ImGuiTreeNodeFlags_OpenOnDoubleClick; @@ -142,15 +141,11 @@ void data_view_draw_task_imgui(class_data* data) { for (draw_task*& j : draw_tasks) { draw_task_sort draw_task; draw_task.first = j; - draw_task.second.first = hash_murmurhash(&j, 8, 0, true); - draw_task.second.second = (uint32_t)(&j - draw_tasks.data()); + draw_task.second = hash_murmurhash(&j, 8, 0, true); draw_tasks_sort.push_back(draw_task); } - quicksort_custom(draw_tasks_sort.data(), draw_tasks_sort.size(), - sizeof(draw_task_sort), draw_task_sort_sort); - - ImGui::Text(" Hash; Index; Type"); + ImGui::Text(" Hash; Type"); for (draw_task_sort& j : draw_tasks_sort) { draw_task* task = j.first; @@ -158,8 +153,8 @@ void data_view_draw_task_imgui(class_data* data) { continue; ImGui::PushID(task); - if (!ImGui::TreeNodeEx("", tree_node_flags, "%08x; %8u; %s", - j.second.first, j.second.second, draw_task_type_name[task->type])) { + if (!ImGui::TreeNodeEx("", tree_node_flags, "%08x; %s", + j.second, draw_task_type_name[task->type])) { ImGui::PopID(); continue; } @@ -169,7 +164,7 @@ void data_view_draw_task_imgui(class_data* data) { vec3 rot; mat4_get_rotation(&task->mat, &rot); - vec3_mult_scalar(rot, RAD_TO_DEG_FLOAT, rot); + rot *= RAD_TO_DEG_FLOAT; vec3 scale; mat4_get_scale(&task->mat, &scale); @@ -220,8 +215,10 @@ void data_view_draw_task_imgui(class_data* data) { bool data_view_draw_task_dispose(class_data* data) { data_view_draw_task* data_view = (data_view_draw_task*)data->data; - delete data_view; - data->data = 0; + if (data_view) { + delete data_view; + data->data = 0; + } return true; } @@ -233,12 +230,6 @@ data_view_draw_task::~data_view_draw_task() { } -static int draw_task_sort_sort(void const* src1, void const* src2) { - float_t d1 = ((draw_task_sort*)src1)->first->depth; - float_t d2 = ((draw_task_sort*)src2)->first->depth; - return d1 > d2 ? -1 : (d1 < d2 ? 1 : 0); -} - static void data_view_draw_task_imgui_draw_object(draw_object* object) { ImGui::Text("Mesh Name: %s", object->mesh->name); ImGui::Text("Sub Mesh Index: %lld", object->sub_mesh - object->mesh->submesh_array); diff --git a/src/ReDIVA/classes/data_view/glitter.cpp b/src/ReDIVA/classes/data_view/glitter.cpp index 156aa067..2b08d90b 100644 --- a/src/ReDIVA/classes/data_view/glitter.cpp +++ b/src/ReDIVA/classes/data_view/glitter.cpp @@ -8,21 +8,13 @@ #include "../../../CRE/render_context.hpp" #include "../../imgui_helper.hpp" -struct data_view_glitter { - render_context* rctx; -}; - extern int32_t width; extern int32_t height; const char* data_view_glitter_window_title = "Glitter##Data Viewer"; bool data_view_glitter_init(class_data* data, render_context* rctx) { - data->data = force_malloc(sizeof(data_view_glitter)); - data_view_glitter* data_view = (data_view_glitter*)data->data; - if (data_view) { - data_view->rctx = rctx; - } + data->data = rctx; return true; } @@ -31,8 +23,8 @@ void data_view_glitter_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 600.0f); - float_t h = min((float_t)height, 480.0f); + float_t w = min_def((float_t)width, 600.0f); + float_t h = min_def((float_t)height, 480.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); @@ -50,14 +42,12 @@ void data_view_glitter_imgui(class_data* data) { return; } - data_view_glitter* data_view = (data_view_glitter*)data->data; - if (!data_view) { + render_context* rctx = (render_context*)data->data; + if (!rctx) { ImGui::End(); return; } - render_context* rctx = data_view->rctx; - ImGuiTreeNodeFlags tree_node_base_flags = 0; tree_node_base_flags |= ImGuiTreeNodeFlags_OpenOnDoubleClick; tree_node_base_flags |= ImGuiTreeNodeFlags_OpenOnArrow; @@ -221,9 +211,6 @@ void data_view_glitter_imgui(class_data* data) { } bool data_view_glitter_dispose(class_data* data) { - data_view_glitter* data_view = (data_view_glitter*)data->data; - if (data_view) { - } - free(data->data); + data->data = 0; return true; } diff --git a/src/ReDIVA/classes/data_view/object.cpp b/src/ReDIVA/classes/data_view/object.cpp index 7a529ac7..68672936 100644 --- a/src/ReDIVA/classes/data_view/object.cpp +++ b/src/ReDIVA/classes/data_view/object.cpp @@ -7,21 +7,13 @@ #include "../../../CRE/render_context.hpp" #include "../../imgui_helper.hpp" -struct data_view_object { - render_context* rctx; -}; - extern int32_t width; extern int32_t height; const char* data_view_object_window_title = "Object##Data Viewer"; bool data_view_object_init(class_data* data, render_context* rctx) { - data->data = force_malloc(sizeof(data_view_object)); - data_view_object* data_view = (data_view_object*)data->data; - if (data_view) { - data_view->rctx = rctx; - } + data->data = rctx; return true; } @@ -30,8 +22,8 @@ void data_view_object_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 420.0f); - float_t h = min((float_t)height, 480.0f); + float_t w = min_def((float_t)width, 420.0f); + float_t h = min_def((float_t)height, 480.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); @@ -49,14 +41,12 @@ void data_view_object_imgui(class_data* data) { return; } - data_view_object* data_view = (data_view_object*)data->data; - if (!data_view) { + render_context* rctx = (render_context*)data->data; + if (!rctx) { ImGui::End(); return; } - render_context* rctx = data_view->rctx; - size_t count = object_storage_get_obj_set_count(); for (size_t i = 0; i < count; i++) { obj_set_handler* handler = object_storage_get_obj_set_handler_by_index(i); @@ -78,9 +68,6 @@ void data_view_object_imgui(class_data* data) { } bool data_view_object_dispose(class_data* data) { - data_view_object* data_view = (data_view_object*)data->data; - if (data_view) { - } - free(data->data); + data->data = 0; return true; } diff --git a/src/ReDIVA/classes/data_view/texture.cpp b/src/ReDIVA/classes/data_view/texture.cpp index f59aacf4..b27f0c79 100644 --- a/src/ReDIVA/classes/data_view/texture.cpp +++ b/src/ReDIVA/classes/data_view/texture.cpp @@ -7,21 +7,13 @@ #include "../../../CRE/render_context.hpp" #include "../../imgui_helper.hpp" -struct data_view_texture { - render_context* rctx; -}; - extern int32_t width; extern int32_t height; const char* data_view_texture_window_title = "Texture##Data Viewer"; bool data_view_texture_init(class_data* data, render_context* rctx) { - data->data = force_malloc(sizeof(data_view_texture)); - data_view_texture* data_view = (data_view_texture*)data->data; - if (data_view) { - data_view->rctx = rctx; - } + data->data = rctx; return true; } @@ -30,8 +22,8 @@ void data_view_texture_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 580.0f); - float_t h = min((float_t)height, 480.0f); + float_t w = min_def((float_t)width, 580.0f); + float_t h = min_def((float_t)height, 480.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); @@ -49,14 +41,12 @@ void data_view_texture_imgui(class_data* data) { return; } - data_view_texture* data_view = (data_view_texture*)data->data; - if (!data_view) { + render_context* rctx = (render_context*)data->data; + if (!rctx) { ImGui::End(); return; } - render_context* rctx = data_view->rctx; - size_t count = texture_storage_get_texture_count(); for (size_t i = 0; i < count; i++) { texture* tex = texture_storage_get_texture_by_index(i); @@ -76,9 +66,6 @@ void data_view_texture_imgui(class_data* data) { } bool data_view_texture_dispose(class_data* data) { - data_view_texture* data_view = (data_view_texture*)data->data; - if (data_view) { - } - free(data->data); + data->data = 0; return true; } diff --git a/src/ReDIVA/classes/glitter_editor.cpp b/src/ReDIVA/classes/glitter_editor.cpp index 3634f617..bc018996 100644 --- a/src/ReDIVA/classes/glitter_editor.cpp +++ b/src/ReDIVA/classes/glitter_editor.cpp @@ -7,8 +7,8 @@ #if defined(ReDIVA_DEV) #include "glitter_editor.hpp" +#include "../../KKdLib/io/file_stream.hpp" #include "../../KKdLib/io/path.hpp" -#include "../../KKdLib/io/stream.hpp" #include "../../KKdLib/dds.hpp" #include "../../KKdLib/interpolation.hpp" #include "../../KKdLib/str_utils.hpp" @@ -82,6 +82,11 @@ struct GlitterEditor { bool add_curve; bool del_curve; bool key_edit; + + CurveEditor(); + + void ResetCurves(); + void ResetState(Glitter::CurveType type = (Glitter::CurveType)-1); }; struct GL { @@ -148,8 +153,7 @@ struct GlitterEditor { Glitter::Scene* scene; uint64_t hash; Glitter::SceneCounter scene_counter; - char file[MAX_PATH * 2]; - GLuint vao; + std::string file; glitter_editor_selected_enum selected_type; int32_t selected_resource; @@ -159,6 +163,13 @@ struct GlitterEditor { CurveEditor curve_editor; GlitterEditor::GL* gl_data; + + GlitterEditor(); + virtual ~GlitterEditor(); + + void Reset(); + + static void ResetDisp(); }; static const float_t curve_base_values[] = { @@ -219,8 +230,6 @@ static void glitter_editor_select_particle(GlitterEditor* glt_edt); static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data); static void glitter_editor_reload(GlitterEditor* glt_edt); -static void glitter_editor_reset(GlitterEditor* glt_edt); -static void glitter_editor_reset_draw(); static void glitter_editor_save(GlitterEditor* glt_edt); static void glitter_editor_open_window(GlitterEditor* glt_edt); static void glitter_editor_save_window(GlitterEditor* glt_edt); @@ -262,10 +271,8 @@ static void glitter_editor_file_load_error_list_popup(GlitterEditor* glt_edt, cl static void glitter_editor_file_save_popup(GlitterEditor* glt_edt, class_data* data, ImGuiIO& io, ImGuiStyle& style, ImFont* font, const float_t title_bar_size); -static void glitter_editor_curve_editor(GlitterEditor* glt_edt); static void glitter_editor_curve_editor_curve_set(GlitterEditor* glt_edt, Glitter::Curve* curve, Glitter::CurveType type); -static void glitter_editor_curve_editor_curves_reset(GlitterEditor* glt_edt); static Glitter::Curve::Key* glitter_editor_curve_editor_get_closest_key( GlitterEditor* glt_edt, Glitter::Curve* curve); static Glitter::Curve::Key* glitter_editor_curve_editor_get_selected_key( @@ -275,16 +282,13 @@ static float_t glitter_editor_curve_editor_get_value(GlitterEditor* glt_edt, static void glitter_editor_curve_editor_key_manager(GlitterEditor* glt_edt, std::vector* keys, bool* add_key, bool* del_key); static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, class_data* data); -static void glitter_editor_curve_editor_reset_state(GlitterEditor* glt_edt, - Glitter::CurveType type); static void glitter_editor_curve_editor_selector(GlitterEditor* glt_edt, class_data* data); +static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt); static bool glitter_editor_hash_input(GlitterEditor* glt_edt, const char* label, uint64_t* hash); bool glitter_editor_init(class_data* data, render_context* rctx) { - data->data = force_malloc_s(GlitterEditor, 1); - LARGE_INTEGER time; QueryPerformanceCounter(&time); Glitter::glt_particle_manager->random.value = (uint32_t)(time.LowPart * hash_fnv1a64m_empty); @@ -293,20 +297,17 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { QueryPerformanceCounter(&time); Glitter::glt_particle_manager->counter = (uint32_t)(time.LowPart * hash_murmurhash_empty); - GlitterEditor* glt_edt = (GlitterEditor*)data->data; + GlitterEditor* glt_edt = new GlitterEditor; if (glt_edt) { - glt_edt->test = false; - glt_edt->draw_flags = (glitter_editor_draw_flags)0; Glitter::glt_particle_manager->emission = 1.0f; Glitter::glt_particle_manager->draw_all = true; Glitter::glt_particle_manager->draw_all_mesh = true; - glGenVertexArrays(1, &glt_edt->vao); draw_grid_3d = true; - glitter_editor_reset(glt_edt); - GlitterEditor::GL::Load(glt_edt); + glt_edt->Reset(); dtm_stg_load(0); } + data->data = glt_edt; input_reset = true; @@ -344,7 +345,7 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { uint64_t* hashes = force_malloc_s(uint64_t, count); for (size_t i = 0; i < count; i++) { size_t len = utf8_length(lines[i]); - hashes[i] = hash_murmurhash(lines[i], min(len, 0x7F)); + hashes[i] = hash_murmurhash(lines[i], min_def(len, 0x7F)); } for (ssize_t i = 0; i < c; i++) { @@ -382,12 +383,12 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { Glitter::EffectGroup_dispose(fr->effect_group); } - free(file_x); + free_def(file_x); } - free(lines); - free(hashes); + free_def(lines); + free_def(hashes); } - free(data); + free_def(data); } for (string* i = files_x.begin; i != files_x.end; i++) string_free(i); @@ -441,7 +442,7 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { Glitter::EffectGroup_dispose(fr->effect_group); } - free(file_x); + free_def(file_x); } for (string* i = files_x.begin; i != files_x.end; i++) string_free(i); @@ -492,7 +493,7 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { uint64_t* hashes = force_malloc_s(uint64_t, count); for (size_t i = 0; i < count; i++) { size_t len = utf8_length(lines[i]); - hashes[i] = hash_murmurhash(lines[i], min(len, 0x7F)); + hashes[i] = hash_murmurhash(lines[i], min_def(len, 0x7F)); } ssize_t c = vector_old_length(files_f2); @@ -525,7 +526,7 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { break; size_t len = utf8_length(lines[j]); - memcpy(e->name, lines[j], min(len, 0x7F)); + memcpy(e->name, lines[j], min_def(len, 0x7F)); } glt_edt->effect_group = fr->effect_group; @@ -533,14 +534,14 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { //glitter_editor_save_file(path_ft, file_ft); Glitter::EffectGroup_dispose(fr->effect_group); } - free(file_f2); - free(file_ft); + free_def(file_f2); + free_def(file_ft); } glitter_file_reader_dispose(fr); - free(buf); - free(lines); - free(hashes); + free_def(buf); + free_def(lines); + free_def(hashes); } for (string* i = files_f2.begin; i != files_f2.end; i++) string_free(i); @@ -549,7 +550,7 @@ bool glitter_editor_init(class_data* data, render_context* rctx) { for (string* i = files_ft.begin; i != files_ft.end; i++) string_free(i); vector_old_string_free(&files_ft); - free(data); + free_def(data); glt_edt->effect_group = 0;*/ return true; } @@ -567,7 +568,7 @@ void glitter_editor_ctrl(class_data* data) { if (glt_edt->effect_group_add) { Glitter::glt_particle_manager->UnloadEffectGroup(glt_edt->hash); - glitter_editor_reset_draw(); + GlitterEditor::ResetDisp(); LARGE_INTEGER time; QueryPerformanceCounter(&time); @@ -921,8 +922,8 @@ void glitter_editor_ctrl(class_data* data) { glt_edt->particle_flags = (glitter_editor_flags)0; if (glt_edt->load || glt_edt->save) { - char* file = str_utils_get_without_extension(glt_edt->file); - char* path = str_utils_split_right_get_left_include(glt_edt->file, '\\'); + char* file = str_utils_get_without_extension(glt_edt->file.c_str()); + char* path = str_utils_split_right_get_left_include(glt_edt->file.c_str(), '\\'); if (glt_edt->load) glitter_editor_load_file(glt_edt, path, file); @@ -931,8 +932,8 @@ void glitter_editor_ctrl(class_data* data) { glt_edt->save = false; glt_edt->save_compress = false; - free(path); - free(file); + free_def(path); + free_def(file); return; } else if (eg && glt_edt->load_data) { @@ -1050,12 +1051,12 @@ void glitter_editor_ctrl(class_data* data) { Glitter::glt_particle_manager->FreeSceneEffect(glt_edt->scene_counter); Glitter::glt_particle_manager->UnloadEffectGroup(glt_edt->hash); - glitter_editor_reset_draw(); + GlitterEditor::ResetDisp(); glt_edt->effect_group = 0; glt_edt->scene = 0; glt_edt->hash = 0; glt_edt->scene_counter = 0; - memset(glt_edt->file, 0, sizeof(glt_edt->file)); + glt_edt->file.clear(); glt_edt->close = false; return; } @@ -1116,7 +1117,7 @@ void glitter_editor_ctrl(class_data* data) { rob_frame = glt_edt->frame_counter; if (!glt_edt->effect_group) { - glitter_editor_reset_draw(); + GlitterEditor::ResetDisp(); return; } @@ -1136,9 +1137,7 @@ void glitter_editor_drop(class_data* data, size_t count, char** paths) { if (!glt_edt) return; - size_t c = min(utf8_length(paths[0]), sizeof(glt_edt->file) - 1); - memcpy(glt_edt->file, paths[0], c); - glt_edt->file[c] = 0; + glt_edt->file.assign(paths[0]); glt_edt->load_popup = true; } @@ -1194,54 +1193,99 @@ bool glitter_editor_dispose(class_data* data) { GlitterEditor* glt_edt = (GlitterEditor*)data->data; if (glt_edt) { dtm_stg_unload(); - GlitterEditor::GL::Free(glt_edt); Glitter::glt_particle_manager->FreeSceneEffect(glt_edt->scene_counter); Glitter::glt_particle_manager->UnloadEffectGroup(glt_edt->hash); - - glt_edt->test = false; - glt_edt->create_popup = false; - glt_edt->load = false; - glt_edt->load_data = false; - glt_edt->load_data_wait = false; - glt_edt->load_popup = false; - glt_edt->load_data_popup = false; - glt_edt->load_error_list_popup = false; - glt_edt->save = false; - glt_edt->save_popup = false; - glt_edt->save_compress = false; - glt_edt->close = false; - glt_edt->input_play = false; - glt_edt->input_reload = false; - glt_edt->input_pause = true; - glt_edt->input_reset = false; - glt_edt->effect_group_add = false; - glt_edt->draw_flags = (glitter_editor_draw_flags)0; - glt_edt->resource_flags = (glitter_editor_flags)0; - glt_edt->effect_flags = (glitter_editor_flags)0; - glt_edt->emitter_flags = (glitter_editor_flags)0; - glt_edt->particle_flags = (glitter_editor_flags)0; - glt_edt->frame_counter = 0.0f; - glt_edt->old_frame_counter = 0.0f; - glt_edt->start_frame = 0; - glt_edt->end_frame = 0; - glt_edt->random.value = 0; - glt_edt->random.step = 1; - glt_edt->counter = 0; - glt_edt->effect_group = 0; - glt_edt->scene = 0; - glt_edt->hash = 0; - glt_edt->scene_counter = 0; - memset(glt_edt->file, 0, sizeof(glt_edt->file)); - glDeleteVertexArrays(1, &glt_edt->vao); + delete glt_edt; } draw_grid_3d = false; - free(data->data); + data->data = 0; data->flags = (class_flags)(CLASS_HIDDEN | CLASS_DISPOSED); data->imgui_focus = false; return true; } +GlitterEditor::CurveEditor::CurveEditor() : type(), animation(), list(), key(), frame_width(), +zoom_time(), prev_zoom_time(), zoom_value(), key_radius_in(), key_radius_out(), height_offset(), frame(), +draw_list(), io(), timeline_pos(), range(), add_key(), del_key(), add_curve(), del_curve(), key_edit() { + +} + +void GlitterEditor::CurveEditor::ResetCurves() { + memset(&list, 0, sizeof(list)); + animation = 0; + key = {}; +} + +void GlitterEditor::CurveEditor::ResetState(Glitter::CurveType type) { + if (this->type != type) + this->type = type; + + frame_width = 16; + zoom_time = 1.0f; + prev_zoom_time = 1.0f; + zoom_value = 1.0f; + key_radius_in = 6.0f; + key_radius_out = 8.0f; + height_offset = 20.0f; + frame = 0; + + timeline_pos = -curve_editor_timeline_base_pos; + + switch (type) { + case Glitter::CURVE_TRANSLATION_X: + case Glitter::CURVE_TRANSLATION_Y: + case Glitter::CURVE_TRANSLATION_Z: + range = 25.0f; + break; + case Glitter::CURVE_ROTATION_X: + case Glitter::CURVE_ROTATION_Y: + case Glitter::CURVE_ROTATION_Z: + range = 360.0f; + break; + case Glitter::CURVE_SCALE_X: + case Glitter::CURVE_SCALE_Y: + case Glitter::CURVE_SCALE_Z: + case Glitter::CURVE_SCALE_ALL: + range = 5.0f; + break; + case Glitter::CURVE_COLOR_R: + case Glitter::CURVE_COLOR_G: + case Glitter::CURVE_COLOR_B: + case Glitter::CURVE_COLOR_A: + case Glitter::CURVE_COLOR_RGB_SCALE: + case Glitter::CURVE_COLOR_R_2ND: + case Glitter::CURVE_COLOR_G_2ND: + case Glitter::CURVE_COLOR_B_2ND: + case Glitter::CURVE_COLOR_A_2ND: + case Glitter::CURVE_COLOR_RGB_SCALE_2ND: + range = 255.0f; + break; + case Glitter::CURVE_EMISSION_INTERVAL: + range = 20.0f; + break; + case Glitter::CURVE_PARTICLES_PER_EMISSION: + range = 50.0f; + break; + case Glitter::CURVE_U_SCROLL: + case Glitter::CURVE_V_SCROLL: + case Glitter::CURVE_U_SCROLL_ALPHA: + case Glitter::CURVE_V_SCROLL_ALPHA: + case Glitter::CURVE_U_SCROLL_2ND: + case Glitter::CURVE_V_SCROLL_2ND: + case Glitter::CURVE_U_SCROLL_ALPHA_2ND: + case Glitter::CURVE_V_SCROLL_ALPHA_2ND: + range = 1.0f; + break; + default: + range = 1.0f; + break; + } + + add_key = false; + del_key = false; +} + GlitterEditor::GL::Wireframe::Wireframe() { } @@ -1407,7 +1451,6 @@ void GlitterEditor::GL::Wireframe::Disp(GlitterEditor* glt_edt, gl_state_disable_cull_face(); gl_state_set_polygon_mode(GL_FRONT_AND_BACK, GL_LINE); - gl_state_bind_vertex_array(glt_edt->vao); shader.use(); shader.set("color", 1.0f, 1.0f, 0.0f, 1.0f); for (Glitter::F2RenderGroup*& i : eff->render_scene.groups) { @@ -1426,33 +1469,17 @@ void GlitterEditor::GL::Wireframe::Disp(GlitterEditor* glt_edt, case Glitter::PARTICLE_QUAD: { static const GLsizei buffer_size = sizeof(Glitter::Buffer); - gl_state_bind_array_buffer(rg->vbo); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, - (void*)offsetof(Glitter::Buffer, position)); // Pos - gl_state_bind_array_buffer(0); - - gl_state_bind_element_array_buffer(rg->ebo); + gl_state_bind_vertex_array(rg->vao); glDrawElements(GL_TRIANGLES, (GLsizei)(6 * rg->disp), GL_UNSIGNED_INT, 0); - gl_state_bind_element_array_buffer(0); - - glDisableVertexAttribArray(0); } break; case Glitter::PARTICLE_LINE: case Glitter::PARTICLE_LOCUS: { static const GLsizei buffer_size = sizeof(Glitter::Buffer); - gl_state_bind_array_buffer(rg->vbo); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, - (void*)offsetof(Glitter::Buffer, position)); // Pos - gl_state_bind_array_buffer(0); - + gl_state_bind_vertex_array(rg->vao); const GLenum mode = rg->type == Glitter::PARTICLE_LINE ? GL_LINE_STRIP : GL_TRIANGLE_STRIP; for (std::pair& i : rg->draw_list) glDrawArrays(mode, i.first, i.second); - - glDisableVertexAttribArray(0); } break; } } @@ -1469,7 +1496,6 @@ void GlitterEditor::GL::Wireframe::Disp(GlitterEditor* glt_edt, gl_state_disable_cull_face(); gl_state_set_polygon_mode(GL_FRONT_AND_BACK, GL_LINE); - gl_state_bind_vertex_array(glt_edt->vao); shader.use(); shader.set("color", 1.0f, 1.0f, 0.0f, 1.0f); for (Glitter::XRenderGroup*& i : eff->render_scene.groups) { @@ -1488,33 +1514,17 @@ void GlitterEditor::GL::Wireframe::Disp(GlitterEditor* glt_edt, case Glitter::PARTICLE_QUAD: { static const GLsizei buffer_size = sizeof(Glitter::Buffer); - gl_state_bind_array_buffer(rg->vbo); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, - (void*)offsetof(Glitter::Buffer, position)); // Pos - gl_state_bind_array_buffer(0); - - gl_state_bind_element_array_buffer(rg->ebo); + gl_state_bind_vertex_array(rg->vao); glDrawElements(GL_TRIANGLES, (GLsizei)(6 * rg->disp), GL_UNSIGNED_INT, 0); - gl_state_bind_element_array_buffer(0); - - glDisableVertexAttribArray(0); } break; case Glitter::PARTICLE_LINE: case Glitter::PARTICLE_LOCUS: { static const GLsizei buffer_size = sizeof(Glitter::Buffer); - gl_state_bind_array_buffer(rg->vbo); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, - (void*)offsetof(Glitter::Buffer, position)); // Pos - gl_state_bind_array_buffer(0); - + gl_state_bind_vertex_array(rg->vao); const GLenum mode = rg->type == Glitter::PARTICLE_LINE ? GL_LINE_STRIP : GL_TRIANGLE_STRIP; for (std::pair& i : rg->draw_list) glDrawArrays(mode, i.first, i.second); - - glDisableVertexAttribArray(0); } break; case Glitter::PARTICLE_MESH: GlitterEditor::GL::Wireframe::DispMesh(glt_edt, rg); @@ -1530,7 +1540,7 @@ void GlitterEditor::GL::Wireframe::DispMesh(GlitterEditor* glt_edt, Glitter::XRenderGroup* rg) { Glitter::RenderElement* elem = rg->elements; for (size_t i = rg->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min(i, j_max); + j_max = min_def(i, j_max); for (size_t j = j_max; j > 0; elem++) { if (!elem->alive) continue; @@ -1691,6 +1701,37 @@ void GlitterEditor::GL::Free(GlitterEditor* glt_edt) { } } +GlitterEditor::GlitterEditor() : test(), create_popup(), load(), load_wait(), load_data(), +load_data_wait(), load_popup(), load_data_popup(), load_error_list_popup(), save(), save_popup(), +save_compress(), close(), input_play(), input_reload(), input_pause(), input_pause_temp(), input_reset(), +effect_group_add(), draw_flags(), resource_flags(), effect_flags(), emitter_flags(), particle_flags(), +load_glt_type(), save_glt_type(), load_data_type(), frame_counter(), old_frame_counter(), +start_frame(), end_frame(), counter(), effect_group(), scene(), hash(), selected_type(), +selected_resource(), selected_effect(), selected_emitter(), selected_particle(), gl_data() { + GlitterEditor::GL::Load(this); +} + +GlitterEditor::~GlitterEditor() { + GlitterEditor::GL::Free(this); +} + +void GlitterEditor::Reset() { + selected_type = GLITTER_EDITOR_SELECTED_NONE; + selected_resource = -1; + selected_effect = 0; + selected_emitter = 0; + selected_particle = 0; + curve_editor.ResetState(); + curve_editor.ResetCurves(); +} + +void GlitterEditor::ResetDisp() { + Glitter::glt_particle_manager->selected_scene = 0; + Glitter::glt_particle_manager->selected_effect = 0; + Glitter::glt_particle_manager->selected_emitter = 0; + Glitter::glt_particle_manager->selected_particle = 0; +} + static void glitter_editor_select_particle(GlitterEditor* glt_edt) { Glitter::glt_particle_manager->selected_scene = 0; Glitter::glt_particle_manager->selected_effect = 0; @@ -1875,12 +1916,12 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { bool selected = glt_edt->selected_effect || glt_edt->selected_emitter || glt_edt->selected_particle ? true : false; - win_x = min((float_t)width / 4.0f, 400.0f); + win_x = min_def((float_t)width / 4.0f, 400.0f); x = 0; y = main_menu_bar_size.y; - w = min((float_t)width / 4.0f, 400.0f); - h = (float_t)height - y - min((float_t)height / 3.0f, 320.0f); + w = min_def((float_t)width / 4.0f, 400.0f); + h = (float_t)height - y - min_def((float_t)height / 3.0f, 320.0f); window_flags = 0; window_flags |= ImGuiWindowFlags_NoTitleBar; @@ -1922,12 +1963,12 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { } ImGui::PopID(); - win_x = min((float_t)width / 4.0f, 400.0f); + win_x = min_def((float_t)width / 4.0f, 400.0f); x = (float_t)width - win_x; y = main_menu_bar_size.y; w = win_x; - h = (float_t)height - y - min((float_t)height / 3.0f, 320.0f); + h = (float_t)height - y - min_def((float_t)height / 3.0f, 320.0f); window_flags = 0; window_flags |= ImGuiWindowFlags_NoResize; @@ -1948,8 +1989,8 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { } ImGui::PopID(); - win_x = min((float_t)width / 4.0f, 400.0f); - win_y = min((float_t)height / 3.0f, 320.0f); + win_x = min_def((float_t)width / 4.0f, 400.0f); + win_y = min_def((float_t)height / 3.0f, 320.0f); x = 0; y = (float_t)height - win_y; @@ -1975,8 +2016,8 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { } ImGui::PopID(); - win_x = min((float_t)width / 4.0f, 400.0f); - win_y = min((float_t)height / 3.0f, 320.0f); + win_x = min_def((float_t)width / 4.0f, 400.0f); + win_y = min_def((float_t)height / 3.0f, 320.0f); x = (float_t)width - win_x; y = (float_t)height - win_y; @@ -2002,8 +2043,8 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { } ImGui::PopID(); - win_x = min((float_t)width / 4.0f, 400.0f); - win_y = min((float_t)height / 3.0f, 320.0f); + win_x = min_def((float_t)width / 4.0f, 400.0f); + win_y = min_def((float_t)height / 3.0f, 320.0f); x = win_x; y = (float_t)height - win_y; @@ -2023,7 +2064,7 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { ImGui::PushID("Glitter Editor Curve Editor Window"); if (ImGui::Begin("Curve Editor", 0, window_flags)) { if (glt_edt->effect_group && selected) - glitter_editor_curve_editor(glt_edt); + glitter_editor_curve_editor_windows(glt_edt); data->imgui_focus |= ImGui::IsWindowFocused(); ImGui::End(); } @@ -2074,24 +2115,6 @@ static void glitter_editor_reload(GlitterEditor* glt_edt) { } } -static void glitter_editor_reset(GlitterEditor* glt_edt) { - glt_edt->selected_type = GLITTER_EDITOR_SELECTED_NONE; - glt_edt->selected_resource = -1; - glt_edt->selected_effect = 0; - glt_edt->selected_emitter = 0; - glt_edt->selected_particle = 0; - glitter_editor_curve_editor_reset_state(glt_edt, (Glitter::CurveType)-1); - glitter_editor_curve_editor_curves_reset(glt_edt); - glitter_editor_reset_draw(); -} - -static void glitter_editor_reset_draw() { - Glitter::glt_particle_manager->selected_scene = 0; - Glitter::glt_particle_manager->selected_effect = 0; - Glitter::glt_particle_manager->selected_emitter = 0; - Glitter::glt_particle_manager->selected_particle = 0; -} - static void glitter_editor_save(GlitterEditor* glt_edt) { glt_edt->save_popup = glt_edt->effect_group && glt_edt->effect_group->type == Glitter::X ? false : true; @@ -2113,8 +2136,8 @@ static void glitter_editor_open_window(GlitterEditor* glt_edt) { ofn.lpstrTitle = L"File to Open"; if (GetOpenFileNameW(&ofn)) { char* file_temp = utf16_to_utf8(file); - memcpy(glt_edt->file, file_temp, utf8_length(file_temp) + 1); - free(file_temp); + glt_edt->file.assign(file_temp); + free_def(file_temp); glt_edt->load_popup = true; } CoUninitialize(); @@ -2155,8 +2178,8 @@ static void glitter_editor_save_as_window(GlitterEditor* glt_edt) { ofn.Flags = OFN_NONETWORKBUTTON; if (GetSaveFileNameW(&ofn)) { char* file_temp = utf16_to_utf8(file); - memcpy(glt_edt->file, file_temp, utf8_length(file_temp) + 1); - free(file_temp); + glt_edt->file.assign(file_temp); + free_def(file_temp); glitter_editor_save(glt_edt); } else @@ -2169,7 +2192,7 @@ static void glitter_editor_load_file(GlitterEditor* glt_edt, const char* path, c Glitter::glt_particle_manager->FreeSceneEffect(glt_edt->scene_counter); Glitter::glt_particle_manager->UnloadEffectGroup(glt_edt->hash); - glitter_editor_reset_draw(); + GlitterEditor::ResetDisp(); glt_edt->effect_group = 0; glt_edt->scene = 0; @@ -2230,7 +2253,7 @@ static void glitter_editor_load_file(GlitterEditor* glt_edt, const char* path, c } } - glitter_editor_reset_draw(); + GlitterEditor::ResetDisp(); Glitter::glt_particle_manager->GetSceneStartEndFrame( &glt_edt->start_frame, &glt_edt->end_frame, glt_edt->scene_counter); @@ -2247,11 +2270,12 @@ static void glitter_editor_load_file(GlitterEditor* glt_edt, const char* path, c glt_edt->load_data_wait = false; } - glitter_editor_reset(glt_edt); + glt_edt->Reset(); } static void glitter_editor_save_file(GlitterEditor* glt_edt, const char* path, const char* file) { - Glitter::FileWriter::Write(glt_edt->save_glt_type, glt_edt->effect_group, path, file, glt_edt->save_compress); + Glitter::FileWriter::Write(glt_edt->save_glt_type, + glt_edt->effect_group, path, file, glt_edt->save_compress); } static bool glitter_editor_list_open_window(Glitter::EffectGroup* eg) { @@ -2271,7 +2295,7 @@ static bool glitter_editor_list_open_window(Glitter::EffectGroup* eg) { ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = L"File to Open"; if (GetOpenFileNameW(&ofn)) { - stream s; + file_stream s; s.open(file, L"rb"); size_t length = s.length; uint8_t* data = force_malloc_s(uint8_t, length); @@ -2281,7 +2305,7 @@ static bool glitter_editor_list_open_window(Glitter::EffectGroup* eg) { char* buf; char** lines; size_t count; - if (str_utils_text_file_parse(data, length, &buf, &lines, &count)) { + if (str_utils_text_file_parse(data, length, buf, lines, count)) { for (size_t i = 0; i < count; i++) { char* t = strstr(lines[i], "#(?)"); if (t) @@ -2294,12 +2318,12 @@ static bool glitter_editor_list_open_window(Glitter::EffectGroup* eg) { if (eg->type != Glitter::FT) for (size_t i = 0; i < count; i++) { size_t len = utf8_length(lines[i]); - hashes[i] = hash_murmurhash(lines[i], min(len, 0x7F)); + hashes[i] = hash_murmurhash(lines[i], min_def(len, 0x7F)); } else for (size_t i = 0; i < count; i++) { size_t len = utf8_length(lines[i]); - hashes[i] = hash_fnv1a64m(lines[i], min(len, 0x7F)); + hashes[i] = hash_fnv1a64m(lines[i], min_def(len, 0x7F)); } ret = true; @@ -2325,11 +2349,11 @@ static bool glitter_editor_list_open_window(Glitter::EffectGroup* eg) { e->name = lines[j]; } - free(buf); - free(lines); - free(hashes); + free_def(buf); + free_def(lines); + free_def(hashes); } - free(data); + free_def(data); } CoUninitialize(); return ret; @@ -2384,8 +2408,8 @@ static bool glitter_editor_resource_import(GlitterEditor* glt_edt) { do for (uint32_t i = 0; i < tex->mipmaps_count; i++) { txp_mipmap tex_mip; - tex_mip.width = max(d.width >> i, 1); - tex_mip.height = max(d.height >> i, 1); + tex_mip.width = max_def(d.width >> i, 1); + tex_mip.height = max_def(d.height >> i, 1); tex_mip.format = d.format; uint32_t size = txp::get_size(tex_mip.format, tex_mip.width, tex_mip.height); @@ -2405,8 +2429,10 @@ static bool glitter_editor_resource_import(GlitterEditor* glt_edt) { ret = true; } DDSEnd: - free(f); - free(p); + if (f) + free(f); + if (p) + free(p); } CoUninitialize(); return ret; @@ -2451,7 +2477,7 @@ static bool glitter_editor_resource_export(GlitterEditor* glt_edt) { uint32_t index = 0; do for (uint32_t i = 0; i < tex.mipmaps_count; i++) { - uint32_t size = txp::get_size(format, max(width >> i, 1), max(height >> i, 1)); + uint32_t size = txp::get_size(format, max_def(width >> i, 1), max_def(height >> i, 1)); void* data = force_malloc(size); memcpy(data, tex.mipmaps[index].data.data(), size); d.data.push_back(data); @@ -2460,7 +2486,8 @@ static bool glitter_editor_resource_export(GlitterEditor* glt_edt) { while (index / tex.mipmaps_count < tex.array_size); d.write(p); ret = true; - free(p); + if (p) + free(p); } CoUninitialize(); return ret; @@ -2563,8 +2590,8 @@ static void glitter_editor_test_window(GlitterEditor* glt_edt, class_data* data) data->imgui_focus |= ImGui::IsWindowFocused(); ImGui::End(); - win_x = min((float_t)width, 240.0f); - win_y = min((float_t)height, 96.0f); + win_x = min_def((float_t)width, 240.0f); + win_y = min_def((float_t)height, 96.0f); x = 0.0f; y = (float_t)height - win_y; @@ -2593,7 +2620,7 @@ static void glitter_editor_test_window(GlitterEditor* glt_edt, class_data* data) life_time = 0; frame = Glitter::glt_particle_manager->GetSceneFrameLifeTime(glt_edt->scene_counter, &life_time); - ImGui::Text("%.0f - %.0f/%d", max(glt_edt->frame_counter - glt_edt->start_frame, 0), frame, life_time); + ImGui::Text("%.0f - %.0f/%d", max_def(glt_edt->frame_counter - glt_edt->start_frame, 0), frame, life_time); ctrl = Glitter::glt_particle_manager->GetCtrlCount(Glitter::PARTICLE_QUAD); disp = Glitter::glt_particle_manager->GetDispCount(Glitter::PARTICLE_QUAD); @@ -2993,7 +3020,7 @@ End: case GLITTER_EDITOR_SELECTED_EFFECT: if (glt_edt->selected_type != type || glt_edt->selected_effect != effect) - glitter_editor_reset(glt_edt); + glt_edt->Reset(); glt_edt->selected_effect = effect; glt_edt->selected_emitter = 0; glt_edt->selected_particle = 0; @@ -3001,7 +3028,7 @@ End: case GLITTER_EDITOR_SELECTED_EMITTER: if (glt_edt->selected_type != type || glt_edt->selected_emitter != emitter) - glitter_editor_reset(glt_edt); + glt_edt->Reset(); glt_edt->selected_effect = effect; glt_edt->selected_emitter = emitter; glt_edt->selected_particle = 0; @@ -3009,7 +3036,7 @@ End: case GLITTER_EDITOR_SELECTED_PARTICLE: if (glt_edt->selected_type != type || glt_edt->selected_particle != particle) - glitter_editor_reset(glt_edt); + glt_edt->Reset(); glt_edt->selected_effect = effect; glt_edt->selected_emitter = emitter; glt_edt->selected_particle = particle; @@ -3196,7 +3223,7 @@ static void glitter_editor_play_manager(GlitterEditor* glt_edt) { life_time = 0; frame = Glitter::glt_particle_manager->GetSceneFrameLifeTime(glt_edt->scene_counter, &life_time); - ImGui::Text("%.0f - %.0f/%d", max(glt_edt->frame_counter - glt_edt->start_frame, 0), frame, life_time); + ImGui::Text("%.0f - %.0f/%d", max_def(glt_edt->frame_counter - glt_edt->start_frame, 0), frame, life_time); ctrl = Glitter::glt_particle_manager->GetCtrlCount(Glitter::PARTICLE_QUAD); disp = Glitter::glt_particle_manager->GetDispCount(Glitter::PARTICLE_QUAD); @@ -3299,13 +3326,12 @@ static void glitter_editor_property_effect(GlitterEditor* glt_edt, class_data* d flags & Glitter::CURVE_TYPE_TRANSLATION_XYZ)) changed = true; - vec3 rotation; - vec3_mult_scalar(effect->rotation, RAD_TO_DEG_FLOAT, rotation); + vec3 rotation = effect->rotation * RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation", &rotation, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation, DEG_TO_RAD_FLOAT, effect->rotation); + effect->rotation = rotation * DEG_TO_RAD_FLOAT; changed = true; } @@ -3395,7 +3421,7 @@ static void glitter_editor_property_effect(GlitterEditor* glt_edt, class_data* d 4, &type, 0, false, &data->imgui_focus)) { if (type == 1) { enum_or(effect->data.flags, Glitter::EFFECT_LOCAL); - free(effect->data.ext_anim); + delete effect->data.ext_anim; } else { enum_and(effect->data.flags, ~Glitter::EFFECT_LOCAL); @@ -3408,7 +3434,7 @@ static void glitter_editor_property_effect(GlitterEditor* glt_edt, class_data* d enum_and(effect->data.ext_anim->flags, ~Glitter::EFFECT_EXT_ANIM_CHARA_ANIM); } else - free(effect->data.ext_anim); + delete effect->data.ext_anim; } changed = true; } @@ -3659,12 +3685,12 @@ static void glitter_editor_property_emitter(GlitterEditor* glt_edt, class_data* vec3 rotation = emitter->rotation; if (draw_z_axis) rotation.z -= (float_t)M_PI_2; - vec3_mult_scalar(rotation, RAD_TO_DEG_FLOAT, rotation); + rotation *= RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation", &rotation, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation, DEG_TO_RAD_FLOAT, rotation); + rotation *= DEG_TO_RAD_FLOAT; if (draw_z_axis) rotation.z += (float_t)M_PI_2; emitter->rotation = rotation; @@ -3672,24 +3698,22 @@ static void glitter_editor_property_emitter(GlitterEditor* glt_edt, class_data* } } else { - vec3 rotation; - vec3_mult_scalar(emitter->rotation, RAD_TO_DEG_FLOAT, rotation); + vec3 rotation = emitter->rotation * RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation", &rotation, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation, DEG_TO_RAD_FLOAT, emitter->rotation); + emitter->rotation = rotation * DEG_TO_RAD_FLOAT; changed = true; } } - vec3 rotation_add; - vec3_mult_scalar(emitter->data.rotation_add, RAD_TO_DEG_FLOAT, rotation_add); + vec3 rotation_add = emitter->data.rotation_add * RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation Add", &rotation_add, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation_add, DEG_TO_RAD_FLOAT, emitter->data.rotation_add); + emitter->data.rotation_add = rotation_add * DEG_TO_RAD_FLOAT; changed = true; } @@ -3730,9 +3754,9 @@ static void glitter_editor_property_emitter(GlitterEditor* glt_edt, class_data* (int32_t*)&emitter->data.timer, 0, true, &data->imgui_focus)) { float_t emission_interval = emitter->data.emission_interval; if (emitter->data.timer == Glitter::EMITTER_TIMER_BY_TIME) - emission_interval = clamp(floorf(emission_interval), 1.0f, FLT_MAX); + emission_interval = clamp_def(floorf(emission_interval), 1.0f, FLT_MAX); else - emission_interval = clamp(emission_interval, 0.0f, FLT_MAX); + emission_interval = clamp_def(emission_interval, 0.0f, FLT_MAX); emitter->data.emission_interval = emission_interval; changed = true; } @@ -4165,12 +4189,12 @@ static void glitter_editor_property_particle(GlitterEditor* glt_edt, class_data* rotation.z -= (float_t)M_PI; else if (draw_z_axis) rotation.z -= (float_t)M_PI_2; - vec3_mult_scalar(rotation, RAD_TO_DEG_FLOAT, rotation); + rotation *= RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation", &rotation, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation, DEG_TO_RAD_FLOAT, rotation); + rotation *= DEG_TO_RAD_FLOAT; if (draw_prev_pos) rotation.z += (float_t)M_PI; else if (draw_z_axis) @@ -4180,44 +4204,40 @@ static void glitter_editor_property_particle(GlitterEditor* glt_edt, class_data* } } else { - vec3 rotation; - vec3_mult_scalar(particle->data.rotation, RAD_TO_DEG_FLOAT, rotation); + vec3 rotation = particle->data.rotation * RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation", &rotation, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation, DEG_TO_RAD_FLOAT, particle->data.rotation); + particle->data.rotation = rotation * DEG_TO_RAD_FLOAT; changed = true; } } - vec3 rotation_random; - vec3_mult_scalar(particle->data.rotation_random, RAD_TO_DEG_FLOAT, rotation_random); + vec3 rotation_random = particle->data.rotation_random * RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation Random", &rotation_random, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation_random, DEG_TO_RAD_FLOAT, particle->data.rotation_random); + particle->data.rotation_random = rotation_random * DEG_TO_RAD_FLOAT; changed = true; } - vec3 rotation_add; - vec3_mult_scalar(particle->data.rotation_add, RAD_TO_DEG_FLOAT, rotation_add); + vec3 rotation_add = particle->data.rotation_add * RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation Add", &rotation_add, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation_add, DEG_TO_RAD_FLOAT, particle->data.rotation_add); + particle->data.rotation_add = rotation_add * DEG_TO_RAD_FLOAT; changed = true; } - vec3 rotation_add_random; - vec3_mult_scalar(particle->data.rotation_add_random, RAD_TO_DEG_FLOAT, rotation_add_random); + vec3 rotation_add_random = particle->data.rotation_add_random * RAD_TO_DEG_FLOAT; if (ImGui::ColumnDragVec3("Rotation Add Random", &rotation_add_random, 0.0001f, -FLT_MAX, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat, (flags & Glitter::CURVE_TYPE_ROTATION_XYZ) >> 3)) { - vec3_mult_scalar(rotation_add_random, DEG_TO_RAD_FLOAT, particle->data.rotation_add_random); + particle->data.rotation_add_random = rotation_add_random * DEG_TO_RAD_FLOAT; changed = true; } @@ -4386,8 +4406,8 @@ static void glitter_editor_property_particle(GlitterEditor* glt_edt, class_data* idx1 = (int32_t)(i + 1); } - char** texture_name_list = force_malloc_s(char*, rc + 1); - char* texture_names = force_malloc_s(char, 0x40 * (rc + 1)); + char** texture_name_list = new char*[rc + 1]; + char* texture_names = new char[0x40 * (rc + 1)]; texture_name_list[0] = texture_names; snprintf(texture_name_list[0], 0x40, "No Texture"); @@ -4414,8 +4434,8 @@ static void glitter_editor_property_particle(GlitterEditor* glt_edt, class_data* idx1, &tex11_anim, &tex1_frame, &tex1_index, &tex1_tex)) changed = true; } - free(texture_names); - free(texture_name_list); + delete[] texture_names; + delete[] texture_name_list; Glitter::ParticleBlendDraw blend_draw = Glitter::particle_blend_draw_default; for (int32_t i = 0; i < Glitter::particle_blend_mask_types_count; i++) @@ -4466,7 +4486,7 @@ static void glitter_editor_property_particle(GlitterEditor* glt_edt, class_data* else if (particle->data.uv_index_end >= 0 && particle->data.uv_index > particle->data.uv_index_end) particle->data.uv_index = particle->data.uv_index_end; - particle->data.uv_index = min(particle->data.uv_index, uv_max_count); + particle->data.uv_index = min_def(particle->data.uv_index, uv_max_count); break; } @@ -5386,878 +5406,6 @@ static float_t convert_value_to_height(GlitterEditor* glt_edt, + crv_edt->height_offset; } -static void glitter_editor_curve_editor(GlitterEditor* glt_edt) { - Glitter::Emitter* sel_emit = glt_edt->selected_emitter; - Glitter::Particle* sel_ptcl = glt_edt->selected_particle; - GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; - - if (crv_edt->type < Glitter::CURVE_TRANSLATION_X - || crv_edt->type > Glitter::CURVE_V_SCROLL_ALPHA_2ND) - return; - - switch (glt_edt->selected_type) { - case GLITTER_EDITOR_SELECTED_EFFECT: - case GLITTER_EDITOR_SELECTED_EMITTER: - case GLITTER_EDITOR_SELECTED_PARTICLE: - break; - default: - return; - } - - Glitter::EffectGroup* eg = glt_edt->effect_group; - Glitter::Curve* curve = crv_edt->list[crv_edt->type]; - std::vector* keys = curve ? &curve->keys_rev : 0; - bool changed = false; - - bool fix_rot_z = eg->type != Glitter::X && curve && curve->type == Glitter::CURVE_ROTATION_Z - && ((glt_edt->selected_type == GLITTER_EDITOR_SELECTED_EMITTER - && sel_emit->data.direction == Glitter::DIRECTION_Z_AXIS) - || (glt_edt->selected_type == GLITTER_EDITOR_SELECTED_PARTICLE - && sel_ptcl->data.draw_type == Glitter::DIRECTION_Z_AXIS)); - - bool add_key = false; - bool del_key = false; - if (curve) - glitter_editor_curve_editor_key_manager(glt_edt, keys, &add_key, &del_key); - - if (ImGui::IsWindowFocused()) { - if (add_key && ImGui::IsKeyPressed(GLFW_KEY_INSERT)) - crv_edt->add_key = true; - else if (del_key && ImGui::IsKeyPressed(GLFW_KEY_DELETE)) - crv_edt->del_key = true; - else if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT)) - crv_edt->frame++; - else if (ImGui::IsKeyPressed(GLFW_KEY_LEFT)) - crv_edt->frame--; - } - - bool exist = true; - if (crv_edt->add_key && add_key) { - if (!crv_edt->list[crv_edt->type] || !keys || !keys->size()) { - if (!crv_edt->list[crv_edt->type]) { - Glitter::Curve* c = new Glitter::Curve(eg->type); - crv_edt->animation->curves.push_back(curve); - crv_edt->list[crv_edt->type] = c; - curve = c; - } - - glitter_editor_curve_editor_curve_set(glt_edt, curve, crv_edt->type); - - if (!keys) - keys = &curve->keys_rev; - - Glitter::Curve::Key key; - key.frame = 0; - key.value = glitter_editor_curve_editor_get_value(glt_edt, curve->type); - keys->push_back(key); - - crv_edt->frame = 0; - changed = true; - } - else { - std::vector::iterator i = keys->begin(); - bool is_before_start = keys->data()[0].frame > crv_edt->frame; - bool has_key_after = false; - if (!is_before_start) - for (i++; i != keys->end(); i++) - if (crv_edt->frame <= i->frame) { - has_key_after = keys->end() - i > 0; - break; - } - - ssize_t pos = i - keys->begin(); - if (!is_before_start) - pos--; - - if (!is_before_start && has_key_after) { - std::vector::iterator c = i - 1; - std::vector::iterator n = i; - - Glitter::Curve::Key key; - key.frame = crv_edt->frame; - key.type = c->type; - switch (c->type) { - case Glitter::KEY_CONSTANT: - key.value = c->value; - key.random_range = c->random_range; - break; - case Glitter::KEY_LINEAR: { - float_t t = (float_t)(key.frame - c->frame) / (float_t)(n->frame - c->frame); - key.value = lerp(c->value, n->value, t); - key.random_range = lerp(c->random_range, n->random_range, t); - } break; - case Glitter::KEY_HERMITE: { - int32_t df = n->frame - c->frame; - int32_t _df = key.frame - c->frame; - float_t* v_arr = 0; - size_t v_length = 0; - interpolate_chs(c->value, n->value, c->tangent2, n->tangent1, 0, df, &v_arr, &v_length); - key.value = v_arr[_df]; - key.random_range = lerp(c->random_range, n->random_range, (float_t)_df / (float_t)df); - interpolate_chs_reverse(v_arr, v_length, &c->tangent2, &key.tangent1, 0, _df); - interpolate_chs_reverse(v_arr, v_length, &key.tangent2, &n->tangent1, _df, df); - free(v_arr); - } break; - } - keys->insert(keys->begin() + ++pos, key); - } - else if (is_before_start) { - std::vector::iterator n = i; - - Glitter::Curve::Key key; - key.frame = crv_edt->frame; - key.type = n->type; - key.value = n->value; - key.random_range = n->random_range; - keys->insert(keys->begin() + pos, key); - } - else { - std::vector::iterator c = i - 1; - - Glitter::Curve::Key key; - key.frame = crv_edt->frame; - key.type = c->type; - key.value = c->value; - key.random_range = c->random_range; - keys->insert(keys->begin() + ++pos, key); - } - *crv_edt->list[crv_edt->type] = *curve; - changed = true; - } - } - else if (keys && crv_edt->del_key && del_key) { - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) - if (&i[0] == crv_edt->key) { - bool has_key_before = keys->front().frame < i->frame; - bool has_key_after = keys->back().frame > i->frame; - if (has_key_before && i[-1].type == Glitter::KEY_HERMITE && has_key_after) { - std::vector::iterator c = i - 1; - std::vector::iterator n = i + 1; - int32_t df_c = i->frame - c->frame; - int32_t df_n = n->frame - i->frame; - - float_t* v_arr_c = 0; - size_t v_length_c = 0; - interpolate_chs(c->value, i->value, c->tangent2, - i->tangent1, 0, df_c, &v_arr_c, &v_length_c); - - float_t* v_arr_n = 0; - size_t v_length_n = 0; - if (i->type == Glitter::KEY_HERMITE) - interpolate_chs(i->value, n->value, i->tangent2, - n->tangent1, 0, df_n, &v_arr_n, &v_length_n); - else - interpolate_linear(i->value, n->value, - 0, df_n, &v_arr_n, &v_length_n); - - size_t v_length = v_length_c + v_length_n - 1; - float_t* v_arr = force_malloc_s(float_t, v_length); - memmove(v_arr, v_arr_c, (v_length_c - 1) * sizeof(float_t)); - memmove(v_arr + (v_length_c - 1), v_arr_n, (v_length_n) * sizeof(float_t)); - free(v_arr_c); - free(v_arr_n); - interpolate_chs_reverse(v_arr, v_length, &c->tangent2, - &n->tangent1, 0, (size_t)n->frame - c->frame); - free(v_arr); - } - keys->erase(i); - changed = true; - break; - } - } - else if (crv_edt->add_curve) { - Glitter::Curve* c = new Glitter::Curve(eg->type); - crv_edt->animation->curves.push_back(c); - crv_edt->list[crv_edt->type] = c; - curve = c; - - glitter_editor_curve_editor_curve_set(glt_edt, curve, crv_edt->type); - *crv_edt->list[crv_edt->type] = *curve; - crv_edt->frame = curve->start_time; - changed = true; - } - else if (crv_edt->del_curve) { - Glitter::Curve* c = crv_edt->list[crv_edt->type]; - Glitter::Animation* anim = crv_edt->animation; - for (std::vector::iterator i = anim->curves.begin(); i != anim->curves.end(); i++) - if (*i && *i == c) { - delete* i; - anim->curves.erase(i); - break; - } - - crv_edt->list[crv_edt->type] = 0; - crv_edt->frame = 0; - changed = true; - } - crv_edt->add_key = false; - crv_edt->del_key = false; - crv_edt->add_curve = false; - crv_edt->del_curve = false; - - if (!curve || !keys) - return; - - int32_t start_time = curve->start_time; - int32_t end_time = curve->end_time; - - ImGuiIO& io = ImGui::GetIO(); - ImGuiStyle& style = ImGui::GetStyle(); - ImFont* font = ImGui::GetFont(); - - ImVec2 cont_reg_avail = ImGui::GetContentRegionAvail(); - - ImVec2 canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max; - crv_edt->draw_list = ImGui::GetWindowDrawList(); - canvas_size = cont_reg_avail; - canvas_pos = ImGui::GetCursorScreenPos(); - canvas_pos_min.x = canvas_pos.x; - canvas_pos_min.y = canvas_pos.y; - canvas_pos_max.x = canvas_pos.x + canvas_size.x; - canvas_pos_max.y = canvas_pos.y + canvas_size.y; - - ImRect boundaries; - boundaries.Min = canvas_pos; - boundaries.Max.x = canvas_pos.x + canvas_size.x; - boundaries.Max.y = canvas_pos.y + canvas_size.y; - - if (crv_edt->zoom_time != crv_edt->prev_zoom_time) { - float_t timeline_pos = crv_edt->timeline_pos + curve_editor_timeline_base_pos; - timeline_pos *= crv_edt->zoom_time / crv_edt->prev_zoom_time; - crv_edt->timeline_pos = timeline_pos - curve_editor_timeline_base_pos; - } - crv_edt->prev_zoom_time = crv_edt->zoom_time; - - float_t frame_width = crv_edt->frame_width - * crv_edt->zoom_time; - canvas_pos.x -= crv_edt->timeline_pos; - - ImGui::ItemSize(boundaries); - bool hovered = ImGui::IsMouseHoveringRect(boundaries.Min, boundaries.Max); - ImGui::RenderFrame(boundaries.Min, boundaries.Max, ImGui::GetColorU32(ImGuiCol_FrameBg), true, 1.0f); - - static bool can_drag; - if (hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left, false)) - can_drag = true; - - if (can_drag && (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT))) { - crv_edt->key = glitter_editor_curve_editor_get_closest_key(glt_edt, curve); - crv_edt->frame = crv_edt->key->frame; - } - else - crv_edt->key = glitter_editor_curve_editor_get_selected_key(glt_edt, curve); - - if (can_drag && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) - can_drag = false; - - float_t timeline_max_offset = (end_time - start_time) * frame_width; - timeline_max_offset = max(timeline_max_offset, 0.0f) - curve_editor_timeline_base_pos; - - crv_edt->draw_list->PushClipRect(boundaries.Min, boundaries.Max, true); - - int32_t start = (int32_t)(crv_edt->timeline_pos / frame_width) + start_time; - int32_t end = (int32_t)((crv_edt->timeline_pos + canvas_size.x) / frame_width) + start_time; - - ImU32 line_color_valid_bold = ImGui::GetColorU32({ 0.5f, 0.5f, 0.5f, 0.75f }); - ImU32 line_color_valid = ImGui::GetColorU32({ 0.4f, 0.4f, 0.4f, 0.45f }); - ImU32 line_color_not_valid = ImGui::GetColorU32({ 0.2f, 0.2f, 0.2f, 0.75f }); - for (int32_t frame = start; frame <= end; frame++) { - if (frame < start_time) - continue; - - int32_t f = frame - start_time; - float_t x = canvas_pos.x + f * frame_width; - float_t y = canvas_pos.y + (f % 2 ? 10.0f : 0.0f) + canvas_size.y; - - bool bold_frame = !(f % 10) || !f || frame == end_time; - bool valid_frame = f >= 0 && frame <= end_time; - - ImU32 line_color = valid_frame ? (bold_frame ? line_color_valid_bold - : line_color_valid) : line_color_not_valid; - crv_edt->draw_list->AddLine({ x, y - canvas_size.y }, - { x, y }, line_color, 0.80f); - - if (bold_frame) { - char buf[0x20]; - snprintf(buf, sizeof(buf), "%d", frame); - crv_edt->draw_list->AddText({ x + 3, canvas_pos.y }, line_color, buf); - } - } - - float_t max = crv_edt->range * (1.0f / crv_edt->zoom_value); - float_t min; - if (curve->type == Glitter::CURVE_EMISSION_INTERVAL) - min = -1.0f; - else if (curve->type == Glitter::CURVE_PARTICLES_PER_EMISSION) - min = 0.0f; - else - min = -max; - - for (int32_t j = 0; j < 5; j++) { - float_t x_pos = canvas_pos_min.x; - float_t y_pos = canvas_pos.y + j * 0.25f * (canvas_size.y - - crv_edt->height_offset) + crv_edt->height_offset; - - ImU32 line_color = j % 2 == 1 - ? ImGui::GetColorU32({ 0.35f, 0.35f, 0.35f, 0.45f }) - : ImGui::GetColorU32({ 0.45f, 0.45f, 0.45f, 0.75f }); - bool last = j == 4; - if (j && !last) - crv_edt->draw_list->AddLine({ x_pos, y_pos }, - { x_pos + canvas_size.x, y_pos }, line_color, 0.80f); - - float_t val = max - j * 0.25f * (max - min); - char buf[0x20]; - snprintf(buf, sizeof(buf), "%.2f", val); - crv_edt->draw_list->AddText({ x_pos + 2, y_pos + (last ? -16 : -2) }, - ImGui::GetColorU32({ 0.65f, 0.65f, 0.65f, 0.85f }), buf); - } - - if (curve->type >= Glitter::CURVE_ROTATION_X && curve->type <= Glitter::CURVE_ROTATION_Z) { - max *= DEG_TO_RAD_FLOAT; - min *= DEG_TO_RAD_FLOAT; - } - else if (curve->type >= Glitter::CURVE_COLOR_R && curve->type <= Glitter::CURVE_COLOR_RGB_SCALE_2ND) { - max *= (float_t)(1.0 / 255.0); - min *= (float_t)(1.0 / 255.0); - } - - float_t base_line = convert_value_to_height(glt_edt, 0.0f, canvas_pos.y, canvas_size.y, min, max); - - ImVec2 p1, p2, p3; - p1.x = canvas_pos_min.x; - p1.y = canvas_pos.y + crv_edt->height_offset; - p2.x = p1.x + canvas_size.x; - p2.y = canvas_pos.y + crv_edt->height_offset; - p3.x = canvas_pos_min.x; - p3.y = canvas_pos.y; - crv_edt->draw_list->AddLine(p1, p2, - ImGui::GetColorU32({ 0.5f, 0.5f, 0.5f, 0.85f }), 2.0f); - - ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); - ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); - ImU32 default_color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.75f }); - ImU32 selected_color = ImGui::GetColorU32({ 0.0f, 1.0f, 1.0f, 0.75f }); - - if (curve->flags & Glitter::CURVE_RANDOM_RANGE - || curve->flags & Glitter::CURVE_KEY_RANDOM_RANGE) { - float_t random_range = curve->random_range; - bool random_range_mult = curve->flags & Glitter::CURVE_RANDOM_RANGE_MULT; - bool random_range_negate = curve->flags & Glitter::CURVE_RANDOM_RANGE_NEGATE; - bool glt_type_ft = eg->type == Glitter::FT; - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { - if (i->frame >= end_time || keys->end() - i <= 1) - break; - - std::vector::iterator c = i; - std::vector::iterator n = i + 1; - float_t x1 = canvas_pos.x + (float_t)(c->frame - start_time) * frame_width; - float_t x2 = canvas_pos.x + (float_t)(n->frame - start_time) * frame_width; - - if (((x1 < canvas_pos_min.x) && (x2 < canvas_pos_min.x)) || - (x1 > canvas_pos_max.x) && (x2 > canvas_pos_max.x)) - continue; - - x1 = max(x1, canvas_pos_min.x); - x2 = min(x2, canvas_pos_max.x); - - Glitter::KeyType k_type = c->type; - float_t c_frame = (float_t)c->frame; - float_t n_frame = (float_t)n->frame; - float_t c_value = c->value; - float_t n_value = n->value; - if (fix_rot_z) { - c_value -= (float_t)M_PI_2; - n_value -= (float_t)M_PI_2; - } - float_t c_random_range = c->random_range; - float_t n_random_range = n->random_range; - if (random_range_mult && glt_type_ft) { - c_random_range *= c_value; - n_random_range *= n_value; - } - - size_t frame_width_int = (size_t)roundf(frame_width); - if (k_type == Glitter::KEY_CONSTANT) { - vec3 value = { c_value + c_random_range, c_value, c_value - c_random_range }; - vec3 random = { random_range, random_range, random_range }; - if (random_range_mult) { - vec3_mult(random, value, random); - if (!glt_type_ft) - vec3_mult_scalar(random, 0.01f, random); - } - - if (value.x != value.y) { - float_t y1 = convert_value_to_height(glt_edt, value.x + random.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, random_range_color, 0.0f, 0); - - y3 = clamp(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddRectFilled({ x1, y3 }, - { x2, y4 }, key_random_range_color, 0.0f, 0); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y + random.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, random_range_color, 0.0f, 0); - } - - if (random_range_negate) - if (value.y != value.z) { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.z - random.z, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, key_random_range_color, 0.0f, 0); - - y3 = clamp(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddRectFilled({ x1, y3 }, - { x2, y4 }, random_range_color, 0.0f, 0); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y - random.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, random_range_color, 0.0f, 0); - } - } - else { - float_t c_tangent2 = c->tangent2; - float_t n_tangent1 = n->tangent1; - - vec3 c_frame_vec = { c_frame, c_frame, c_frame }; - vec3 n_frame_vec = { n_frame, n_frame, n_frame }; - vec3 c_value_vec = { c_value + c_random_range, c_value, c_value - c_random_range }; - vec3 n_value_vec = { n_value + n_random_range, n_value, n_value - n_random_range }; - vec3 random_vec = { random_range, random_range, random_range }; - vec3 c_tangent2_vec = { c_tangent2, c_tangent2, c_tangent2 }; - vec3 n_tangent1_vec = { n_tangent1, n_tangent1, n_tangent1 }; - for (size_t i = c->frame; i < n->frame; i++) - for (size_t j = 0; j < frame_width_int; j++) { - float_t frame = (float_t)i + (float_t)j / frame_width; - vec3 frame_vec = { frame, frame, frame }; - - vec3 value; - if (k_type != Glitter::KEY_HERMITE) - interpolate_linear_value_vec3(&c_value_vec, &n_value_vec, - &c_frame_vec, &n_frame_vec, &frame_vec, &value); - else - interpolate_chs_value_vec3(&c_value_vec, &n_value_vec, - &c_tangent2_vec, &n_tangent1_vec, - &c_frame_vec, &n_frame_vec, &frame_vec, &value); - - vec3 random; - if (random_range_mult) { - vec3_mult(random_vec, value, random); - if (!glt_type_ft) - vec3_mult_scalar(random, 0.01f, random); - } - else - random = random_vec; - - if (random_range_mult) { - vec3 random = { random_range, random_range, random_range }; - vec3_mult(random, value, random); - if (!glt_type_ft) - vec3_mult_scalar(random, 0.01f, random); - } - - float_t x = canvas_pos.x - + (float_t)(i - start_time) * frame_width + (float_t)j; - if (value.x != value.y) { - float_t y1 = convert_value_to_height(glt_edt, value.x + random.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, random_range_color, 0.0f); - - y3 = clamp(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddLine({ x, y3 }, - { x, y4 }, key_random_range_color, 0.0f); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y + random.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, random_range_color, 0.0f); - } - - if (random_range_negate) - if (value.y != value.z) { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.z - random.z, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, key_random_range_color, 0.0f); - - y3 = clamp(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddLine({ x, y3 }, - { x, y4 }, random_range_color, 0.0f); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y - random.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, random_range_color, 0.0f); - } - } - } - } - } - - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { - if (i->frame >= end_time || keys->end() - i <= 1) - break; - - std::vector::iterator c = i; - std::vector::iterator n = i + 1; - float_t x1 = canvas_pos.x + (float_t)(c->frame - start_time) * frame_width; - float_t x2 = canvas_pos.x + (float_t)(n->frame - start_time) * frame_width; - - if (((x1 < canvas_pos_min.x) && (x2 < canvas_pos_min.x)) || - (x1 > canvas_pos_max.x) && (x2 > canvas_pos_max.x)) - continue; - - float_t c_value = c->value; - float_t n_value = n->value; - - if (fix_rot_z) { - c_value -= (float_t)M_PI_2; - n_value -= (float_t)M_PI_2; - } - - if (i->type != Glitter::KEY_HERMITE) { - float_t y1 = convert_value_to_height(glt_edt, c_value, canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, n_value, canvas_pos.y, canvas_size.y, min, max); - - if (i->type == Glitter::KEY_CONSTANT) { - int32_t count = 0; - ImVec2 points_temp[3]; - if (x1 != x2) - points_temp[count++] = { x1, y1 }; - points_temp[count++] = { x2, y1 }; - if (y1 != y2) - points_temp[count++] = { x2, y2 }; - - if (count > 1) - crv_edt->draw_list->AddPolyline(points_temp, - count, default_color, 0, 3.0f); - } - else - crv_edt->draw_list->AddLine({ x1, y1 }, { x2, y2 }, default_color, 3.0f); - } - else { - float_t c_frame = (float_t)c->frame; - float_t n_frame = (float_t)n->frame; - float_t c_tangent2 = (float_t)c->tangent2; - float_t n_tangent1 = (float_t)n->tangent1; - size_t frame_width_int = (size_t)roundf(frame_width); - size_t points_count = ((size_t)n_frame - (size_t)c_frame) * frame_width_int; - ImVec2* points = force_malloc_s(ImVec2, points_count); - for (size_t i = c->frame; i < n->frame; i++) - for (size_t j = 0; j < frame_width_int; j++) { - float_t value = interpolate_chs_value(c_value, n_value, c_tangent2, n_tangent1, - c_frame, n_frame, (float_t)i + (float_t)j / frame_width); - - ImVec2 point; - point.x = canvas_pos.x - + (float_t)(i - start_time) * frame_width + (float_t)j; - point.y = convert_value_to_height(glt_edt, value, - canvas_pos.y, canvas_size.y, min, max); - points[(i - c->frame) * frame_width_int + j] = point; - } - crv_edt->draw_list->AddPolyline(points, - (int32_t)points_count, default_color, 0, 3.0f); - free(points); - } - } - - const ImU32 key_constant_color = ImGui::GetColorU32({ 1.0f, 0.0f, 0.0f, 0.75f }); - const ImU32 key_linear_color = ImGui::GetColorU32({ 0.0f, 1.0f, 0.0f, 0.75f }); - const ImU32 key_hermite_color = ImGui::GetColorU32({ 0.0f, 0.0f, 1.0f, 0.75f }); - - bool dragged = false; - bool holding_tan = false; - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { - if (!(i->frame >= start_time || i->frame <= end_time)) - continue; - else if (i - keys->begin() > 1) - if (i->frame < start_time && i[1].frame < start_time) - continue; - else if (i->frame > end_time && i[-1].frame > end_time) - continue; - - float_t base_value = i->value; - if (fix_rot_z) - base_value -= (float_t)M_PI_2; - float_t x = canvas_pos.x + ((size_t)i->frame - start_time) * frame_width; - float_t y = convert_value_to_height(glt_edt, base_value, canvas_pos.y, canvas_size.y, min, max); - - if (!(x >= p3.x - 10.0f && x <= p3.x + canvas_size.x + 10.0f) - || !(y >= p3.y - 10.0f && y <= p3.y + canvas_size.y + 10.0f)) - continue; - - ImU32 value_color; - switch (i->type) { - case Glitter::KEY_CONSTANT: - value_color = key_constant_color; - break; - case Glitter::KEY_LINEAR: - default: - value_color = key_linear_color; - break; - case Glitter::KEY_HERMITE: - value_color = key_hermite_color; - break; - } - - ImGui::PushID(i._Ptr); - ImGui::SetCursorScreenPos({ x - 7.5f, y - 7.5f }); - ImGui::InvisibleButton("val", { 15.0f, 15.0f }, 0); - - if (can_drag && ImGui::IsItemActive() - && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f)) { - float_t old_y = y; - - static int32_t base_frame; - static float_t base_y; - if ((ImGui::IsKeyPressed(GLFW_KEY_LEFT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) - || (ImGui::IsKeyPressed(GLFW_KEY_RIGHT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT))) { - base_frame = i->frame; - base_y = base_value; - } - - if (i->frame >= start_time && i->frame <= end_time) { - int32_t start = i - keys->begin() > 0 ? (i - 1)->frame + 1 : start_time; - int32_t end = keys->end() - i > 1 ? (i + 1)->frame - 1 : end_time; - crv_edt->frame = (int32_t)roundf((io.MousePos.x - canvas_pos.x) / frame_width); - crv_edt->frame = clamp(crv_edt->frame + start_time, start, end); - if (i->frame != crv_edt->frame) { - i->frame = crv_edt->frame; - changed = true; - } - } - - static float_t mouse_delta_history; - if ((ImGui::IsKeyPressed(GLFW_KEY_LEFT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) - || (ImGui::IsKeyPressed(GLFW_KEY_RIGHT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT))) - mouse_delta_history = io.MouseDelta.y; - else if ((ImGui::IsKeyReleased(GLFW_KEY_LEFT_SHIFT) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) - || ImGui::IsKeyReleased(GLFW_KEY_RIGHT_SHIFT) && !ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT)) { - y += mouse_delta_history; - y += io.MouseDelta.y; - } - else if (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) - mouse_delta_history += io.MouseDelta.y; - else - y += io.MouseDelta.y; - - if (old_y != y) { - float_t value = convert_height_to_value(glt_edt, - y, canvas_pos.y, canvas_size.y, min, max); - dragged = true; - - if (base_value != value) { - if (fix_rot_z) - value += (float_t)M_PI_2; - i->value = value; - changed = true; - } - crv_edt->key = &i[0]; - } - } - - if (i - keys->begin() > 0 && (i - 1)->type == Glitter::KEY_HERMITE) { - ImU32 tangent1_color; - float_t tangent1; - ImVec2 circle_pos; - circle_pos.x = x - 25.0f; - circle_pos.y = y - base_line + convert_value_to_height(glt_edt, tangent1 = i->tangent1, - canvas_pos.y, canvas_size.y, min, max); - crv_edt->draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); - - if ((circle_pos.x >= p3.x - 10.0f && circle_pos.x <= p3.x + canvas_size.x + 10.0f) - && (circle_pos.y >= p3.y - 10.0f && circle_pos.y <= p3.y + canvas_size.y + 10.0f)) { - ImGui::SetCursorScreenPos({ circle_pos.x - 7.5f, circle_pos.y - 7.5f }); - ImGui::InvisibleButton("tan1", { 15.0f, 15.0f }, 0); - - if (can_drag && ImGui::IsItemActive()) { - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { - i->tangent1 = convert_height_to_value(glt_edt, - circle_pos.y + io.MouseDelta.y - y + base_line, - canvas_pos.y, canvas_size.y, min, max); - - if (i->tangent1 != tangent1) - changed = true; - } - holding_tan = true; - tangent1_color = selected_color; - } - else - tangent1_color = default_color; - - crv_edt->draw_list->AddCircleFilled(circle_pos, - crv_edt->key_radius_in, tangent1_color, 12); - } - } - - if (keys->end() - i > 1 && i->type == Glitter::KEY_HERMITE) { - ImU32 tangent2_color; - float_t tangent2; - ImVec2 circle_pos; - circle_pos.x = x + 25.0f; - circle_pos.y = y - base_line + convert_value_to_height(glt_edt, tangent2 = i->tangent2, - canvas_pos.y, canvas_size.y, min, max); - crv_edt->draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); - - if ((circle_pos.x >= p3.x - 10.0f && circle_pos.x <= p3.x + canvas_size.x + 10.0f) - && (circle_pos.y >= p3.y - 10.0f && circle_pos.y <= p3.y + canvas_size.y + 10.0f)) { - ImGui::SetCursorScreenPos({ circle_pos.x - 7.5f, circle_pos.y - 7.5f }); - ImGui::InvisibleButton("tan2", { 15.0f, 15.0f }, 0); - - if (can_drag && ImGui::IsItemActive()) { - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { - i->tangent2 = convert_height_to_value(glt_edt, - circle_pos.y + io.MouseDelta.y - y + base_line, - canvas_pos.y, canvas_size.y, min, max); - - if (i->tangent2 != tangent2) - changed = true; - } - holding_tan = true; - tangent2_color = selected_color; - } - else - tangent2_color = default_color; - - crv_edt->draw_list->AddCircleFilled(circle_pos, - crv_edt->key_radius_in, tangent2_color, 12); - } - } - - crv_edt->draw_list->AddCircleFilled({ x, y }, - crv_edt->key_radius_out, crv_edt->key == &i[0] ? selected_color : default_color, 12); - crv_edt->draw_list->AddCircleFilled({ x, y }, - crv_edt->key_radius_in, value_color, 12); - ImGui::PopID(); - } - - if (!crv_edt->key_edit && can_drag && ImGui::IsMouseDown(ImGuiMouseButton_Left) && (!holding_tan || dragged)) { - int32_t frame = (int32_t)roundf((io.MousePos.x - canvas_pos.x) / frame_width); - crv_edt->frame = clamp(frame + start_time, start_time, end_time); - if (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) { - crv_edt->key = glitter_editor_curve_editor_get_closest_key(glt_edt, curve); - crv_edt->frame = crv_edt->key->frame; - } - else - crv_edt->key = glitter_editor_curve_editor_get_selected_key(glt_edt, curve); - } - crv_edt->frame = clamp(crv_edt->frame, start_time, end_time); - - int32_t cursor_frame = crv_edt->frame - start_time; - ImVec2 cursor_pos = canvas_pos; - cursor_pos.x += cursor_frame * frame_width; - if (cursor_pos.x >= p1.x - 10.0f && cursor_pos.x <= p1.x + canvas_size.x + 10.0f) { - ImU32 cursor_color = ImGui::GetColorU32({ 0.8f, 0.8f, 0.8f, 0.75f }); - p1.x = cursor_pos.x; - p1.y = canvas_pos.y + canvas_size.y; - crv_edt->draw_list->AddLine(cursor_pos, p1, cursor_color, 2.5f); - - p1 = p2 = p3 = cursor_pos; - p1.x -= 10.0f; - p2.y += 10.0f; - p3.x += 10.0f; - crv_edt->draw_list->AddTriangleFilled(p1, p2, p3, cursor_color); - } - crv_edt->draw_list->PopClipRect(); - - if (hovered) - if (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) - crv_edt->timeline_pos -= io.MouseWheel * 25.0f * 4.0f; - else - crv_edt->timeline_pos -= io.MouseWheel * 25.0f; - - crv_edt->timeline_pos = clamp(crv_edt->timeline_pos, - -curve_editor_timeline_base_pos, timeline_max_offset); - - if (crv_edt->list[crv_edt->type] && changed) { - curve->Recalculate(eg->type); - *crv_edt->list[crv_edt->type] = *curve; - glt_edt->input_reload = true; - } -} - static void glitter_editor_curve_editor_curve_set(GlitterEditor* glt_edt, Glitter::Curve* curve, Glitter::CurveType type) { Glitter::EffectGroup* eg = glt_edt->effect_group; @@ -6281,14 +5429,6 @@ static void glitter_editor_curve_editor_curve_set(GlitterEditor* glt_edt, } } -static void glitter_editor_curve_editor_curves_reset(GlitterEditor* glt_edt) { - GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; - memset(&crv_edt->list, 0, sizeof(Glitter::Curve*) - * (Glitter::CURVE_V_SCROLL_ALPHA_2ND - Glitter::CURVE_TRANSLATION_X + 1)); - crv_edt->animation = 0; - crv_edt->key = {}; -} - static Glitter::Curve::Key* glitter_editor_curve_editor_get_closest_key( GlitterEditor* glt_edt, Glitter::Curve* curve) { GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; @@ -6646,9 +5786,9 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, ImGui::SetNextItemWidth(60.0f); if (ImGui::InputInt("##C Type:", &c_type, 1, 1)) { if (eg->type == Glitter::X) - c_type = clamp(c_type, 1, 2); + c_type = clamp_def(c_type, 1, 2); else - c_type = clamp(c_type, 0, 1); + c_type = clamp_def(c_type, 0, 1); if (c_type != curve->version) changed = true; @@ -6662,9 +5802,9 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, ImGui::SetNextItemWidth(60.0f); if (ImGui::InputInt("##K Type:", &k_type, 1, 1)) { if (eg->type == Glitter::X) - k_type = clamp(k_type, 2, 3); + k_type = clamp_def(k_type, 2, 3); else - k_type = clamp(k_type, 0, 2); + k_type = clamp_def(k_type, 0, 2); if (k_type != curve->keys_version) changed = true; @@ -6737,77 +5877,6 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, } } -static void glitter_editor_curve_editor_reset_state(GlitterEditor* glt_edt, Glitter::CurveType type) { - GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; - - if (crv_edt->type != type) - crv_edt->type = type; - - crv_edt->frame_width = 16; - crv_edt->zoom_time = 1.0f; - crv_edt->prev_zoom_time = 1.0f; - crv_edt->zoom_value = 1.0f; - crv_edt->key_radius_in = 6.0f; - crv_edt->key_radius_out = 8.0f; - crv_edt->height_offset = 20.0f; - crv_edt->frame = 0; - - crv_edt->timeline_pos = -curve_editor_timeline_base_pos; - - switch (type) { - case Glitter::CURVE_TRANSLATION_X: - case Glitter::CURVE_TRANSLATION_Y: - case Glitter::CURVE_TRANSLATION_Z: - crv_edt->range = 25.0f; - break; - case Glitter::CURVE_ROTATION_X: - case Glitter::CURVE_ROTATION_Y: - case Glitter::CURVE_ROTATION_Z: - crv_edt->range = 360.0f; - break; - case Glitter::CURVE_SCALE_X: - case Glitter::CURVE_SCALE_Y: - case Glitter::CURVE_SCALE_Z: - case Glitter::CURVE_SCALE_ALL: - crv_edt->range = 5.0f; - break; - case Glitter::CURVE_COLOR_R: - case Glitter::CURVE_COLOR_G: - case Glitter::CURVE_COLOR_B: - case Glitter::CURVE_COLOR_A: - case Glitter::CURVE_COLOR_RGB_SCALE: - case Glitter::CURVE_COLOR_R_2ND: - case Glitter::CURVE_COLOR_G_2ND: - case Glitter::CURVE_COLOR_B_2ND: - case Glitter::CURVE_COLOR_A_2ND: - case Glitter::CURVE_COLOR_RGB_SCALE_2ND: - crv_edt->range = 255.0f; - break; - case Glitter::CURVE_EMISSION_INTERVAL: - crv_edt->range = 20.0f; - break; - case Glitter::CURVE_PARTICLES_PER_EMISSION: - crv_edt->range = 50.0f; - break; - case Glitter::CURVE_U_SCROLL: - case Glitter::CURVE_V_SCROLL: - case Glitter::CURVE_U_SCROLL_ALPHA: - case Glitter::CURVE_V_SCROLL_ALPHA: - case Glitter::CURVE_U_SCROLL_2ND: - case Glitter::CURVE_V_SCROLL_2ND: - case Glitter::CURVE_U_SCROLL_ALPHA_2ND: - case Glitter::CURVE_V_SCROLL_ALPHA_2ND: - crv_edt->range = 1.0f; - break; - default: - crv_edt->range = 1.0f; - break; - } - - crv_edt->add_key = false; - crv_edt->del_key = false; -} - static void glitter_editor_curve_editor_selector(GlitterEditor* glt_edt, class_data* data) { GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; int32_t sel_rsrc = glt_edt->selected_resource; @@ -6871,7 +5940,7 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ ImGui::Selectable(_l, crv_edt->type == Glitter::CURVE_##curve_type); \ \ if (ImGui::IsItemFocused() && crv_edt->type != Glitter::CURVE_##curve_type) { \ - glitter_editor_curve_editor_reset_state(glt_edt, Glitter::CURVE_##curve_type); \ + glt_edt->curve_editor.ResetState(Glitter::CURVE_##curve_type); \ reset = true; \ } \ } @@ -7015,6 +6084,865 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ ImGui::EndGroup(); } +static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { + Glitter::Emitter* sel_emit = glt_edt->selected_emitter; + Glitter::Particle* sel_ptcl = glt_edt->selected_particle; + GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; + + if (crv_edt->type < Glitter::CURVE_TRANSLATION_X + || crv_edt->type > Glitter::CURVE_V_SCROLL_ALPHA_2ND) + return; + + switch (glt_edt->selected_type) { + case GLITTER_EDITOR_SELECTED_EFFECT: + case GLITTER_EDITOR_SELECTED_EMITTER: + case GLITTER_EDITOR_SELECTED_PARTICLE: + break; + default: + return; + } + + Glitter::EffectGroup* eg = glt_edt->effect_group; + Glitter::Curve* curve = crv_edt->list[crv_edt->type]; + std::vector* keys = curve ? &curve->keys_rev : 0; + bool changed = false; + + bool fix_rot_z = eg->type != Glitter::X && curve && curve->type == Glitter::CURVE_ROTATION_Z + && ((glt_edt->selected_type == GLITTER_EDITOR_SELECTED_EMITTER + && sel_emit->data.direction == Glitter::DIRECTION_Z_AXIS) + || (glt_edt->selected_type == GLITTER_EDITOR_SELECTED_PARTICLE + && sel_ptcl->data.draw_type == Glitter::DIRECTION_Z_AXIS)); + + bool add_key = false; + bool del_key = false; + if (curve) + glitter_editor_curve_editor_key_manager(glt_edt, keys, &add_key, &del_key); + + if (ImGui::IsWindowFocused()) { + if (add_key && ImGui::IsKeyPressed(GLFW_KEY_INSERT)) + crv_edt->add_key = true; + else if (del_key && ImGui::IsKeyPressed(GLFW_KEY_DELETE)) + crv_edt->del_key = true; + else if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT)) + crv_edt->frame++; + else if (ImGui::IsKeyPressed(GLFW_KEY_LEFT)) + crv_edt->frame--; + } + + bool exist = true; + if (crv_edt->add_key && add_key) { + if (!crv_edt->list[crv_edt->type] || !keys || !keys->size()) { + if (!crv_edt->list[crv_edt->type]) { + Glitter::Curve* c = new Glitter::Curve(eg->type); + crv_edt->animation->curves.push_back(curve); + crv_edt->list[crv_edt->type] = c; + curve = c; + } + + glitter_editor_curve_editor_curve_set(glt_edt, curve, crv_edt->type); + + if (!keys) + keys = &curve->keys_rev; + + Glitter::Curve::Key key; + key.frame = 0; + key.value = glitter_editor_curve_editor_get_value(glt_edt, curve->type); + keys->push_back(key); + + crv_edt->frame = 0; + changed = true; + } + else { + std::vector::iterator i = keys->begin(); + bool is_before_start = keys->data()[0].frame > crv_edt->frame; + bool has_key_after = false; + if (!is_before_start) + for (i++; i != keys->end(); i++) + if (crv_edt->frame <= i->frame) { + has_key_after = keys->end() - i > 0; + break; + } + + ssize_t pos = i - keys->begin(); + if (!is_before_start) + pos--; + + if (!is_before_start && has_key_after) { + std::vector::iterator c = i - 1; + std::vector::iterator n = i; + + Glitter::Curve::Key key; + key.frame = crv_edt->frame; + key.type = c->type; + switch (c->type) { + case Glitter::KEY_CONSTANT: + key.value = c->value; + key.random_range = c->random_range; + break; + case Glitter::KEY_LINEAR: { + float_t t = (float_t)(key.frame - c->frame) / (float_t)(n->frame - c->frame); + key.value = lerp_def(c->value, n->value, t); + key.random_range = lerp_def(c->random_range, n->random_range, t); + } break; + case Glitter::KEY_HERMITE: { + int32_t df = n->frame - c->frame; + int32_t _df = key.frame - c->frame; + std::vector v_arr = interpolate_chs(c->value, n->value, c->tangent2, n->tangent1, 0, df); + key.value = v_arr[_df]; + key.random_range = lerp_def(c->random_range, n->random_range, (float_t)_df / (float_t)df); + interpolate_chs_reverse(v_arr.data(), v_arr.size(), c->tangent2, key.tangent1, 0, _df); + interpolate_chs_reverse(v_arr.data(), v_arr.size(), key.tangent2, n->tangent1, _df, df); + } break; + } + keys->insert(keys->begin() + ++pos, key); + } + else if (is_before_start) { + std::vector::iterator n = i; + + Glitter::Curve::Key key; + key.frame = crv_edt->frame; + key.type = n->type; + key.value = n->value; + key.random_range = n->random_range; + keys->insert(keys->begin() + pos, key); + } + else { + std::vector::iterator c = i - 1; + + Glitter::Curve::Key key; + key.frame = crv_edt->frame; + key.type = c->type; + key.value = c->value; + key.random_range = c->random_range; + keys->insert(keys->begin() + ++pos, key); + } + *crv_edt->list[crv_edt->type] = *curve; + changed = true; + } + } + else if (keys && crv_edt->del_key && del_key) { + for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) + if (&i[0] == crv_edt->key) { + bool has_key_before = keys->front().frame < i->frame; + bool has_key_after = keys->back().frame > i->frame; + if (has_key_before && i[-1].type == Glitter::KEY_HERMITE && has_key_after) { + std::vector::iterator c = i - 1; + std::vector::iterator n = i + 1; + int32_t df_c = i->frame - c->frame; + int32_t df_n = n->frame - i->frame; + + std::vector v_arr_c = interpolate_chs(c->value, + i->value, c->tangent2, i->tangent1, 0, df_c); + + std::vector v_arr_n = i->type == Glitter::KEY_HERMITE + ? interpolate_chs(i->value, n->value, i->tangent2, n->tangent1, 0, df_n) + : interpolate_linear(i->value, n->value, 0, df_n); + + size_t v_length = v_arr_c.size() + v_arr_n.size() - 1; + float_t* v_arr = new float_t[v_length]; + memmove(v_arr, v_arr_c.data(), (v_arr_c.size() - 1) * sizeof(float_t)); + memmove(v_arr + (v_arr_c.size() - 1), v_arr_n.data(), v_arr_n.size() * sizeof(float_t)); + interpolate_chs_reverse(v_arr, v_length, c->tangent2, + n->tangent1, 0, (size_t)n->frame - c->frame); + delete[] v_arr; + } + keys->erase(i); + changed = true; + break; + } + } + else if (crv_edt->add_curve) { + Glitter::Curve* c = new Glitter::Curve(eg->type); + crv_edt->animation->curves.push_back(c); + crv_edt->list[crv_edt->type] = c; + curve = c; + + glitter_editor_curve_editor_curve_set(glt_edt, curve, crv_edt->type); + *crv_edt->list[crv_edt->type] = *curve; + crv_edt->frame = curve->start_time; + changed = true; + } + else if (crv_edt->del_curve) { + Glitter::Curve* c = crv_edt->list[crv_edt->type]; + Glitter::Animation* anim = crv_edt->animation; + for (std::vector::iterator i = anim->curves.begin(); i != anim->curves.end(); i++) + if (*i && *i == c) { + delete* i; + anim->curves.erase(i); + break; + } + + crv_edt->list[crv_edt->type] = 0; + crv_edt->frame = 0; + changed = true; + } + crv_edt->add_key = false; + crv_edt->del_key = false; + crv_edt->add_curve = false; + crv_edt->del_curve = false; + + if (!curve || !keys) + return; + + int32_t start_time = curve->start_time; + int32_t end_time = curve->end_time; + + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle& style = ImGui::GetStyle(); + ImFont* font = ImGui::GetFont(); + + ImVec2 cont_reg_avail = ImGui::GetContentRegionAvail(); + + ImVec2 canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max; + crv_edt->draw_list = ImGui::GetWindowDrawList(); + canvas_size = cont_reg_avail; + canvas_pos = ImGui::GetCursorScreenPos(); + canvas_pos_min.x = canvas_pos.x; + canvas_pos_min.y = canvas_pos.y; + canvas_pos_max.x = canvas_pos.x + canvas_size.x; + canvas_pos_max.y = canvas_pos.y + canvas_size.y; + + ImRect boundaries; + boundaries.Min = canvas_pos; + boundaries.Max.x = canvas_pos.x + canvas_size.x; + boundaries.Max.y = canvas_pos.y + canvas_size.y; + + if (crv_edt->zoom_time != crv_edt->prev_zoom_time) { + float_t timeline_pos = crv_edt->timeline_pos + curve_editor_timeline_base_pos; + timeline_pos *= crv_edt->zoom_time / crv_edt->prev_zoom_time; + crv_edt->timeline_pos = timeline_pos - curve_editor_timeline_base_pos; + } + crv_edt->prev_zoom_time = crv_edt->zoom_time; + + float_t frame_width = crv_edt->frame_width + * crv_edt->zoom_time; + canvas_pos.x -= crv_edt->timeline_pos; + + ImGui::ItemSize(boundaries); + bool hovered = ImGui::IsMouseHoveringRect(boundaries.Min, boundaries.Max); + ImGui::RenderFrame(boundaries.Min, boundaries.Max, ImGui::GetColorU32(ImGuiCol_FrameBg), true, 1.0f); + + static bool can_drag; + if (hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left, false)) + can_drag = true; + + if (can_drag && (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT))) { + crv_edt->key = glitter_editor_curve_editor_get_closest_key(glt_edt, curve); + crv_edt->frame = crv_edt->key->frame; + } + else + crv_edt->key = glitter_editor_curve_editor_get_selected_key(glt_edt, curve); + + if (can_drag && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + can_drag = false; + + float_t timeline_max_offset = (end_time - start_time) * frame_width; + timeline_max_offset = max_def(timeline_max_offset, 0.0f) - curve_editor_timeline_base_pos; + + crv_edt->draw_list->PushClipRect(boundaries.Min, boundaries.Max, true); + + int32_t start = (int32_t)(crv_edt->timeline_pos / frame_width) + start_time; + int32_t end = (int32_t)((crv_edt->timeline_pos + canvas_size.x) / frame_width) + start_time; + + ImU32 line_color_valid_bold = ImGui::GetColorU32({ 0.5f, 0.5f, 0.5f, 0.75f }); + ImU32 line_color_valid = ImGui::GetColorU32({ 0.4f, 0.4f, 0.4f, 0.45f }); + ImU32 line_color_not_valid = ImGui::GetColorU32({ 0.2f, 0.2f, 0.2f, 0.75f }); + for (int32_t frame = start; frame <= end; frame++) { + if (frame < start_time) + continue; + + int32_t f = frame - start_time; + float_t x = canvas_pos.x + f * frame_width; + float_t y = canvas_pos.y + (f % 2 ? 10.0f : 0.0f) + canvas_size.y; + + bool bold_frame = !(f % 10) || !f || frame == end_time; + bool valid_frame = f >= 0 && frame <= end_time; + + ImU32 line_color = valid_frame ? (bold_frame ? line_color_valid_bold + : line_color_valid) : line_color_not_valid; + crv_edt->draw_list->AddLine({ x, y - canvas_size.y }, + { x, y }, line_color, 0.80f); + + if (bold_frame) { + char buf[0x20]; + snprintf(buf, sizeof(buf), "%d", frame); + crv_edt->draw_list->AddText({ x + 3, canvas_pos.y }, line_color, buf); + } + } + + float_t max = crv_edt->range * (1.0f / crv_edt->zoom_value); + float_t min; + if (curve->type == Glitter::CURVE_EMISSION_INTERVAL) + min = -1.0f; + else if (curve->type == Glitter::CURVE_PARTICLES_PER_EMISSION) + min = 0.0f; + else + min = -max; + + for (int32_t j = 0; j < 5; j++) { + float_t x_pos = canvas_pos_min.x; + float_t y_pos = canvas_pos.y + j * 0.25f * (canvas_size.y + - crv_edt->height_offset) + crv_edt->height_offset; + + ImU32 line_color = j % 2 == 1 + ? ImGui::GetColorU32({ 0.35f, 0.35f, 0.35f, 0.45f }) + : ImGui::GetColorU32({ 0.45f, 0.45f, 0.45f, 0.75f }); + bool last = j == 4; + if (j && !last) + crv_edt->draw_list->AddLine({ x_pos, y_pos }, + { x_pos + canvas_size.x, y_pos }, line_color, 0.80f); + + float_t val = max - j * 0.25f * (max - min); + char buf[0x20]; + snprintf(buf, sizeof(buf), "%.2f", val); + crv_edt->draw_list->AddText({ x_pos + 2, y_pos + (last ? -16 : -2) }, + ImGui::GetColorU32({ 0.65f, 0.65f, 0.65f, 0.85f }), buf); + } + + if (curve->type >= Glitter::CURVE_ROTATION_X && curve->type <= Glitter::CURVE_ROTATION_Z) { + max *= DEG_TO_RAD_FLOAT; + min *= DEG_TO_RAD_FLOAT; + } + else if (curve->type >= Glitter::CURVE_COLOR_R && curve->type <= Glitter::CURVE_COLOR_RGB_SCALE_2ND) { + max *= (float_t)(1.0 / 255.0); + min *= (float_t)(1.0 / 255.0); + } + + float_t base_line = convert_value_to_height(glt_edt, 0.0f, canvas_pos.y, canvas_size.y, min, max); + + ImVec2 p1, p2, p3; + p1.x = canvas_pos_min.x; + p1.y = canvas_pos.y + crv_edt->height_offset; + p2.x = p1.x + canvas_size.x; + p2.y = canvas_pos.y + crv_edt->height_offset; + p3.x = canvas_pos_min.x; + p3.y = canvas_pos.y; + crv_edt->draw_list->AddLine(p1, p2, + ImGui::GetColorU32({ 0.5f, 0.5f, 0.5f, 0.85f }), 2.0f); + + ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); + ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); + ImU32 default_color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.75f }); + ImU32 selected_color = ImGui::GetColorU32({ 0.0f, 1.0f, 1.0f, 0.75f }); + + if (curve->flags & Glitter::CURVE_RANDOM_RANGE + || curve->flags & Glitter::CURVE_KEY_RANDOM_RANGE) { + float_t random_range = curve->random_range; + bool random_range_mult = curve->flags & Glitter::CURVE_RANDOM_RANGE_MULT; + bool random_range_negate = curve->flags & Glitter::CURVE_RANDOM_RANGE_NEGATE; + bool glt_type_ft = eg->type == Glitter::FT; + for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { + if (i->frame >= end_time || keys->end() - i <= 1) + break; + + std::vector::iterator c = i; + std::vector::iterator n = i + 1; + float_t x1 = canvas_pos.x + (float_t)(c->frame - start_time) * frame_width; + float_t x2 = canvas_pos.x + (float_t)(n->frame - start_time) * frame_width; + + if (((x1 < canvas_pos_min.x) && (x2 < canvas_pos_min.x)) || + (x1 > canvas_pos_max.x) && (x2 > canvas_pos_max.x)) + continue; + + x1 = max_def(x1, canvas_pos_min.x); + x2 = min_def(x2, canvas_pos_max.x); + + Glitter::KeyType k_type = c->type; + float_t c_frame = (float_t)c->frame; + float_t n_frame = (float_t)n->frame; + float_t c_value = c->value; + float_t n_value = n->value; + if (fix_rot_z) { + c_value -= (float_t)M_PI_2; + n_value -= (float_t)M_PI_2; + } + float_t c_random_range = c->random_range; + float_t n_random_range = n->random_range; + if (random_range_mult && glt_type_ft) { + c_random_range *= c_value; + n_random_range *= n_value; + } + + size_t frame_width_int = (size_t)roundf(frame_width); + if (k_type == Glitter::KEY_CONSTANT) { + vec3 value = { c_value + c_random_range, c_value, c_value - c_random_range }; + vec3 random = { random_range, random_range, random_range }; + if (random_range_mult) { + random *= value; + if (!glt_type_ft) + random *= 0.01f; + } + + if (value.x != value.y) { + float_t y1 = convert_value_to_height(glt_edt, value.x + random.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y3 = convert_value_to_height(glt_edt, value.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y4 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddRectFilled({ x1, y1 }, + { x2, y2 }, random_range_color, 0.0f, 0); + + y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); + y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); + if (y3 != y4) + crv_edt->draw_list->AddRectFilled({ x1, y3 }, + { x2, y4 }, key_random_range_color, 0.0f, 0); + } + else { + float_t y1 = convert_value_to_height(glt_edt, value.y + random.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddRectFilled({ x1, y1 }, + { x2, y2 }, random_range_color, 0.0f, 0); + } + + if (random_range_negate) + if (value.y != value.z) { + float_t y1 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.z, + canvas_pos.y, canvas_size.y, min, max); + float_t y3 = convert_value_to_height(glt_edt, value.z, + canvas_pos.y, canvas_size.y, min, max); + float_t y4 = convert_value_to_height(glt_edt, value.z - random.z, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddRectFilled({ x1, y1 }, + { x2, y2 }, key_random_range_color, 0.0f, 0); + + y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); + y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); + if (y3 != y4) + crv_edt->draw_list->AddRectFilled({ x1, y3 }, + { x2, y4 }, random_range_color, 0.0f, 0); + } + else { + float_t y1 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.y - random.y, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddRectFilled({ x1, y1 }, + { x2, y2 }, random_range_color, 0.0f, 0); + } + } + else { + float_t c_tangent2 = c->tangent2; + float_t n_tangent1 = n->tangent1; + + vec3 c_frame_vec = { c_frame, c_frame, c_frame }; + vec3 n_frame_vec = { n_frame, n_frame, n_frame }; + vec3 c_value_vec = { c_value + c_random_range, c_value, c_value - c_random_range }; + vec3 n_value_vec = { n_value + n_random_range, n_value, n_value - n_random_range }; + vec3 random_vec = { random_range, random_range, random_range }; + vec3 c_tangent2_vec = { c_tangent2, c_tangent2, c_tangent2 }; + vec3 n_tangent1_vec = { n_tangent1, n_tangent1, n_tangent1 }; + for (size_t i = c->frame; i < n->frame; i++) + for (size_t j = 0; j < frame_width_int; j++) { + float_t frame = (float_t)i + (float_t)j / frame_width; + vec3 frame_vec = { frame, frame, frame }; + + vec3 value; + if (k_type != Glitter::KEY_HERMITE) + value = interpolate_linear_value(c_value_vec, n_value_vec, + c_frame_vec, n_frame_vec, frame_vec); + else + value = interpolate_chs_value(c_value_vec, n_value_vec, + c_tangent2_vec, n_tangent1_vec, c_frame_vec, n_frame_vec, frame_vec); + + vec3 random; + if (random_range_mult) { + random_vec *= value; + if (!glt_type_ft) + random *= 0.01f; + } + else + random = random_vec; + + if (random_range_mult) { + vec3 random = { random_range, random_range, random_range }; + random *= value; + if (!glt_type_ft) + random *= 0.01f; + } + + float_t x = canvas_pos.x + + (float_t)(i - start_time) * frame_width + (float_t)j; + if (value.x != value.y) { + float_t y1 = convert_value_to_height(glt_edt, value.x + random.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y3 = convert_value_to_height(glt_edt, value.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y4 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddLine({ x, y1 }, + { x, y2 }, random_range_color, 0.0f); + + y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); + y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); + if (y3 != y4) + crv_edt->draw_list->AddLine({ x, y3 }, + { x, y4 }, key_random_range_color, 0.0f); + } + else { + float_t y1 = convert_value_to_height(glt_edt, value.y + random.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddLine({ x, y1 }, + { x, y2 }, random_range_color, 0.0f); + } + + if (random_range_negate) + if (value.y != value.z) { + float_t y1 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.z, + canvas_pos.y, canvas_size.y, min, max); + float_t y3 = convert_value_to_height(glt_edt, value.z, + canvas_pos.y, canvas_size.y, min, max); + float_t y4 = convert_value_to_height(glt_edt, value.z - random.z, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddLine({ x, y1 }, + { x, y2 }, key_random_range_color, 0.0f); + + y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); + y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); + if (y3 != y4) + crv_edt->draw_list->AddLine({ x, y3 }, + { x, y4 }, random_range_color, 0.0f); + } + else { + float_t y1 = convert_value_to_height(glt_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, value.y - random.y, + canvas_pos.y, canvas_size.y, min, max); + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + crv_edt->draw_list->AddLine({ x, y1 }, + { x, y2 }, random_range_color, 0.0f); + } + } + } + } + } + + for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { + if (i->frame >= end_time || keys->end() - i <= 1) + break; + + std::vector::iterator c = i; + std::vector::iterator n = i + 1; + float_t x1 = canvas_pos.x + (float_t)(c->frame - start_time) * frame_width; + float_t x2 = canvas_pos.x + (float_t)(n->frame - start_time) * frame_width; + + if (((x1 < canvas_pos_min.x) && (x2 < canvas_pos_min.x)) || + (x1 > canvas_pos_max.x) && (x2 > canvas_pos_max.x)) + continue; + + float_t c_value = c->value; + float_t n_value = n->value; + + if (fix_rot_z) { + c_value -= (float_t)M_PI_2; + n_value -= (float_t)M_PI_2; + } + + if (i->type != Glitter::KEY_HERMITE) { + float_t y1 = convert_value_to_height(glt_edt, c_value, canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(glt_edt, n_value, canvas_pos.y, canvas_size.y, min, max); + + if (i->type == Glitter::KEY_CONSTANT) { + int32_t count = 0; + ImVec2 points_temp[3]; + if (x1 != x2) + points_temp[count++] = { x1, y1 }; + points_temp[count++] = { x2, y1 }; + if (y1 != y2) + points_temp[count++] = { x2, y2 }; + + if (count > 1) + crv_edt->draw_list->AddPolyline(points_temp, + count, default_color, 0, 3.0f); + } + else + crv_edt->draw_list->AddLine({ x1, y1 }, { x2, y2 }, default_color, 3.0f); + } + else { + float_t c_frame = (float_t)c->frame; + float_t n_frame = (float_t)n->frame; + float_t c_tangent2 = (float_t)c->tangent2; + float_t n_tangent1 = (float_t)n->tangent1; + size_t frame_width_int = (size_t)roundf(frame_width); + size_t points_count = ((size_t)n_frame - (size_t)c_frame) * frame_width_int; + ImVec2* points = force_malloc_s(ImVec2, points_count); + for (size_t i = c->frame; i < n->frame; i++) + for (size_t j = 0; j < frame_width_int; j++) { + float_t value = interpolate_chs_value(c_value, n_value, c_tangent2, n_tangent1, + c_frame, n_frame, (float_t)i + (float_t)j / frame_width); + + ImVec2 point; + point.x = canvas_pos.x + + (float_t)(i - start_time) * frame_width + (float_t)j; + point.y = convert_value_to_height(glt_edt, value, + canvas_pos.y, canvas_size.y, min, max); + points[(i - c->frame) * frame_width_int + j] = point; + } + crv_edt->draw_list->AddPolyline(points, + (int32_t)points_count, default_color, 0, 3.0f); + free_def(points); + } + } + + const ImU32 key_constant_color = ImGui::GetColorU32({ 1.0f, 0.0f, 0.0f, 0.75f }); + const ImU32 key_linear_color = ImGui::GetColorU32({ 0.0f, 1.0f, 0.0f, 0.75f }); + const ImU32 key_hermite_color = ImGui::GetColorU32({ 0.0f, 0.0f, 1.0f, 0.75f }); + + bool dragged = false; + bool holding_tan = false; + for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { + if (!(i->frame >= start_time || i->frame <= end_time)) + continue; + else if (i - keys->begin() > 1) + if (i->frame < start_time && i[1].frame < start_time) + continue; + else if (i->frame > end_time && i[-1].frame > end_time) + continue; + + float_t base_value = i->value; + if (fix_rot_z) + base_value -= (float_t)M_PI_2; + float_t x = canvas_pos.x + ((size_t)i->frame - start_time) * frame_width; + float_t y = convert_value_to_height(glt_edt, base_value, canvas_pos.y, canvas_size.y, min, max); + + if (!(x >= p3.x - 10.0f && x <= p3.x + canvas_size.x + 10.0f) + || !(y >= p3.y - 10.0f && y <= p3.y + canvas_size.y + 10.0f)) + continue; + + ImU32 value_color; + switch (i->type) { + case Glitter::KEY_CONSTANT: + value_color = key_constant_color; + break; + case Glitter::KEY_LINEAR: + default: + value_color = key_linear_color; + break; + case Glitter::KEY_HERMITE: + value_color = key_hermite_color; + break; + } + + ImGui::PushID(i._Ptr); + ImGui::SetCursorScreenPos({ x - 7.5f, y - 7.5f }); + ImGui::InvisibleButton("val", { 15.0f, 15.0f }, 0); + + if (can_drag && ImGui::IsItemActive() + && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f)) { + float_t old_y = y; + + static int32_t base_frame; + static float_t base_y; + if ((ImGui::IsKeyPressed(GLFW_KEY_LEFT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) + || (ImGui::IsKeyPressed(GLFW_KEY_RIGHT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT))) { + base_frame = i->frame; + base_y = base_value; + } + + if (i->frame >= start_time && i->frame <= end_time) { + int32_t start = i - keys->begin() > 0 ? (i - 1)->frame + 1 : start_time; + int32_t end = keys->end() - i > 1 ? (i + 1)->frame - 1 : end_time; + crv_edt->frame = (int32_t)roundf((io.MousePos.x - canvas_pos.x) / frame_width); + crv_edt->frame = clamp_def(crv_edt->frame + start_time, start, end); + if (i->frame != crv_edt->frame) { + i->frame = crv_edt->frame; + changed = true; + } + } + + static float_t mouse_delta_history; + if ((ImGui::IsKeyPressed(GLFW_KEY_LEFT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) + || (ImGui::IsKeyPressed(GLFW_KEY_RIGHT_SHIFT, false) && !ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT))) + mouse_delta_history = io.MouseDelta.y; + else if ((ImGui::IsKeyReleased(GLFW_KEY_LEFT_SHIFT) && !ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) + || ImGui::IsKeyReleased(GLFW_KEY_RIGHT_SHIFT) && !ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT)) { + y += mouse_delta_history; + y += io.MouseDelta.y; + } + else if (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) + mouse_delta_history += io.MouseDelta.y; + else + y += io.MouseDelta.y; + + if (old_y != y) { + float_t value = convert_height_to_value(glt_edt, + y, canvas_pos.y, canvas_size.y, min, max); + dragged = true; + + if (base_value != value) { + if (fix_rot_z) + value += (float_t)M_PI_2; + i->value = value; + changed = true; + } + crv_edt->key = &i[0]; + } + } + + if (i - keys->begin() > 0 && (i - 1)->type == Glitter::KEY_HERMITE) { + ImU32 tangent1_color; + float_t tangent1; + ImVec2 circle_pos; + circle_pos.x = x - 25.0f; + circle_pos.y = y - base_line + convert_value_to_height(glt_edt, tangent1 = i->tangent1, + canvas_pos.y, canvas_size.y, min, max); + crv_edt->draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); + + if ((circle_pos.x >= p3.x - 10.0f && circle_pos.x <= p3.x + canvas_size.x + 10.0f) + && (circle_pos.y >= p3.y - 10.0f && circle_pos.y <= p3.y + canvas_size.y + 10.0f)) { + ImGui::SetCursorScreenPos({ circle_pos.x - 7.5f, circle_pos.y - 7.5f }); + ImGui::InvisibleButton("tan1", { 15.0f, 15.0f }, 0); + + if (can_drag && ImGui::IsItemActive()) { + if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { + i->tangent1 = convert_height_to_value(glt_edt, + circle_pos.y + io.MouseDelta.y - y + base_line, + canvas_pos.y, canvas_size.y, min, max); + + if (i->tangent1 != tangent1) + changed = true; + } + holding_tan = true; + tangent1_color = selected_color; + } + else + tangent1_color = default_color; + + crv_edt->draw_list->AddCircleFilled(circle_pos, + crv_edt->key_radius_in, tangent1_color, 12); + } + } + + if (keys->end() - i > 1 && i->type == Glitter::KEY_HERMITE) { + ImU32 tangent2_color; + float_t tangent2; + ImVec2 circle_pos; + circle_pos.x = x + 25.0f; + circle_pos.y = y - base_line + convert_value_to_height(glt_edt, tangent2 = i->tangent2, + canvas_pos.y, canvas_size.y, min, max); + crv_edt->draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); + + if ((circle_pos.x >= p3.x - 10.0f && circle_pos.x <= p3.x + canvas_size.x + 10.0f) + && (circle_pos.y >= p3.y - 10.0f && circle_pos.y <= p3.y + canvas_size.y + 10.0f)) { + ImGui::SetCursorScreenPos({ circle_pos.x - 7.5f, circle_pos.y - 7.5f }); + ImGui::InvisibleButton("tan2", { 15.0f, 15.0f }, 0); + + if (can_drag && ImGui::IsItemActive()) { + if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { + i->tangent2 = convert_height_to_value(glt_edt, + circle_pos.y + io.MouseDelta.y - y + base_line, + canvas_pos.y, canvas_size.y, min, max); + + if (i->tangent2 != tangent2) + changed = true; + } + holding_tan = true; + tangent2_color = selected_color; + } + else + tangent2_color = default_color; + + crv_edt->draw_list->AddCircleFilled(circle_pos, + crv_edt->key_radius_in, tangent2_color, 12); + } + } + + crv_edt->draw_list->AddCircleFilled({ x, y }, + crv_edt->key_radius_out, crv_edt->key == &i[0] ? selected_color : default_color, 12); + crv_edt->draw_list->AddCircleFilled({ x, y }, + crv_edt->key_radius_in, value_color, 12); + ImGui::PopID(); + } + + if (!crv_edt->key_edit && can_drag && ImGui::IsMouseDown(ImGuiMouseButton_Left) && (!holding_tan || dragged)) { + int32_t frame = (int32_t)roundf((io.MousePos.x - canvas_pos.x) / frame_width); + crv_edt->frame = clamp_def(frame + start_time, start_time, end_time); + if (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) { + crv_edt->key = glitter_editor_curve_editor_get_closest_key(glt_edt, curve); + crv_edt->frame = crv_edt->key->frame; + } + else + crv_edt->key = glitter_editor_curve_editor_get_selected_key(glt_edt, curve); + } + crv_edt->frame = clamp_def(crv_edt->frame, start_time, end_time); + + int32_t cursor_frame = crv_edt->frame - start_time; + ImVec2 cursor_pos = canvas_pos; + cursor_pos.x += cursor_frame * frame_width; + if (cursor_pos.x >= p1.x - 10.0f && cursor_pos.x <= p1.x + canvas_size.x + 10.0f) { + ImU32 cursor_color = ImGui::GetColorU32({ 0.8f, 0.8f, 0.8f, 0.75f }); + p1.x = cursor_pos.x; + p1.y = canvas_pos.y + canvas_size.y; + crv_edt->draw_list->AddLine(cursor_pos, p1, cursor_color, 2.5f); + + p1 = p2 = p3 = cursor_pos; + p1.x -= 10.0f; + p2.y += 10.0f; + p3.x += 10.0f; + crv_edt->draw_list->AddTriangleFilled(p1, p2, p3, cursor_color); + } + crv_edt->draw_list->PopClipRect(); + + if (hovered) + if (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) + crv_edt->timeline_pos -= io.MouseWheel * 25.0f * 4.0f; + else + crv_edt->timeline_pos -= io.MouseWheel * 25.0f; + + crv_edt->timeline_pos = clamp_def(crv_edt->timeline_pos, + -curve_editor_timeline_base_pos, timeline_max_offset); + + if (crv_edt->list[crv_edt->type] && changed) { + curve->Recalculate(eg->type); + *crv_edt->list[crv_edt->type] = *curve; + glt_edt->input_reload = true; + } +} + static bool glitter_editor_hash_input(GlitterEditor* glt_edt, const char* label, uint64_t* hash) { uint64_t h = *hash; if (glt_edt->effect_group->type == Glitter::FT) { diff --git a/src/ReDIVA/classes/graphics.cpp b/src/ReDIVA/classes/graphics.cpp index 60a47fac..920551eb 100644 --- a/src/ReDIVA/classes/graphics.cpp +++ b/src/ReDIVA/classes/graphics.cpp @@ -39,7 +39,7 @@ classes_data graphics_classes[] = { "Light##Graphics", CLASSES_IN_CONTEXT_MENU, graphics_light_init, - CLASSES_DATA_NO_FUNC, + graphics_light_ctrl, CLASSES_DATA_NO_FUNC, CLASSES_DATA_NO_FUNC, CLASSES_DATA_NO_FUNC, diff --git a/src/ReDIVA/classes/graphics/background_color.cpp b/src/ReDIVA/classes/graphics/background_color.cpp index 58ceee94..39620181 100644 --- a/src/ReDIVA/classes/graphics/background_color.cpp +++ b/src/ReDIVA/classes/graphics/background_color.cpp @@ -23,8 +23,8 @@ void graphics_background_color_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 360.0f); - float_t h = min((float_t)height, 100.0f); + float_t w = min_def((float_t)width, 360.0f); + float_t h = min_def((float_t)height, 100.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); @@ -53,10 +53,9 @@ void graphics_background_color_imgui(class_data* data) { ImGui::GetContentRegionAvailSetNextItemWidth(); vec4 _clear_color; vec4u8_to_vec4(clear_color, _clear_color); - vec4_mult_scalar(_clear_color, (float_t)(1.0 / 255.0), _clear_color); + _clear_color *= (float_t)(1.0 / 255.0); if (ImGui::ColorEdit4("##Background Color", (float_t*)&_clear_color, color_edit_flags)) { - vec4_clamp_scalar(_clear_color, 0.0f, 1.0f, _clear_color); - vec4_mult_scalar(_clear_color, 255.0f, _clear_color); + _clear_color = vec4::clamp(_clear_color, 0.0f, 1.0f) * 255.0f; vec4_to_vec4u8(_clear_color, clear_color); } ImGui::Checkbox("Set Clear Color", &set_clear_color); diff --git a/src/ReDIVA/classes/graphics/face_light.cpp b/src/ReDIVA/classes/graphics/face_light.cpp index dd932709..2092c202 100644 --- a/src/ReDIVA/classes/graphics/face_light.cpp +++ b/src/ReDIVA/classes/graphics/face_light.cpp @@ -24,8 +24,8 @@ void graphics_face_light_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 200.0f); - float_t h = min((float_t)height, 84.0f); + float_t w = min_def((float_t)width, 200.0f); + float_t h = min_def((float_t)height, 84.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); @@ -47,21 +47,22 @@ void graphics_face_light_imgui(class_data* data) { } render_context* rctx = (render_context*)data->data; - face* face = &rctx->face; + if (!rctx) { + ImGui::End(); + return; + } - ImGuiColorEditFlags color_edit_flags = 0; - color_edit_flags |= ImGuiColorEditFlags_NoLabel; - color_edit_flags |= ImGuiColorEditFlags_NoSidePreview; - color_edit_flags |= ImGuiColorEditFlags_NoDragDrop; + face* face = &rctx->face; w = ImGui::GetContentRegionAvailWidth(); if (ImGui::ButtonEnterKeyPressed("Reset", { w, 0.0f })) - light_param_data_storage_data_set_default_light_param(LIGHT_PARAM_DATA_STORAGE_FACE); + light_param_data_storage_data_set_stage( + light_param_data_storage_data_get_stage_index(), LIGHT_PARAM_DATA_STORAGE_FACE); ImGui::GetContentRegionAvailSetNextItemWidth(); float_t strength = face->get_offset(); if (ImGui::ColumnSliderFloatButton("Strength", - &strength, 0.25f, 0.0f, 10.0f, 1.0f, "%5.2f", color_edit_flags)) + &strength, 0.25f, 0.0f, 10.0f, 1.0f, "%5.2f", 0)) face->set_offset(strength); data->imgui_focus |= ImGui::IsWindowFocused(); @@ -69,5 +70,6 @@ void graphics_face_light_imgui(class_data* data) { } bool graphics_face_light_dispose(class_data* data) { + data->data = 0; return true; } diff --git a/src/ReDIVA/classes/graphics/fog.cpp b/src/ReDIVA/classes/graphics/fog.cpp index 7b0a6423..8549081f 100644 --- a/src/ReDIVA/classes/graphics/fog.cpp +++ b/src/ReDIVA/classes/graphics/fog.cpp @@ -4,10 +4,16 @@ */ #include "fog.hpp" -#include "../../../KKdLib/vec.hpp" -#include "../../../CRE/clear_color.hpp" #include "../../imgui_helper.hpp" +struct data_view_fog { + render_context* rctx; + int32_t group; + + data_view_fog(); + virtual ~data_view_fog(); +}; + extern int32_t width; extern int32_t height; @@ -15,7 +21,10 @@ static const char* graphics_fog_window_title = "Fog##Graphics"; bool graphics_fog_init(class_data* data, render_context* rctx) { graphics_fog_dispose(data); - data->data = rctx; + data_view_fog* fog = new data_view_fog; + if (fog) + fog->rctx = rctx; + data->data = fog; return true; } @@ -24,18 +33,15 @@ void graphics_fog_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 200.0f); - float_t h = min((float_t)height, 84.0f); + float_t w = min_def((float_t)width, 300.0f); + float_t h = min_def((float_t)height, 344.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); - ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); - - ImGuiWindowFlags window_flags = 0; - window_flags |= ImGuiWindowFlags_NoResize; + ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); data->imgui_focus = false; bool open = data->flags & CLASS_HIDDEN ? false : true; - bool collapsed = !ImGui::Begin(graphics_fog_window_title, &open, window_flags); + bool collapsed = !ImGui::Begin(graphics_fog_window_title, &open, 0); if (!open) { enum_or(data->flags, CLASS_HIDE); ImGui::End(); @@ -46,16 +52,75 @@ void graphics_fog_imgui(class_data* data) { return; } - render_context* rctx = (render_context*)data->data; - fog* fog = rctx->fog; + data_view_fog* fog = (data_view_fog*)data->data; + if (!fog) { + ImGui::End(); + return; + } - ImGuiColorEditFlags color_edit_flags = 0; - color_edit_flags |= ImGuiColorEditFlags_NoLabel; - color_edit_flags |= ImGuiColorEditFlags_NoSidePreview; - color_edit_flags |= ImGuiColorEditFlags_NoDragDrop; + render_context* rctx = fog->rctx; + ::fog* fog_data = &rctx->fog[fog->group]; if (ImGui::ButtonEnterKeyPressed("Reset")) - light_param_data_storage_data_set_default_light_param(LIGHT_PARAM_DATA_STORAGE_FOG); + light_param_data_storage_data_set_stage( + light_param_data_storage_data_get_stage_index(), LIGHT_PARAM_DATA_STORAGE_FOG); + + const char* fog_group_labels[] = { + "0: DEPTH", + "1: HEIGHT", + "2: BUMP", + }; + + ImGui::TextCentered("GROUP"); + ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::ComboBox("##Group", fog_group_labels, 3, + &fog->group, 0, false, &data->imgui_focus); + + const char* fog_type_labels[] = { + "NONE", + "LINEAR", + "EXP", + "EXP2", + }; + + ImGui::TextCentered("TYPE"); + + fog_type type = fog_data->get_type(); + ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::ComboBox("##Type", fog_type_labels, FOG_EXP2, + (int32_t*)&type, 0, true, &data->imgui_focus); + fog_data->set_type(type); + + ImGui::TextCentered("DENSITY"); + + float_t density = fog_data->get_density(); + ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::SliderFloatButton("##Density", &density, 0.01f, 0.0f, 1.0f, 0.1f, "%.3f", 0); + fog_data->set_density(density); + + ImGui::TextCentered("LINEAR"); + + ImGui::PushID("Linear"); + float_t start = fog_data->get_start(); + ImGui::ColumnSliderFloatButton("START", &start, 0.1f, -100.0f, 1000.0f, 1.0f, "%.2f", 0); + fog_data->set_start(start); + + float_t end = fog_data->get_end(); + ImGui::ColumnSliderFloatButton("END", &end, 0.1f, -100.0f, 1000.0f, 1.0f, "%.2f", 0); + fog_data->set_end(end); + ImGui::PopID(); + + ImGui::TextCentered("COLOR"); + + ImGui::PushID("Color"); + vec4 color; + fog_data->get_color(color); + ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::ColumnSliderFloatButton("R", &color.x, 0.01f, 0.0f, 8.0f, 0.1f, "%.2f", 0); + ImGui::ColumnSliderFloatButton("G", &color.y, 0.01f, 0.0f, 8.0f, 0.1f, "%.2f", 0); + ImGui::ColumnSliderFloatButton("B", &color.z, 0.01f, 0.0f, 8.0f, 0.1f, "%.2f", 0); + fog_data->set_color(color); + ImGui::PopID(); ImGui::GetContentRegionAvailSetNextItemWidth(); @@ -64,5 +129,17 @@ void graphics_fog_imgui(class_data* data) { } bool graphics_fog_dispose(class_data* data) { + data_view_fog* fog = (data_view_fog*)data->data; + if (fog) + delete fog; + data->data = 0; return true; } + +data_view_fog::data_view_fog() : rctx(), group() { + +} + +data_view_fog::~data_view_fog() { + +} diff --git a/src/ReDIVA/classes/graphics/glitter.cpp b/src/ReDIVA/classes/graphics/glitter.cpp index d564b283..33342163 100644 --- a/src/ReDIVA/classes/graphics/glitter.cpp +++ b/src/ReDIVA/classes/graphics/glitter.cpp @@ -20,8 +20,8 @@ bool graphics_glitter_init(class_data* data, render_context* rctx) { } void graphics_glitter_imgui(class_data* data) { - float_t w = min((float_t)width / 4.0f, 148.0f); - float_t h = min((float_t)height, 204.0f); + float_t w = min_def((float_t)width / 4.0f, 148.0f); + float_t h = min_def((float_t)height, 204.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); diff --git a/src/ReDIVA/classes/graphics/light.cpp b/src/ReDIVA/classes/graphics/light.cpp index 173459b4..814e6f95 100644 --- a/src/ReDIVA/classes/graphics/light.cpp +++ b/src/ReDIVA/classes/graphics/light.cpp @@ -4,10 +4,23 @@ */ #include "light.hpp" -#include "../../../KKdLib/vec.hpp" -#include "../../../CRE/clear_color.hpp" +#include "../../../CRE/stage.hpp" #include "../../imgui_helper.hpp" +struct data_view_light { + render_context* rctx; + light_id id; + bool sync_pos; + bool light_auth_enable; + int32_t stage_index; + int32_t stage_index_prev; + + data_view_light(); + virtual ~data_view_light(); + + static void column_slider_float_button(const char* label, float_t* val); +}; + extern int32_t width; extern int32_t height; @@ -15,27 +28,49 @@ static const char* graphics_light_window_title = "Light##Graphics"; bool graphics_light_init(class_data* data, render_context* rctx) { graphics_light_dispose(data); - data->data = rctx; + + data_view_light* light = new data_view_light; + if (light) { + light->rctx = rctx; + + int32_t stage_index = task_stage_get_current_stage_index(); + stage_index = max_def(stage_index, 0); + light->stage_index = stage_index; + light->stage_index_prev = stage_index; + } + data->data = light; return true; } +void graphics_light_ctrl(class_data* data) { + if (data->flags & (CLASS_HIDE | CLASS_HIDDEN)) + return; + + data_view_light* light = (data_view_light*)data->data; + if (!light) + return; + + if (light->stage_index != light->stage_index_prev + && !light_param_data_storage_data_load_file()) { + light->stage_index_prev = light->stage_index; + light_param_data_storage_data_set_stage(light->stage_index); + } +} + void graphics_light_imgui(class_data* data) { ImGuiIO& io = ImGui::GetIO(); ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 200.0f); - float_t h = min((float_t)height, 84.0f); + float_t w = min_def((float_t)width, 464.0f); + float_t h = min_def((float_t)height, 604.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); - ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); - - ImGuiWindowFlags window_flags = 0; - window_flags |= ImGuiWindowFlags_NoResize; + ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); data->imgui_focus = false; bool open = data->flags & CLASS_HIDDEN ? false : true; - bool collapsed = !ImGui::Begin(graphics_light_window_title, &open, window_flags); + bool collapsed = !ImGui::Begin(graphics_light_window_title, &open, 0); if (!open) { enum_or(data->flags, CLASS_HIDE); ImGui::End(); @@ -46,23 +81,240 @@ void graphics_light_imgui(class_data* data) { return; } - render_context* rctx = (render_context*)data->data; + data_view_light* light = (data_view_light*)data->data; + if (!light) { + ImGui::End(); + return; + } + + render_context* rctx = light->rctx; + + data_struct* aft_data = &data_list[DATA_AFT]; + stage_database* aft_stage_data = &aft_data->data_ft.stage_data; + + std::vector& stg_data = aft_stage_data->stage_data; + light_set* light_set = rctx->light_set; - ImGuiColorEditFlags color_edit_flags = 0; - color_edit_flags |= ImGuiColorEditFlags_NoLabel; - color_edit_flags |= ImGuiColorEditFlags_NoSidePreview; - color_edit_flags |= ImGuiColorEditFlags_NoDragDrop; + int32_t stage_index = light_param_data_storage_data_get_stage_index(); - if (ImGui::ButtonEnterKeyPressed("Reset")) - light_param_data_storage_data_set_default_light_param(LIGHT_PARAM_DATA_STORAGE_LIGHT); + int32_t _stage_index = stage_index < 0 ? light->stage_index : stage_index; + + ImGui::TextCentered("STAGE (Light/Fog/PP)"); ImGui::GetContentRegionAvailSetNextItemWidth(); + if (ImGui::BeginCombo("##Stage Index", _stage_index > -1 + ? stg_data[_stage_index].name.c_str() : "", 0)) { + for (stage_data& i : stg_data) { + int32_t stage_idx = (int32_t)(&i - stg_data.data()); + + ImGui::PushID(&i); + if (ImGui::Selectable(i.name.c_str(), _stage_index == stage_idx) + || ImGui::ItemKeyPressed(GLFW_KEY_ENTER, true) + || (ImGui::IsItemFocused() && _stage_index != stage_idx)) { + stage_index = -1; + _stage_index = stage_idx; + } + ImGui::PopID(); + + if (_stage_index == stage_idx) + ImGui::SetItemDefaultFocus(); + } + + data->imgui_focus |= ImGui::IsWindowFocused(); + ImGui::EndCombo(); + } + + ::light_data* light_data = &light_set->lights[light->id]; + + const char* light_id_labels[] = { + "0:CHARA", + "1:STAGE", + "2:SUN", + "3:REFLECT", + "4:SHADOW", + "5:CHARA COLOR", + "6:CHARA(F)", + "7:PROJECTION", + }; + + ImGui::TextCentered("ID"); + + ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::ComboBox("##ID", light_id_labels, LIGHT_MAX, + (int32_t*)&light->id, 0, false, &data->imgui_focus); + + const char* light_type_labels[] = { + "OFF", + "PARALLEL", + "POINT", + "SPOT", + }; + + ImGui::TextCentered("TYPE"); + + light_type type = light_data->get_type(); + ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::ComboBox("##Type", light_type_labels, LIGHT_SPOT, + (int32_t*)&type, 0, true, &data->imgui_focus); + light_data->set_type(type); + + if (light->id == LIGHT_CHARA || light->id == LIGHT_TONE_CURVE) { + ::light_data* light_data = &light_set->lights[LIGHT_TONE_CURVE]; + + ImGui::TextCentered("CHARA(F) Tone Curve Adjustment"); + + ImGui::PushID("Tone Curve"); + light_tone_curve tone_curve; + light_data->get_tone_curve(tone_curve); + ImGui::ColumnSliderFloatButton("Start Point", &tone_curve.start_point, 0.01f, 0.0f, 1.0f, 0.1f, "%4.2f", 0); + ImGui::ColumnSliderFloatButton("End Point", &tone_curve.end_point, 0.01f, 0.0f, 1.0f, 0.1f, "%4.2f", 0); + ImGui::ColumnSliderFloatButton("Coefficient", &tone_curve.coefficient, 0.01f, 0.0f, 1.0f, 0.1f, "%4.2f", 0); + light_data->set_tone_curve(tone_curve); + ImGui::PopID(); + + ImGui::Checkbox("Light 0-6 Sync Position", &light->sync_pos); + ImGui::Checkbox("Light Auth Enable", &light->light_auth_enable); + } + + if (light_data->type != LIGHT_OFF) { + ImGui::TextCentered("AMBIENT"); + + ImGui::PushID("Ambient"); + vec4 ambient; + light_data->get_ambient(ambient); + ImGui::ColumnSliderFloatButton("R", &ambient.x, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + ImGui::ColumnSliderFloatButton("G", &ambient.y, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + ImGui::ColumnSliderFloatButton("B", &ambient.z, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + light_data->set_ambient(ambient); + ImGui::PopID(); + + ImGui::TextCentered("DIFFUSE"); + + ImGui::PushID("Diffuse"); + vec4 diffuse; + light_data->get_diffuse(diffuse); + ImGui::ColumnSliderFloatButton("R", &diffuse.x, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + ImGui::ColumnSliderFloatButton("G", &diffuse.y, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + ImGui::ColumnSliderFloatButton("B", &diffuse.z, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + light_data->set_diffuse(diffuse); + ImGui::PopID(); + + ImGui::TextCentered("SPECULAR"); + + ImGui::PushID("Specular"); + vec4 specular; + light_data->get_specular(specular); + ImGui::ColumnSliderFloatButton("R", &specular.x, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + ImGui::ColumnSliderFloatButton("G", &specular.y, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + ImGui::ColumnSliderFloatButton("B", &specular.z, 0.01f, 0.0f, 2.0f, 0.1f, "%4.3f", 0); + ImGui::ColumnSliderFloatButton("A", &specular.z, 0.02f, 0.0f, 4.0f, 0.2f, "%4.3f", 0); + light_data->set_specular(specular); + ImGui::PopID(); + + ImGui::TextCentered("POSITION"); + + ImGui::PushID("Position"); + vec3 position; + light_data->get_position(position); + + float_t rot_y; + if (fabsf(position.x) > 0.000001f || fabsf(position.y) > 0.000001f) + rot_y = atan2f(position.z, position.x) * RAD_TO_DEG_FLOAT; + else + rot_y = 0.0f; + + data_view_light::column_slider_float_button("X", &position.x); + data_view_light::column_slider_float_button("Y", &position.y); + data_view_light::column_slider_float_button("Z", &position.z); + if (ImGui::ColumnSliderFloatButton("ROTY", &rot_y, 0.01f, -180.0f, 180.0f, 0.1f, "%6.2f", 0)) { + vec2 pos = { position.x, position.z }; + float_t len = vec2::length(pos); + position.x = cosf(rot_y * DEG_TO_RAD_FLOAT) * len; + position.z = sinf(rot_y * DEG_TO_RAD_FLOAT) * len; + } + light_data->set_position(position); + ImGui::PopID(); + } + + if (light_data->type == LIGHT_SPOT) { + ImGui::TextCentered("SPOT DIRECTION"); + + ImGui::PushID("Spot Direction"); + vec3 spot_direction; + light_data->get_spot_direction(spot_direction); + ImGui::ColumnSliderFloatButton("X", &spot_direction.x, 0.02f, -1.0f, 1.0f, 0.1f, "%5.2f", 0); + ImGui::ColumnSliderFloatButton("Y", &spot_direction.y, 0.02f, -1.0f, 1.0f, 0.1f, "%5.2f", 0); + ImGui::ColumnSliderFloatButton("Z", &spot_direction.z, 0.02f, -1.0f, 1.0f, 0.1f, "%5.2f", 0); + light_data->set_spot_direction(spot_direction); + ImGui::PopID(); + + if (light->id == LIGHT_REFLECT) { + light_clip_plane clip_plane; + light_data->get_clip_plane(clip_plane); + ImGui::Checkbox("Reflective surface clip(STAGE)", &clip_plane.data[1]); + light_data->set_clip_plane(clip_plane); + } + + ImGui::TextCentered("SPOT EXPONENT"); + + float_t spot_exponent = light_data->get_spot_exponent(); + ImGui::ColumnSliderFloatButton("EXPONENT", &spot_exponent, 1.0f, 0.0f, 128.0f, 10.0f, "%8.4f", 0); + light_data->set_spot_exponent(spot_exponent); + + ImGui::TextCentered("SPOT CUTOFF"); + + float_t spot_cutoff = light_data->get_spot_cutoff(); + ImGui::ColumnSliderFloatButton("CUTOFF", &spot_cutoff, 0.0f, 0.0f, 90.0f, 5.0f, "%8.4f", 0); + light_data->set_spot_cutoff(spot_cutoff); + + ImGui::TextCentered("ATTENUATION"); + + ImGui::PushID("Attenuation"); + light_attenuation attenuation; + light_data->get_attenuation(attenuation); + ImGui::ColumnSliderFloatButton("CONSTANT", &attenuation.constant, 0.01f, 0.0f, 1.0f, 0.1f, "%8.4f", 0); + ImGui::ColumnSliderFloatButton("LINEAR", &attenuation.linear, 0.01f, 0.0f, 1.0f, 0.1f, "%8.4f", 0); + ImGui::ColumnSliderFloatButton("QUADRATIC", &attenuation.quadratic, 0.01f, 0.0f, 1.0f, 0.1f, "%8.4f", 0); + light_data->set_attenuation(attenuation); + } + + if (_stage_index != stage_index && _stage_index != light->stage_index) { + light_param_data_storage_data_load_stage(_stage_index); + light->stage_index = _stage_index; + } data->imgui_focus |= ImGui::IsWindowFocused(); ImGui::End(); } bool graphics_light_dispose(class_data* data) { + data_view_light* light = (data_view_light*)data->data; + if (light) + delete light; + data->data = 0; return true; } + +data_view_light::data_view_light() : rctx(), id(), sync_pos(), +light_auth_enable(), stage_index(), stage_index_prev() { + +} + +data_view_light::~data_view_light() { + +} + +void data_view_light::column_slider_float_button(const char* label, float_t* val) { + float_t val_abs = fabsf(*val); + float_t step; + if (val_abs < 150.0f) + step = 1.0; + else if (val_abs >= 1900.0) + step = 50.0f; + else + step = 10.0f; + + ImGui::ColumnSliderFloatButton(label, val, + step * 0.2f, 1.0f - step * 200.0f, step * 200.0f - 1.0f, step, "%6.2f", 0); +} diff --git a/src/ReDIVA/classes/graphics/light.hpp b/src/ReDIVA/classes/graphics/light.hpp index e37173ff..f9d9806e 100644 --- a/src/ReDIVA/classes/graphics/light.hpp +++ b/src/ReDIVA/classes/graphics/light.hpp @@ -9,5 +9,6 @@ #include "../../classes.hpp" extern bool graphics_light_init(class_data* data, render_context* rctx); +extern void graphics_light_ctrl(class_data* data); extern void graphics_light_imgui(class_data* data); extern bool graphics_light_dispose(class_data* data); diff --git a/src/ReDIVA/classes/graphics/post_process.cpp b/src/ReDIVA/classes/graphics/post_process.cpp index ecd33ab5..473852d1 100644 --- a/src/ReDIVA/classes/graphics/post_process.cpp +++ b/src/ReDIVA/classes/graphics/post_process.cpp @@ -24,8 +24,8 @@ void graphics_post_process_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 400.0f); - float_t h = min((float_t)height, 790.0f); + float_t w = min_def((float_t)width, 400.0f); + float_t h = min_def((float_t)height, 790.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Appearing); @@ -44,6 +44,11 @@ void graphics_post_process_imgui(class_data* data) { } render_context* rctx = (render_context*)data->data; + if (!rctx) { + ImGui::End(); + return; + } + post_process* pp = &rctx->post_process; post_process_blur* blur = pp->blur; diff --git a/src/ReDIVA/classes/graphics/render_settings.cpp b/src/ReDIVA/classes/graphics/render_settings.cpp index aa55f23f..d127e20e 100644 --- a/src/ReDIVA/classes/graphics/render_settings.cpp +++ b/src/ReDIVA/classes/graphics/render_settings.cpp @@ -14,7 +14,6 @@ extern int32_t width; extern int32_t height; extern timer* render_timer; -extern timer* sound_timer; const char* graphics_render_settings_window_title = "Render Settings##Graphics"; @@ -41,7 +40,7 @@ void graphics_render_settings_imgui(class_data* data) { float_t w = 280.0f; #if defined(ReDIVA_DEV) - float_t h = 196.0f; + float_t h = 140.0f; #else float_t h = 86.0f; #endif @@ -77,37 +76,21 @@ void graphics_render_settings_imgui(class_data* data) { ImGui::Separator(); double_t render_freq = render_timer->get_freq(); - double_t sound_freq = sound_timer->get_freq(); double_t render_freq_hist = render_timer->get_freq_hist(); - double_t sound_freq_hist = sound_timer->get_freq_hist(); char render_freq_str[0x20]; - char sound_freq_str[0x20]; char render_ms_str[0x20]; - char sound_ms_str[0x20]; render_settings_freq_to_string(render_freq, render_freq_str, sizeof(render_freq_str), render_ms_str, sizeof(render_ms_str)); - render_settings_freq_to_string(sound_freq, sound_freq_str, - sizeof(sound_freq_str), sound_ms_str, sizeof(sound_ms_str)); char render_freq_hist_str[0x20]; - char sound_freq_hist_str[0x20]; char render_ms_hist_str[0x20]; - char sound_ms_hist_str[0x20]; render_settings_freq_to_string(render_freq_hist, render_freq_hist_str, sizeof(render_freq_hist_str), render_ms_hist_str, sizeof(render_ms_hist_str)); - render_settings_freq_to_string(sound_freq_hist, sound_freq_hist_str, - sizeof(sound_freq_hist_str), sound_ms_hist_str, sizeof(sound_ms_hist_str)); - ImGui::Text("Targ: Render / Sound"); - ImGui::Text("freq: %s / %s", render_freq_str, sound_freq_str); - ImGui::Text(" ms: %s / %s", render_ms_str, sound_ms_str); - - ImGui::Separator(); - - ImGui::Text("Curr: Render / Sound"); - ImGui::Text("freq: %s / %s", render_freq_hist_str, sound_freq_hist_str); - ImGui::Text(" ms: %s / %s", render_ms_hist_str, sound_ms_hist_str); + ImGui::Text("Render: Target / Current"); + ImGui::Text(" freq: %s / %s", render_freq_str, render_freq_hist_str); + ImGui::Text(" ms: %s / %s", render_ms_str, render_ms_hist_str); #endif ImGui::Separator(); diff --git a/src/ReDIVA/classes/information/frame_speed.cpp b/src/ReDIVA/classes/information/frame_speed.cpp index 007ac723..7113018e 100644 --- a/src/ReDIVA/classes/information/frame_speed.cpp +++ b/src/ReDIVA/classes/information/frame_speed.cpp @@ -22,8 +22,8 @@ void information_frame_speed_imgui(class_data* data) { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 240.0f); - float_t h = min((float_t)height, 58.0f); + float_t w = min_def((float_t)width, 240.0f); + float_t h = min_def((float_t)height, 58.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); diff --git a/src/ReDIVA/data_initialize.cpp b/src/ReDIVA/data_initialize.cpp index e5e540c5..404d7afa 100644 --- a/src/ReDIVA/data_initialize.cpp +++ b/src/ReDIVA/data_initialize.cpp @@ -6,6 +6,7 @@ #include "data_initialize.hpp" #include "../CRE/data.hpp" #include "../CRE/object.hpp" +#include "../CRE/sound.hpp" #include "game_state.hpp" extern uint32_t dbg_set_id; @@ -89,14 +90,14 @@ bool TaskDataInit::Ctrl() { object_storage_load_set(aft_data, aft_obj_db, dbg_set_id); //bone_database_read(); //item_table_handler_array_read(); - //sub_14061F7E0("rom/sound/se.farc"); - //sub_14061F7E0("rom/sound/button.farc"); - //sub_14061F7E0("rom/sound/se_cmn.farc"); - //sub_14061F7E0("rom/sound/se_sel.farc"); - //sub_14061F7E0("rom/sound/se_aime.farc"); - //sub_14061F7E0("rom/sound/pvchange.farc"); - //sub_14061F7E0("rom/sound/slide_se.farc"); - //sub_14061F7E0("rom/sound/slide_long.farc"); + sound_work_read_farc("rom/sound/se.farc"); + sound_work_read_farc("rom/sound/button.farc"); + sound_work_read_farc("rom/sound/se_cmn.farc"); + sound_work_read_farc("rom/sound/se_sel.farc"); + sound_work_read_farc("rom/sound/se_aime.farc"); + sound_work_read_farc("rom/sound/pvchange.farc"); + sound_work_read_farc("rom/sound/slide_se.farc"); + sound_work_read_farc("rom/sound/slide_long.farc"); //sub_14037EF30(); //sub_14037F180(); //sub_140377A10(); @@ -124,14 +125,14 @@ bool TaskDataInit::Ctrl() { if (!object_storage_load_obj_set_check_not_read(dbg_set_id) //&& !bone_database_load() //&& !item_table_handler_array_load() - //&& !sub_140620E20("rom/sound/se.farc") - //&& !sub_140620E20("rom/sound/button.farc") - //&& !sub_140620E20("rom/sound/se_cmn.farc") - //&& !sub_140620E20("rom/sound/se_sel.farc") - //&& !sub_140620E20("rom/sound/se_aime.farc") - //&& !sub_140620E20("rom/sound/pvchange.farc") - //&& !sub_140620E20("rom/sound/slide_se.farc") - //&& !sub_140620E20("rom/sound/slide_long.farc") + && !sound_work_load_farc("rom/sound/se.farc") + && !sound_work_load_farc("rom/sound/button.farc") + && !sound_work_load_farc("rom/sound/se_cmn.farc") + && !sound_work_load_farc("rom/sound/se_sel.farc") + && !sound_work_load_farc("rom/sound/se_aime.farc") + && !sound_work_load_farc("rom/sound/pvchange.farc") + && !sound_work_load_farc("rom/sound/slide_se.farc") + && !sound_work_load_farc("rom/sound/slide_long.farc") //&& !sub_14037FE80() //&& !sub_1403785C0() //&& !sub_1403933B0() diff --git a/src/ReDIVA/data_test/auth_3d_test.cpp b/src/ReDIVA/data_test/auth_3d_test.cpp index 9588affd..c9794d26 100644 --- a/src/ReDIVA/data_test/auth_3d_test.cpp +++ b/src/ReDIVA/data_test/auth_3d_test.cpp @@ -137,8 +137,8 @@ void Auth3dTestWindow::Window() { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 280.0f); - float_t h = min((float_t)height, 324.0f); + float_t w = min_def((float_t)width, 280.0f); + float_t h = min_def((float_t)height, 324.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); @@ -312,8 +312,8 @@ void Auth3dTestWindow::Window() { float_t x = w; float_t y = 0.0f; - w = min((float_t)width, 200.0f); - h = min((float_t)height, 124.0f); + w = min_def((float_t)width, 200.0f); + h = min_def((float_t)height, 124.0f); ImGui::SetNextWindowPos({ x, y }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); diff --git a/src/ReDIVA/data_test/glitter_test.cpp b/src/ReDIVA/data_test/glitter_test.cpp index be038fad..98c24197 100644 --- a/src/ReDIVA/data_test/glitter_test.cpp +++ b/src/ReDIVA/data_test/glitter_test.cpp @@ -41,8 +41,12 @@ bool TaskDataTestGlitterParticle::Init() { for (std::vector::iterator i = files.begin(); i != files.end();) if (str_utils_check_ends_with(i->name.c_str(), ".farc")) { char* temp = str_utils_get_without_extension(i->name.c_str()); - i->name = temp ? std::string(temp) : std::string(); - free(temp); + if (temp) { + i->name.assign(temp); + free(temp); + } + else + i->name.clear(); i++; } else @@ -196,8 +200,8 @@ void TaskDataTestGlitterParticle::Window() { window_focus |= ImGui::IsWindowFocused(); ImGui::End(); - float_t win_x = min((float_t)width, 240.0f); - float_t win_y = min((float_t)height, 96.0f); + float_t win_x = min_def((float_t)width, 240.0f); + float_t win_y = min_def((float_t)height, 96.0f); float_t x = 0.0f; float_t y = (float_t)height - win_y; diff --git a/src/ReDIVA/data_test/stage_test.cpp b/src/ReDIVA/data_test/stage_test.cpp index 5e98834d..1ae47900 100644 --- a/src/ReDIVA/data_test/stage_test.cpp +++ b/src/ReDIVA/data_test/stage_test.cpp @@ -166,8 +166,8 @@ void DtwStg::Window() { ImGuiStyle& style = ImGui::GetStyle(); ImFont* font = ImGui::GetFont(); - float_t w = min((float_t)width, 240.0f); - float_t h = min((float_t)height, 240.0f); + float_t w = min_def((float_t)width, 240.0f); + float_t h = min_def((float_t)height, 240.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); @@ -180,7 +180,7 @@ void DtwStg::Window() { ImGui::End(); return; } - + data_struct* aft_data = &data_list[DATA_AFT]; stage_database* aft_stage_data = &aft_data->data_ft.stage_data; diff --git a/src/ReDIVA/game_state.cpp b/src/ReDIVA/game_state.cpp index 639c108f..95f9ee8d 100644 --- a/src/ReDIVA/game_state.cpp +++ b/src/ReDIVA/game_state.cpp @@ -770,8 +770,7 @@ bool SubGameState::Selector::Init() { bool SubGameState::Selector::Ctrl() { if (x_pv_game_selector.exit) { - if (x_pv_game_selector.start) { - x_pv_game_init(); + if (x_pv_game_selector.start && x_pv_game_init()) { XPVGameSelector& sel = x_pv_game_selector; app::TaskWork::AppendTask(x_pv_game_ptr, "X PVGAME", 0); x_pv_game_ptr->Load(sel.pv_id, sel.stage_id, sel.charas, sel.modules); @@ -800,8 +799,7 @@ bool SubGameState::GameMain::Ctrl() { } bool SubGameState::GameMain::Dest() { - x_pv_game_free(); - return true; + return x_pv_game_free(); } bool SubGameState::GameSel::Init() { diff --git a/src/ReDIVA/imgui_helper.cpp b/src/ReDIVA/imgui_helper.cpp index 64ec3107..c449599c 100644 --- a/src/ReDIVA/imgui_helper.cpp +++ b/src/ReDIVA/imgui_helper.cpp @@ -65,7 +65,8 @@ namespace ImGui { TableNextColumn(); GetContentRegionAvailSetNextItemWidth(); Text(label_temp); - free(label_temp); + if (label_temp) + free(label_temp); TableNextColumn(); GetContentRegionAvailSetNextItemWidth(); @@ -316,7 +317,8 @@ namespace ImGui { DisableElementPush(enable); Text(label_temp); DisableElementPop(enable); - free(label_temp); + if (label_temp) + free(label_temp); TableNextColumn(); GetContentRegionAvailSetNextItemWidth(); @@ -693,7 +695,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -711,8 +713,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -730,9 +732,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -750,10 +752,10 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -771,7 +773,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -789,8 +791,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -808,9 +810,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -828,10 +830,10 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -861,7 +863,7 @@ namespace ImGui { v[0] = roundf(v[0] / step) * step; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -884,8 +886,8 @@ namespace ImGui { v[0] = roundf(v[0] / step) * step; v[1] = roundf(v[1] / step) * step; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -909,9 +911,9 @@ namespace ImGui { v[1] = roundf(v[1] / step) * step; v[2] = roundf(v[2] / step) * step; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -936,10 +938,10 @@ namespace ImGui { v[2] = roundf(v[2] / step) * step; v[3] = roundf(v[3] / step) * step; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -959,7 +961,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -979,8 +981,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1000,9 +1002,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1022,17 +1024,17 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; *val = *(vec4i*)v; return true; } - + bool ColumnSliderFloatButton(const char* label, float_t* val, float_t button_step, float_t min, float_t max, float_t step, const char* format, ImGuiSliderFlags flags) { float_t v[1]; @@ -1045,9 +1047,9 @@ namespace ImGui { if (!res) return false; - v[0] = roundf(v[0] / step) * step; + v[0] = roundf(v[0] / button_step) * button_step; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -1075,11 +1077,11 @@ namespace ImGui { if (!res) return false; - v[0] = roundf(v[0] / step) * step; - v[1] = roundf(v[1] / step) * step; + v[0] = roundf(v[0] / button_step) * button_step; + v[1] = roundf(v[1] / button_step) * button_step; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1110,13 +1112,13 @@ namespace ImGui { if (!res) return false; - v[0] = roundf(v[0] / step) * step; - v[1] = roundf(v[1] / step) * step; - v[2] = roundf(v[2] / step) * step; + v[0] = roundf(v[0] / button_step) * button_step; + v[1] = roundf(v[1] / button_step) * button_step; + v[2] = roundf(v[2] / button_step) * button_step; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1150,15 +1152,15 @@ namespace ImGui { if (!res) return false; - v[0] = roundf(v[0] / step) * step; - v[1] = roundf(v[1] / step) * step; - v[2] = roundf(v[2] / step) * step; - v[3] = roundf(v[3] / step) * step; + v[0] = roundf(v[0] / button_step) * button_step; + v[1] = roundf(v[1] / button_step) * button_step; + v[2] = roundf(v[2] / button_step) * button_step; + v[3] = roundf(v[3] / button_step) * button_step; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -1178,7 +1180,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -1206,8 +1208,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1238,9 +1240,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1274,10 +1276,10 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -1310,7 +1312,7 @@ namespace ImGui { if (!res) return false; - v[0] = 1 << clamp(v[0], min, max); + v[0] = 1 << clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -1347,8 +1349,8 @@ namespace ImGui { if (!res) return false; - v[0] = 1 << clamp(v[0], min, max); - v[1] = 1 << clamp(v[1], min, max); + v[0] = 1 << clamp_def(v[0], min, max); + v[1] = 1 << clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1389,9 +1391,9 @@ namespace ImGui { if (!res) return false; - v[0] = 1 << clamp(v[0], min, max); - v[1] = 1 << clamp(v[1], min, max); - v[2] = 1 << clamp(v[2], min, max); + v[0] = 1 << clamp_def(v[0], min, max); + v[1] = 1 << clamp_def(v[1], min, max); + v[2] = 1 << clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1436,10 +1438,10 @@ namespace ImGui { if (!res) return false; - v[0] = 1 << clamp(v[0], min, max); - v[1] = 1 << clamp(v[1], min, max); - v[2] = 1 << clamp(v[2], min, max); - v[3] = 1 << clamp(v[3], min, max); + v[0] = 1 << clamp_def(v[0], min, max); + v[1] = 1 << clamp_def(v[1], min, max); + v[2] = 1 << clamp_def(v[2], min, max); + v[3] = 1 << clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -1470,7 +1472,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -1495,8 +1497,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1523,9 +1525,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1554,10 +1556,10 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -1580,7 +1582,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -1605,8 +1607,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1633,9 +1635,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1664,10 +1666,10 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -1690,7 +1692,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -1715,8 +1717,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1743,9 +1745,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1774,10 +1776,10 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -1800,7 +1802,7 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); + v[0] = clamp_def(v[0], min, max); if (v[0] == *val) return false; @@ -1825,8 +1827,8 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); if (v[0] == val->x && v[1] == val->y) return false; @@ -1853,9 +1855,9 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z) return false; @@ -1884,10 +1886,10 @@ namespace ImGui { if (!res) return false; - v[0] = clamp(v[0], min, max); - v[1] = clamp(v[1], min, max); - v[2] = clamp(v[2], min, max); - v[3] = clamp(v[3], min, max); + v[0] = clamp_def(v[0], min, max); + v[1] = clamp_def(v[1], min, max); + v[2] = clamp_def(v[2], min, max); + v[3] = clamp_def(v[3], min, max); if (v[0] == val->x && v[1] == val->y && v[2] == val->z && v[3] == val->w) return false; @@ -1895,10 +1897,36 @@ namespace ImGui { return true; } + void TextCentered(const char* fmt, ...) { + ImGuiContext& g = *GImGui; + + va_list args; + va_start(args, fmt); + vsprintf_s(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args); + va_end(args); + + std::string tex_buf(g.TempBuffer.Data, g.TempBuffer.Size); + ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize(tex_buf.c_str()).x) * 0.5f); + ImGui::Text(tex_buf.c_str()); + } + + void TextRight(const char* fmt, ...) { + ImGuiContext& g = *GImGui; + + va_list args; + va_start(args, fmt); + vsprintf_s(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args); + va_end(args); + + std::string tex_buf(g.TempBuffer.Data, g.TempBuffer.Size); + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ImGui::CalcTextSize(tex_buf.c_str()).x); + ImGui::Text(tex_buf.c_str()); + } + // Taken from ImGui src // FIXME: Try to move more of the code into shared SliderBehavior() template - bool SliderBehaviorTA(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, + bool SliderBehaviorStepT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const TYPE v_step, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb) { ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; @@ -1932,8 +1960,26 @@ namespace ImGui { zero_deadzone_halfsize = (style.LogSliderDeadzone * 0.5f) / ImMax(slider_usable_sz, 1.0f); } + if (slider_sz < 1.0f) + *out_grab_bb = ImRect(bb.Min, bb.Min); + else { + // Output grab position so it can be displayed by the caller + float_t grab_t = ScaleRatioFromValueT(data_type, + *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + if (axis == ImGuiAxis_Y) + grab_t = 1.0f - grab_t; + const float_t grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); + if (axis == ImGuiAxis_X) + *out_grab_bb = ImRect(grab_pos - grab_sz * 0.5f, bb.Min.y + grab_padding, + grab_pos + grab_sz * 0.5f, bb.Max.y - grab_padding); + else + *out_grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz * 0.5f, + bb.Max.x - grab_padding, grab_pos + grab_sz * 0.5f); + } + // Process interacting with the slider bool value_changed = false; + bool continuos_value_change = false; if (g.ActiveId == id) { bool set_new_value = false; float_t clicked_t = 0.0f; @@ -1960,7 +2006,15 @@ namespace ImGui { - slider_usable_pos_min) / slider_usable_sz); if (axis == ImGuiAxis_Y) clicked_t = 1.0f - clicked_t; - set_new_value = IsMouseClicked(ImGuiMouseButton_Left, true); + + float_t diff1 = g.IO.MousePosPrev[axis] - out_grab_bb->Min[axis]; + float_t diff2 = out_grab_bb->Max[axis] - g.IO.MousePosPrev[axis]; + if (diff1 >= -grab_sz && diff2 >= -grab_sz) { + set_new_value = true; + continuos_value_change = true; + } + else + set_new_value = IsMouseClicked(ImGuiMouseButton_Left, true); } } else if (g.ActiveIdSource == ImGuiInputSource_Nav) { @@ -2038,7 +2092,11 @@ namespace ImGui { v_new = RoundScalarWithFormatT(format, data_type, v_new); // Apply result - if (v_new - *v >= v_step) { + if (continuos_value_change) { + *v = v_new; + value_changed = true; + } + else if (v_new - *v >= v_step) { *v += v_step; value_changed = true; } @@ -2053,23 +2111,6 @@ namespace ImGui { } } - if (slider_sz < 1.0f) - *out_grab_bb = ImRect(bb.Min, bb.Min); - else { - // Output grab position so it can be displayed by the caller - float_t grab_t = ScaleRatioFromValueT(data_type, - *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); - if (axis == ImGuiAxis_Y) - grab_t = 1.0f - grab_t; - const float_t grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); - if (axis == ImGuiAxis_X) - *out_grab_bb = ImRect(grab_pos - grab_sz * 0.5f, bb.Min.y + grab_padding, - grab_pos + grab_sz * 0.5f, bb.Max.y - grab_padding); - else - *out_grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz * 0.5f, - bb.Max.x - grab_padding, grab_pos + grab_sz * 0.5f); - } - return value_changed; } @@ -2093,7 +2134,7 @@ namespace ImGui { const int8_t min = *(const int8_t*)p_min; const int8_t max = *(const int8_t*)p_max; const int8_t step = *(const int8_t*)p_step; - bool r = SliderBehaviorTA(bb, id, ImGuiDataType_S32, + bool r = SliderBehaviorStepT(bb, id, ImGuiDataType_S32, &v32, min, max, step, format, flags, out_grab_bb); if (r) *(int8_t*)p_v = (int8_t)v32; @@ -2104,7 +2145,7 @@ namespace ImGui { const uint8_t min = *(const uint8_t*)p_min; const uint8_t max = *(const uint8_t*)p_max; const uint8_t step = *(const uint8_t*)p_step; - bool r = SliderBehaviorTA(bb, id, ImGuiDataType_U32, + bool r = SliderBehaviorStepT(bb, id, ImGuiDataType_U32, &v32, min, max, step, format, flags, out_grab_bb); if (r) *(uint8_t*)p_v = (uint8_t)v32; @@ -2115,7 +2156,7 @@ namespace ImGui { const int16_t min = *(const int16_t*)p_min; const int16_t max = *(const int16_t*)p_max; const int16_t step = *(const int16_t*)p_step; - bool r = SliderBehaviorTA(bb, id, ImGuiDataType_S32, + bool r = SliderBehaviorStepT(bb, id, ImGuiDataType_S32, &v32, min, max, step, format, flags, out_grab_bb); if (r) *(int16_t*)p_v = (int16_t)v32; @@ -2126,7 +2167,7 @@ namespace ImGui { const uint16_t min = *(const uint16_t*)p_min; const uint16_t max = *(const uint16_t*)p_max; const uint16_t step = *(const uint16_t*)p_step; - bool r = SliderBehaviorTA(bb, id, ImGuiDataType_U32, + bool r = SliderBehaviorStepT(bb, id, ImGuiDataType_U32, &v32, min, max, step, format, flags, out_grab_bb); if (r) *(uint16_t*)p_v = (uint16_t)v32; @@ -2137,7 +2178,7 @@ namespace ImGui { const int32_t max = *(const int32_t*)p_max; const int32_t step = *(const int32_t*)p_step; IM_ASSERT(min >= INT32_MIN / 2 && max <= INT32_MAX / 2); - return SliderBehaviorTA(bb, id, data_type, + return SliderBehaviorStepT(bb, id, data_type, (int32_t*)p_v, min, max, step, format, flags, out_grab_bb); } case ImGuiDataType_U32: { @@ -2145,7 +2186,7 @@ namespace ImGui { const uint32_t max = *(const uint32_t*)p_max; const uint32_t step = *(const uint32_t*)p_step; IM_ASSERT(max <= UINT32_MAX / 2); - return SliderBehaviorTA(bb, id, data_type, + return SliderBehaviorStepT(bb, id, data_type, (uint32_t*)p_v, min, max, step, format, flags, out_grab_bb); } case ImGuiDataType_S64: { @@ -2153,7 +2194,7 @@ namespace ImGui { const int64_t max = *(const int64_t*)p_max; const int64_t step = *(const int64_t*)p_step; IM_ASSERT(min >= INT64_MIN / 2 && max <= INT64_MAX / 2); - return SliderBehaviorTA(bb, id, data_type, + return SliderBehaviorStepT(bb, id, data_type, (int64_t*)p_v, min, max, step, format, flags, out_grab_bb); } case ImGuiDataType_U64: { @@ -2161,7 +2202,7 @@ namespace ImGui { const uint64_t max = *(const uint64_t*)p_max; const uint64_t step = *(const uint64_t*)p_step; IM_ASSERT(max <= UINT64_MAX / 2); - return SliderBehaviorTA(bb, id, data_type, + return SliderBehaviorStepT(bb, id, data_type, (uint64_t*)p_v, min, max, step, format, flags, out_grab_bb); } case ImGuiDataType_Float: { @@ -2169,7 +2210,7 @@ namespace ImGui { const float_t max = *(const float_t*)p_max; const float_t step = *(const float_t*)p_step; IM_ASSERT(min >= -FLT_MAX / 2.0f && max <= FLT_MAX / 2.0f); - return SliderBehaviorTA(bb, id, data_type, + return SliderBehaviorStepT(bb, id, data_type, (float_t*)p_v, min, max, step, format, flags, out_grab_bb); } case ImGuiDataType_Double: { @@ -2177,7 +2218,7 @@ namespace ImGui { const double_t max = *(const double_t*)p_max; const double_t step = *(const double_t*)p_step; IM_ASSERT(min >= -DBL_MAX / 2.0f && max <= DBL_MAX / 2.0f); - return SliderBehaviorTA(bb, id, data_type, + return SliderBehaviorStepT(bb, id, data_type, (double_t*)p_v, min, max, step, format, flags, out_grab_bb); } case ImGuiDataType_COUNT: break; diff --git a/src/ReDIVA/imgui_helper.hpp b/src/ReDIVA/imgui_helper.hpp index 127c8ffe..7d383fa3 100644 --- a/src/ReDIVA/imgui_helper.hpp +++ b/src/ReDIVA/imgui_helper.hpp @@ -88,9 +88,11 @@ namespace ImGui { extern bool ButtonEnterKeyPressed(const char* label, const ImVec2& size = ImVec2(0, 0)); extern bool ButtonExEnterKeyPressed(const char* label, const ImVec2& size = ImVec2(0, 0), ImGuiButtonFlags flags = 0); + extern bool CheckboxEnterKeyPressed(const char* label, bool* v); extern bool CheckboxFlagsEnterKeyPressed(const char* label, int* flags, int flags_value); extern bool CheckboxFlagsEnterKeyPressed(const char* label, unsigned int* flags, unsigned int flags_value); + extern bool ComboBox(const char* label, const char** items, const size_t size, int32_t* selected_idx, ImGuiComboFlags flags, bool include_last, bool* focus); extern bool ComboBox(const char* label, const char** items, const size_t size, @@ -103,8 +105,10 @@ namespace ImGui { int32_t* selected_idx, ImGuiComboFlags flags, bool include_last, bool* focus); extern bool ComboBoxConfigFile(const char* label, void* items, const size_t size, size_t* selected_idx, ImGuiComboFlags flags, bool include_last, bool* focus); + extern bool ColumnColorEdit3(const char* label, vec3* val, ImGuiColorEditFlags flags); extern bool ColumnColorEdit4(const char* label, vec4* val, ImGuiColorEditFlags flags); + extern bool ColumnComboBox(const char* label, const char** items, const size_t size, int32_t* selected_idx, ImGuiComboFlags flags, bool include_last, bool* focus); extern bool ColumnComboBox(const char* label, const char** items, const size_t size, @@ -117,6 +121,7 @@ namespace ImGui { int32_t* selected_idx, ImGuiComboFlags flags, bool include_last, bool* focus); extern bool ColumnComboBoxConfigFile(const char* label, void* items, const size_t size, size_t* selected_idx, ImGuiComboFlags flags, bool include_last, bool* focus); + extern bool ColumnDragFloat(const char* label, float_t* val, float_t speed, float_t min, float_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnDragVec2(const char* label, vec2* val, float_t speed, @@ -125,6 +130,7 @@ namespace ImGui { float_t min, float_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnDragVec4(const char* label, vec4* val, float_t speed, float_t min, float_t max, const char* format, ImGuiSliderFlags flags); + extern bool ColumnDragInt(const char* label, int32_t* val, float_t speed, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnDragVec2I(const char* label, vec2i* val, float_t speed, @@ -133,8 +139,10 @@ namespace ImGui { int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnDragVec4I(const char* label, vec4i* val, float_t speed, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); + extern bool ColumnInputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); + extern bool ColumnSliderFloat(const char* label, float_t* val, float_t step, float_t min, float_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec2(const char* label, vec2* val, float_t step, @@ -143,6 +151,7 @@ namespace ImGui { float_t min, float_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec4(const char* label, vec4* val, float_t step, float_t min, float_t max, const char* format, ImGuiSliderFlags flags); + extern bool ColumnSliderInt(const char* label, int32_t* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec2I(const char* label, vec2i* val, @@ -151,6 +160,7 @@ namespace ImGui { int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec4I(const char* label, vec4i* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); + extern bool ColumnSliderFloatButton(const char* label, float_t* val, float_t button_step, float_t min, float_t max, float_t step, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec2Button(const char* label, vec2* val, float_t button_step, @@ -159,6 +169,7 @@ namespace ImGui { float_t min, float_t max, float_t step, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec4Button(const char* label, vec4* val, float_t button_step, float_t min, float_t max, float_t step, const char* format, ImGuiSliderFlags flags); + extern bool ColumnSliderIntButton(const char* label, int32_t* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec2IButton(const char* label, vec2i* val, @@ -167,6 +178,7 @@ namespace ImGui { int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderVec4IButton(const char* label, vec4i* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); + extern bool ColumnSliderLogInt(const char* label, int32_t* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderLogVec2I(const char* label, vec2i* val, @@ -175,8 +187,10 @@ namespace ImGui { int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); extern bool ColumnSliderLogVec4I(const char* label, vec4i* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags); + extern bool ColumnInputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags); + extern bool ColumnDragFloat(const char* label, float_t* val, float_t speed, float_t min, float_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnDragVec2(const char* label, vec2* val, float_t speed, @@ -185,6 +199,7 @@ namespace ImGui { float_t min, float_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnDragVec4(const char* label, vec4* val, float_t speed, float_t min, float_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); + extern bool ColumnDragInt(const char* label, int32_t* val, float_t speed, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnDragVec2I(const char* label, vec2i* val, float_t speed, @@ -193,6 +208,7 @@ namespace ImGui { int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnDragVec4I(const char* label, vec4i* val, float_t speed, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); + extern bool ColumnSliderFloat(const char* label, float_t* val, float_t min, float_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnSliderVec2(const char* label, vec2* val, @@ -201,6 +217,7 @@ namespace ImGui { float_t min, float_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnSliderVec4(const char* label, vec4* val, float_t min, float_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); + extern bool ColumnSliderInt(const char* label, int32_t* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnSliderVec2I(const char* label, vec2i* val, @@ -209,4 +226,7 @@ namespace ImGui { int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); extern bool ColumnSliderVec4I(const char* label, vec4i* val, int32_t min, int32_t max, const char* format, ImGuiSliderFlags flags, int32_t bit_flag); -} \ No newline at end of file + + extern void TextCentered(const char* fmt, ...); + extern void TextRight(const char* fmt, ...); +} diff --git a/src/ReDIVA/main.cpp b/src/ReDIVA/main.cpp index 201c3c87..61772219 100644 --- a/src/ReDIVA/main.cpp +++ b/src/ReDIVA/main.cpp @@ -3,6 +3,9 @@ GitHub/GitLab: korenkonder */ +#include "../KKdLib/database/sprite.hpp" +#include "../KKdLib/io/file_stream.hpp" +#include "../KKdLib/io/memory_stream.hpp" #include "../KKdLib/f2/struct.hpp" #include "../KKdLib/a3da.hpp" #include "../KKdLib/dsc.hpp" @@ -86,8 +89,7 @@ static bool a3da_to_dof_data(const char* a3da_path, dft_dsc_data& data) { continue; } - float_t focus; - vec3_distance(cam_a3da.dof.model_transform.translation_value, cr->view_point_value, focus); + float_t focus = vec3::distance(cam_a3da.dof.model_transform.translation_value, cr->view_point_value); dof_data d; d.flags = 0x1F; @@ -118,7 +120,7 @@ static void a3da_to_dft_dsc(int32_t pv_id) { char buf[0x100]; sprintf_s(buf, sizeof(buf), "DOF\\script\\pv_%03d_hard.dsc", pv_id); - stream s_src_dsc; + file_stream s_src_dsc; s_src_dsc.open(buf, "rb"); size_t src_dsc_length = s_src_dsc.get_length(); @@ -128,7 +130,8 @@ static void a3da_to_dft_dsc(int32_t pv_id) { dsc d_src = dsc(); d_src.parse(src_dsc_data, src_dsc_length, DSC_FT); - free(src_dsc_data); + if (src_dsc_data) + free(src_dsc_data); d_src.rebuild(); dsc_get_func_id src_get_func_id = dsc_type_get_dsc_get_func_id(d_src.type); @@ -253,15 +256,17 @@ static void a3da_to_dft_dsc(int32_t pv_id) { d.unparse(&dsc_data, &dsc_length); sprintf_s(buf, sizeof(buf), "DOF\\pv_script\\pv_%03d_dof.dsc", pv_id); - stream s_dsc; + file_stream s_dsc; s_dsc.open(buf, "wb"); s_dsc.write(dsc_data, dsc_length); s_dsc.close(); - free(dsc_data); + if (dsc_data) + free(dsc_data); - stream s_dft; + memory_stream s_dft; s_dft.open(); + uint32_t off; enrs e; enrs_entry ee; @@ -304,11 +309,6 @@ static void a3da_to_dft_dsc(int32_t pv_id) { bool close; -struct thread { - HANDLE handle; - DWORD id; -}; - int32_t wmain(int32_t argc, wchar_t** argv) { //ShowWindow(GetConsoleWindow(), SW_HIDE); timeBeginPeriod(1); @@ -323,26 +323,8 @@ int32_t wmain(int32_t argc, wchar_t** argv) { render_init_struct ris; - thread render, sound; - HANDLE h[2]; - h[0] = render.handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)render_main, &ris, 0, &render.id); - h[1] = sound.handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sound_main, 0, 0, &sound.id); + render_main(&ris); - if (render.handle) - SetThreadDescription(render.handle, L"Render Thread"); - if (sound.handle) - SetThreadDescription(sound.handle, L"Sound Thread"); - - lock_init(&state_lock); - state = RENDER_UNINITIALIZED; - if (render.handle && sound.handle) - WaitForMultipleObjects(2, h, true, INFINITE); - lock_free(&state_lock); - - if (render.handle) - CloseHandle(render.handle); - if (sound.handle) - CloseHandle(sound.handle); timeEndPeriod(1); return 0; } diff --git a/src/ReDIVA/main.hpp b/src/ReDIVA/main.hpp index e8543c47..5bbfe06e 100644 --- a/src/ReDIVA/main.hpp +++ b/src/ReDIVA/main.hpp @@ -8,4 +8,3 @@ #include "../KKdLib/default.hpp" #include "input.hpp" #include "render.hpp" -#include "sound.hpp" diff --git a/src/ReDIVA/pv_game.cpp b/src/ReDIVA/pv_game.cpp index e888e393..2a398df8 100644 --- a/src/ReDIVA/pv_game.cpp +++ b/src/ReDIVA/pv_game.cpp @@ -11,6 +11,7 @@ #include "../CRE/Glitter/glitter.hpp" #include "../CRE/light_param/light.hpp" #include "../CRE/light_param.hpp" +#include "../CRE/rob/rob.hpp" #include "../CRE/data.hpp" #include "../CRE/object.hpp" #include "../CRE/pv_param.hpp" @@ -135,10 +136,6 @@ TaskPvGame task_pv_game; extern render_context* rctx_ptr; static float_t dsc_time_to_frame(int64_t time); -static int32_t expression_id_to_mottbl_index(int32_t expression_id); -static int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id); -static int32_t look_anim_id_to_mottbl_index(int32_t look_anim_id); -static int32_t mouth_anim_id_to_mottbl_index(int32_t mouth_anim_id); static void pv_game_change_field(pv_game_old* pvgm, int32_t field, int64_t dsc_time, int64_t curr_time); static bool pv_game_dsc_process(pv_game_old* pvgm, int64_t curr_time); static void pv_game_reset_field(pv_game_old* pvgm); @@ -969,67 +966,6 @@ static float_t dsc_time_to_frame(int64_t time) { return (float_t)time / 1000000000.0f * 60.0f; } -static int32_t expression_id_to_mottbl_index(int32_t expression_id) { - static const int32_t expression_id_to_mottbl_index_table[] = { - 11, 15, 57, 19, 23, 25, 29, 33, - 37, 41, 45, 49, 53, 65, 7, 69, - 73, 77, 81, 85, 89, 7, 61, 6, - 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 93, 95, 97, 99, 101, 103, - 105, 107, 109, 111, 113, 115, 117, 119, - 121, 123, 125, 127, 13, 21, 31, 39, - 43, 47, 51, 55, 67, 71, 79, 83, - 129, 59, 17, 91, 27, 87, 35, 75, - 9, 63, 236, 238, 240, 242, - }; - - if (expression_id >= 0 && expression_id - < sizeof(expression_id_to_mottbl_index_table) / sizeof(int32_t)) - return expression_id_to_mottbl_index_table[expression_id]; - return 6; -} - -static int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id) { - static const int32_t hand_anim_id_to_mottbl_index_table[] = { - 195, 196, 194, 197, 201, 198, 199, 202, - 203, 192, 200, 204, 204, 204, 193, - }; - - if (hand_anim_id >= 0 && hand_anim_id - < sizeof(hand_anim_id_to_mottbl_index_table) / sizeof(int32_t)) - return hand_anim_id_to_mottbl_index_table[hand_anim_id]; - return 192; -} - -static int32_t look_anim_id_to_mottbl_index(int32_t look_anim_id) { - static const int32_t look_anim_id_to_mottbl_index_table[] = { - 168, 170, 174, 172, 178, 176, 182, 180, - 166, 165, 224, 169, 171, 175, 173, 179, - 177, 183, 181, 167, - }; - - if (look_anim_id >= 0 && look_anim_id - < sizeof(look_anim_id_to_mottbl_index_table) / sizeof(int32_t)) - return look_anim_id_to_mottbl_index_table[look_anim_id]; - return 165; -} - -static int32_t mouth_anim_id_to_mottbl_index(int32_t mouth_anim_id) { - static const int32_t mouth_anim_id_to_mottbl_index_table[] = { - 134, 140, 142, 146, 144, 148, 150, 152, - 132, 131, 136, 138, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 151, - 135, 143, 147, 145, 133, 137, 139, 141, - 149, 153, 244, 245, 246, 247, 248, 249, - 250, 251, 252, - }; - - if (mouth_anim_id >= 0 && mouth_anim_id - < sizeof(mouth_anim_id_to_mottbl_index_table) / sizeof(int32_t)) - return mouth_anim_id_to_mottbl_index_table[mouth_anim_id]; - return 131; -} - static void sub_140122B60(pv_game_old* a1, int32_t chara_id, int32_t motion_index, int64_t disp_time) { if (chara_id < 0 || chara_id > ROB_CHARA_COUNT || motion_index < 0) return; @@ -1764,7 +1700,7 @@ static bool pv_game_dsc_process(pv_game_old* a1, int64_t curr_time) { if (!rob_chr) break; - rob_chr->item_equip->wet = clamp(value, 0.0f, 1.0f); + rob_chr->item_equip->wet = clamp_def(value, 0.0f, 1.0f); } break; case DSC_FT_LIGHT_ROT: { diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index 6d58bf6e..03931a25 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -26,7 +26,9 @@ #include "../CRE/lock.hpp" #include "../CRE/mdata_manager.hpp" #include "../CRE/object.hpp" +#include "../CRE/ogg_vorbis.hpp" #include "../CRE/pv_db.hpp" +#include "../CRE/random.hpp" #include "../CRE/shader.hpp" #include "../CRE/shader_ft.hpp" #include "../CRE/shader_glsl.hpp" @@ -150,11 +152,11 @@ static void APIENTRY render_debug_output(GLenum source, GLenum type, uint32_t id extern bool close; bool reload_render; -lock render_lock; +lock* render_lock; HWND window_handle; GLFWwindow* window; ImGuiContext* imgui_context; -lock imgui_context_lock; +lock* imgui_context_lock; bool global_context_menu; extern size_t frame_counter; render_context* rctx_ptr; @@ -164,32 +166,21 @@ render_init_struct::render_init_struct() : scale_index() { } -int32_t render_main(void* arg) { +int32_t render_main(render_init_struct* ris) { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); timeBeginPeriod(1); + + render_lock = new lock; + if (!render_lock) + return 0; + render_timer = new timer(60.0); - state = RENDER_UNINITIALIZED; - - lock_init(&render_lock); - if (!lock_check_init(&render_lock)) { - delete render_timer; - return 0; - } - - render_init_struct* ris = (render_init_struct*)arg; window_handle = 0; #pragma region GLFW Init - glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); - glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE); -#if defined(DEBUG) && OPENGL_DEBUG - glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); -#endif + if (!glfwInit()) + return -1; GLFWmonitor* monitor = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(monitor); @@ -204,6 +195,16 @@ int32_t render_main(void* arg) { height = 1080; #endif + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); + glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE); + //glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); +#if defined(DEBUG) && OPENGL_DEBUG + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); +#endif + glfwWindowHint(GLFW_RED_BITS, mode->redBits); glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); @@ -233,19 +234,21 @@ int32_t render_main(void* arg) { window = glfwCreateWindow(width, height, glfw_titlelabel, maximized ? monitor : 0, 0); if (!window) { glfwTerminate(); - return -1; + return -2; } glfwMakeContextCurrent(window); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { glfwTerminate(); - return -2; + return -3; } + glGetError(); glViewport(0, 0, width, height); window_handle = glfwGetWin32Window(window); + glfwShowWindow(window); glfwFocusWindow(window); glfwSetDropCallback(window, (GLFWdropfun)render_drop_glfw); glfwSetWindowSizeCallback(window, (GLFWwindowsizefun)render_resize_fb_glfw); @@ -284,11 +287,6 @@ int32_t render_main(void* arg) { glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &sv_max_texture_max_anisotropy); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); - lock_lock(&state_lock); - state = RENDER_INITIALIZING; - enum_or(thread_flags, THREAD_RENDER); - lock_unlock(&state_lock); - #if DRAW_PASS_TIME_DISP for (std::vector& i : draw_pass_cpu_time) i.resize(240, 0.0f); @@ -302,21 +300,24 @@ int32_t render_main(void* arg) { reload_render = false; render_context* rctx = 0; - lock_lock(&render_lock); + lock_lock(render_lock); rctx = render_load(); - lock_unlock(&render_lock); + lock_unlock(render_lock); + + data_struct* aft_data = &data_list[DATA_AFT]; + + //OggFileHandler ofh; + //aft_data->load_file(&ofh, "rom/sound/bgm/", + // "selector_verB_a_lp.ogg", OggFileHandler::LoadFile); - lock_lock(&state_lock); frame_counter = 0; - state = RENDER_INITIALIZED; - lock_unlock(&state_lock); #pragma region GL Init #if !(BAKE_PNG || BAKE_VIDEO) glfwGetFramebufferSize(window, &width, &height); #endif glViewport(0, 0, width, height); - glfwSwapInterval(0); + glfwSwapInterval(1); gl_state_disable_blend(); gl_state_disable_depth_test(); @@ -324,7 +325,6 @@ int32_t render_main(void* arg) { gl_state_disable_cull_face(); gl_state_disable_stencil_test(); #pragma endregion - render_timer->reset(); while (!close && !reload_render) { render_timer->start_of_cycle(); @@ -332,41 +332,25 @@ int32_t render_main(void* arg) { ImGui_ImplGlfw_NewFrame(); ImGui_ImplOpenGL3_NewFrame(); ImGui::NewFrame(); - lock_lock(&render_lock); + Input::NewFrame(); + lock_lock(render_lock); render_ctrl(rctx); - lock_unlock(&render_lock); + lock_unlock(render_lock); render_disp(rctx); - glfwSwapBuffers(window); close |= !!glfwWindowShouldClose(window); frame_counter++; Input::EndFrame(); render_timer->end_of_cycle(); + glfwSwapBuffers(window); } - lock_lock(&state_lock); - state = RENDER_DISPOSING; - lock_unlock(&state_lock); + //ofh.~OggFileHandler(); - bool threads_wait = false; - render_timer->reset(); - do { - render_timer->start_of_cycle(); - lock_lock(&state_lock); - threads_wait = thread_flags & ~THREAD_RENDER; - lock_unlock(&state_lock); - render_timer->end_of_cycle(); - } while (threads_wait); - - lock_lock(&render_lock); + lock_lock(render_lock); render_dispose(rctx); - lock_unlock(&render_lock); + lock_unlock(render_lock); } while (reload_render); - lock_lock(&state_lock); - state = RENDER_DISPOSED; - enum_and(thread_flags, ~THREAD_RENDER); - lock_unlock(&state_lock); - #if DRAW_PASS_TIME_DISP for (std::vector& i : draw_pass_cpu_time) { i.clear(); @@ -383,8 +367,10 @@ int32_t render_main(void* arg) { glfwDestroyWindow(window); glfwTerminate(); #pragma endregion - lock_free(&render_lock); + delete render_lock; + render_lock = 0; delete render_timer; + render_timer = 0; return 0; } @@ -437,8 +423,11 @@ static render_context* render_load() { } render_shaders_load(); + sound_init(); + wave_audio_storage_init(); object_storage_init(aft_obj_db); item_table_array_init(); + rand_state_array_init(); app::task_work_init(); @@ -475,7 +464,7 @@ static render_context* render_load() { sprintf_s(buf, sizeof(buf), i == 815 ? "EFFPV%03d" : "ITMPV%03d", i); object_set_info* effpv_set_info; - if (aft_obj_db->get_object_set_info(buf, &effpv_set_info)){ + if (aft_obj_db->get_object_set_info(buf, &effpv_set_info)) { obj_set_ids.push_back(effpv_set_info->id); obj_set_id_name.insert({ effpv_set_info->id, buf }); } @@ -491,7 +480,7 @@ static render_context* render_load() { sprintf_s(buf, sizeof(buf), "STGPV%03dHRC", i); object_set_info* stgpvhrc_set_info; - if (aft_obj_db->get_object_set_info(buf, &stgpvhrc_set_info)){ + if (aft_obj_db->get_object_set_info(buf, &stgpvhrc_set_info)) { obj_set_ids.push_back(stgpvhrc_set_info->id); obj_set_id_name.insert({ stgpvhrc_set_info->id, buf }); } @@ -780,13 +769,15 @@ static render_context* render_load() { " vec2 uv;\n" "} frg;\n" "\n" - "uniform float dark_border_end;\n" - "uniform float dark_border_start;\n" + "uniform float border_end;\n" + "uniform float border_start;\n" + "uniform vec3 border_color;" + "uniform vec3 center_color;" "\n" "void main() {\n" - " float blend = step(dark_border_end, frg.uv.x) * (1.0 - step(dark_border_start, frg.uv.x))" - " * step(dark_border_end, frg.uv.y) * (1.0 - step(dark_border_start, frg.uv.y));\n" - " result = vec4(blend, blend, blend, 1.0);\n" + " float blend = step(border_end, frg.uv.x) * (1.0 - step(border_start, frg.uv.x))" + " * step(border_end, frg.uv.y) * (1.0 - step(border_start, frg.uv.y));\n" + " result = vec4(mix(border_color, center_color, blend), 1.0);\n" "}\n"; const char* grid_vert_shader = @@ -895,12 +886,13 @@ static render_context* render_load() { render_timer->reset(); for (int32_t i = 0; i < 30; i++) { render_timer->start_of_cycle(); - lock_lock(&render_lock); + lock_lock(render_lock); game_state_ctrl(); app::TaskWork::Ctrl(); + sound_ctrl(); file_handler_storage_ctrl(); app::TaskWork::Basic(); - lock_unlock(&render_lock); + lock_unlock(render_lock); render_timer->end_of_cycle(); } @@ -965,7 +957,8 @@ static render_context* render_load() { camera* cam = rctx->camera; - cam->initialize(aspect, internal_3d_res.x, internal_3d_res.y); + cam->initialize(aspect, internal_3d_res.x, internal_3d_res.y, + internal_2d_res.x, internal_2d_res.y); //cam->set_position(cam, { 1.35542f, 1.41634f, 1.27852f }); //cam->rotate(cam, { -45.0, -32.5 }); //cam->set_position(cam, { -6.67555f, 4.68882f, -3.67537f }); @@ -977,14 +970,14 @@ static render_context* render_load() { cam->set_interest({ 0.0f, 1.375f, 0.0f }); imgui_context = ImGui::CreateContext(); - lock_init(&imgui_context_lock); + imgui_context_lock = new lock; - lock_lock(&imgui_context_lock); + lock_lock(imgui_context_lock); ImGui::SetCurrentContext(imgui_context); ImGuiIO& io = ImGui::GetIO(); io.IniFilename = 0; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - lock_unlock(&imgui_context_lock); + lock_unlock(imgui_context_lock); ImGui::StyleColorsDark(0); ImGui_ImplGlfw_InitForOpenGL(window, true); @@ -1037,15 +1030,15 @@ static void render_ctrl(render_context* rctx) { } global_context_menu = true; - lock_lock(&imgui_context_lock); + lock_lock(imgui_context_lock); ImGui::SetCurrentContext(imgui_context); app::TaskWork_Window(); classes_process_imgui(classes, classes_count); +#if DRAW_PASS_TIME_DISP ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ 1280, 636 }, ImGuiCond_Appearing); -#if DRAW_PASS_TIME_DISP if (ImGui::Begin("CPU/GPU Time")) { static const char* draw_pass_names[] = { "Shadow", @@ -1083,7 +1076,7 @@ static void render_ctrl(render_context* rctx) { size_t cpu_time_count = draw_pass_cpu_time[i].size(); if (cpu_time_count) cpu_avg /= (double_t)cpu_time_count; - + for (float_t& j : draw_pass_gpu_time[i]) { if (gpu_min > j) gpu_min = j; @@ -1107,17 +1100,18 @@ static void render_ctrl(render_context* rctx) { } #endif - lock_unlock(&imgui_context_lock); + lock_unlock(imgui_context_lock); if (old_width != width || old_height != height || old_scale_index != scale_index) { render_resize_fb(rctx, true); - cam->set_res(internal_3d_res.x, internal_3d_res.y); + cam->set_res(internal_3d_res.x, internal_3d_res.y, + internal_2d_res.x, internal_2d_res.y); } old_width = width; old_height = height; old_scale_index = scale_index; - lock_lock(&imgui_context_lock); + lock_lock(imgui_context_lock); ImGui::SetCurrentContext(imgui_context); if (global_context_menu && ImGui::IsMouseReleased(ImGuiMouseButton_Right) && !ImGui::IsItemHovered(0) && imgui_context->OpenPopupStack.Size < 1) @@ -1127,7 +1121,7 @@ static void render_ctrl(render_context* rctx) { render_imgui_context_menu(classes, classes_count, rctx); ImGui::EndPopup(); } - lock_unlock(&imgui_context_lock); + lock_unlock(imgui_context_lock); if (window_handle == GetForegroundWindow()) { if (input_reset) { @@ -1212,9 +1206,7 @@ static void cube_line_disp(shader_glsl* shader, camera* cam, vec3* trans, float_ mat4_get_translation(&mat[1], &t[1]); vec3 d; - vec2_sub(*(vec2*)&t[1], *(vec2*)&t[0], *(vec2*)&d); - vec2_normalize(*(vec2*)&d, *(vec2*)&d); - vec2_mult_scalar(*(vec2*)&d, line_size, *(vec2*)&d); + *(vec2*)&d = vec2::normalize(*(vec2*)&t[1] - *(vec2*)&t[0]) * line_size; d.z = 0.0f; vec3 norm[2]; @@ -1224,10 +1216,10 @@ static void cube_line_disp(shader_glsl* shader, camera* cam, vec3* trans, float_ mat4_mult_vec3(&cam->inv_view_rot, &norm[1], &norm[1]); vec3 vert_trans[4]; - vec3_add(trans[0], norm[0], vert_trans[0]); - vec3_add(trans[0], norm[1], vert_trans[1]); - vec3_add(trans[1], norm[0], vert_trans[2]); - vec3_add(trans[1], norm[1], vert_trans[3]); + vert_trans[0] = trans[0] + norm[0]; + vert_trans[1] = trans[0] + norm[1]; + vert_trans[2] = trans[1] + norm[0]; + vert_trans[3] = trans[1] + norm[1]; shader->set("color", *color); @@ -1241,6 +1233,7 @@ static int cube_line_points_sort(void const* src1, void const* src2) { return d1 > d2 ? -1 : (d1 < d2 ? 1 : 0); } +static bool auth_3d_disp = false; static bool rob_disp = false; static void render_disp(render_context* rctx) { @@ -1276,13 +1269,6 @@ static void render_disp(render_context* rctx) { glClearBufferfv(GL_DEPTH, 0, &depth_clear); gl_state_set_depth_mask(GL_FALSE); - if (set_clear_color) { - vec4 _clear_color; - vec4u8_to_vec4(clear_color, _clear_color); - vec4_mult_scalar(_clear_color, (float_t)(1.0 / 255.0), _clear_color); - glClearBufferfv(GL_COLOR, 0, (GLfloat*)&_clear_color); - } - cam->update(); rctx->disp(); @@ -1300,89 +1286,201 @@ static void render_disp(render_context* rctx) { vec4 exp_color = { 0.0f, 1.0f, 0.0f, 1.0f }; vec4 osg_color = { 0.0f, 0.0f, 1.0f, 1.0f }; vec4 osg_node_color = { 1.0f, 0.0f, 1.0f, 1.0f }; - for (int32_t i = 0; i < ROB_CHARA_COUNT && rob_disp; i++) { - if (rob_chara_pv_data_array[i].type == ROB_CHARA_TYPE_NONE) - continue; - - rob_chara* rob_chr = &rob_chara_array[i]; - if (~rob_chr->data.field_0 & 1) - continue; - - gl_state_bind_vertex_array(cube_line_vao); - gl_state_bind_array_buffer(cube_line_vbo); - rob_chara_bone_data* rob_bone_data = rob_chr->bone_data; - size_t object_bone_count = rob_bone_data->object_bone_count; - size_t total_bone_count = rob_bone_data->total_bone_count; - size_t ik_bone_count = rob_bone_data->ik_bone_count; - cube_line_shader->use(); - for (bone_node& j : rob_bone_data->nodes) { - if (!j.parent) + if (rob_disp) + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + if (rob_chara_pv_data_array[i].type == ROB_CHARA_TYPE_NONE) continue; - vec3 trans[2]; - mat4_get_translation(j.parent->mat, &trans[0]); - mat4_get_translation(j.mat, &trans[1]); + rob_chara* rob_chr = &rob_chara_array[i]; + if (~rob_chr->data.field_0 & 1) + continue; - if (memcmp(&trans[0], &trans[1], sizeof(vec3))) - cube_line_disp(cube_line_shader, cam, trans, CUBE_LINE_SIZE, &bone_color); - } - gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(cube_line_vao); + gl_state_bind_array_buffer(cube_line_vbo); + rob_chara_bone_data* rob_bone_data = rob_chr->bone_data; + size_t object_bone_count = rob_bone_data->object_bone_count; + size_t total_bone_count = rob_bone_data->total_bone_count; + size_t ik_bone_count = rob_bone_data->ik_bone_count; + cube_line_shader->use(); + for (bone_node& j : rob_bone_data->nodes) { + if (!j.parent) + continue; - std::vector> cube_line_points; - for (bone_node& j : rob_bone_data->nodes) { - vec3 trans; - mat4_get_translation(j.mat, &trans); - cube_line_points.push_back({ trans, 0.0f }); + vec3 trans[2]; + mat4_get_translation(j.parent->mat, &trans[0]); + mat4_get_translation(j.mat, &trans[1]); + + if (memcmp(&trans[0], &trans[1], sizeof(vec3))) + cube_line_disp(cube_line_shader, cam, trans, CUBE_LINE_SIZE, &bone_color); + } + gl_state_bind_array_buffer(0); + + std::vector> cube_line_points; + for (bone_node& j : rob_bone_data->nodes) { + vec3 trans; + vec3 vp_trans; + mat4_get_translation(j.mat, &trans); + mat4_mult_vec3(&cam->view_projection, &trans, &vp_trans); + cube_line_points.push_back({ trans, vp_trans.z }); + } + + quicksort_custom(cube_line_points.data(), cube_line_points.size(), + sizeof(std::pair), cube_line_points_sort); + + gl_state_bind_array_buffer(cube_line_point_instance_vbo); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(sizeof(std::pair) + * cube_line_points.size()), cube_line_points.data(), GL_STREAM_DRAW); + gl_state_bind_array_buffer(0); + + vec3 trans[4]; + trans[0] = { -CUBE_LINE_POINT_SIZE, CUBE_LINE_POINT_SIZE, 0.0f }; + trans[1] = { CUBE_LINE_POINT_SIZE, CUBE_LINE_POINT_SIZE, 0.0f }; + trans[2] = { -CUBE_LINE_POINT_SIZE, -CUBE_LINE_POINT_SIZE, 0.0f }; + trans[3] = { CUBE_LINE_POINT_SIZE, -CUBE_LINE_POINT_SIZE, 0.0f }; + + mat4_mult_vec3(&cam->inv_view_rot, &trans[0], &trans[0]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[1], &trans[1]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[2], &trans[2]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[3], &trans[3]); + + gl_state_bind_vertex_array(cube_line_point_vao); + cube_line_point_shader->use(); + cube_line_point_shader->set("trans", 4, trans); + cube_line_point_shader->set("border_end", + ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE))); + cube_line_point_shader->set("border_start", + (1.0f - ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE)))); + cube_line_point_shader->set("border_color", 0.0f, 0.0f, 0.0f); + cube_line_point_shader->set("center_color", 1.0f, 1.0f, 1.0f); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)cube_line_points.size()); + gl_state_bind_vertex_array(0); + cube_line_points.clear(); + cube_line_points.shrink_to_fit(); } - motion_blend_mot* mot = rob_chr->bone_data->motion_loaded.front(); - mot_key_set* key_set = mot->mot_key_data.mot.key_sets; - for (bone_data& j :mot->bone_data.bones) - if (j.type >= BONE_DATABASE_BONE_HEAD_IK_ROTATION - && j.type <= BONE_DATABASE_BONE_LEGS_IK_ROTATION) - cube_line_points.push_back({ j.ik_target, 0.0f }); + if (auth_3d_disp) + for (auth_3d& i : auth_3d_data->data) { + if (i.id == -1 || !i.visible) + continue; - for (std::pair& i : cube_line_points) { - vec3 trans; - mat4_mult_vec3(&cam->view_projection, &i.first, &trans); - i.second = trans.z; + for (auth_3d_object_hrc& j : i.object_hrc) { + if (!j.node[0].model_transform.visible) + continue; + + gl_state_bind_vertex_array(cube_line_vao); + gl_state_bind_array_buffer(cube_line_vbo); + cube_line_shader->use(); + for (auth_3d_object_node& k : j.node) { + if (k.parent == -1 ) + continue; + + vec3 trans[2]; + mat4_get_translation(&j.node[k.parent].model_transform.mat, &trans[0]); + mat4_get_translation(&k.model_transform.mat, &trans[1]); + + if (memcmp(&trans[0], &trans[1], sizeof(vec3))) + cube_line_disp(cube_line_shader, cam, trans, CUBE_LINE_SIZE, &osg_color); + } + gl_state_bind_array_buffer(0); + + std::vector> cube_line_points; + for (auth_3d_object_node& k : j.node) { + vec3 trans; + vec3 vp_trans; + mat4_get_translation(&k.model_transform.mat, &trans); + mat4_mult_vec3(&cam->view_projection, &trans, &vp_trans); + cube_line_points.push_back({ trans, vp_trans.z }); + } + + quicksort_custom(cube_line_points.data(), cube_line_points.size(), + sizeof(std::pair), cube_line_points_sort); + + gl_state_bind_array_buffer(cube_line_point_instance_vbo); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(sizeof(std::pair) + * cube_line_points.size()), cube_line_points.data(), GL_STREAM_DRAW); + gl_state_bind_array_buffer(0); + + vec3 trans[4]; + trans[0] = { -CUBE_LINE_POINT_SIZE, CUBE_LINE_POINT_SIZE, 0.0f }; + trans[1] = { CUBE_LINE_POINT_SIZE, CUBE_LINE_POINT_SIZE, 0.0f }; + trans[2] = { -CUBE_LINE_POINT_SIZE, -CUBE_LINE_POINT_SIZE, 0.0f }; + trans[3] = { CUBE_LINE_POINT_SIZE, -CUBE_LINE_POINT_SIZE, 0.0f }; + + mat4_mult_vec3(&cam->inv_view_rot, &trans[0], &trans[0]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[1], &trans[1]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[2], &trans[2]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[3], &trans[3]); + + gl_state_bind_vertex_array(cube_line_point_vao); + cube_line_point_shader->use(); + cube_line_point_shader->set("trans", 4, trans); + cube_line_point_shader->set("border_end", + ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE))); + cube_line_point_shader->set("border_start", + (1.0f - ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE)))); + cube_line_point_shader->set("border_color", 0.0f, 0.0f, 0.0f); + cube_line_point_shader->set("center_color", 1.0f, 1.0f, 1.0f); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)cube_line_points.size()); + gl_state_bind_vertex_array(0); + cube_line_points.clear(); + cube_line_points.shrink_to_fit(); + } } - quicksort_custom(cube_line_points.data(), cube_line_points.size(), - sizeof(std::pair), cube_line_points_sort); + if (rob_disp) + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + if (rob_chara_pv_data_array[i].type == ROB_CHARA_TYPE_NONE) + continue; - gl_state_bind_array_buffer(cube_line_point_instance_vbo); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(sizeof(std::pair) - * cube_line_points.size()), cube_line_points.data(), GL_STREAM_DRAW); - gl_state_bind_array_buffer(0); + rob_chara* rob_chr = &rob_chara_array[i]; + if (~rob_chr->data.field_0 & 1) + continue; - vec3 trans[4]; - trans[0] = { -1.0, 1.0, 0.0 }; - trans[1] = { 1.0, 1.0, 0.0 }; - trans[2] = { -1.0, -1.0, 0.0 }; - trans[3] = { 1.0, -1.0, 0.0 }; + std::vector> cube_line_points; + motion_blend_mot* mot = rob_chr->bone_data->motion_loaded.front(); + mot_key_set* key_set = mot->mot_key_data.mot.key_sets; + for (bone_data& j : mot->bone_data.bones) + if (j.type >= BONE_DATABASE_BONE_HEAD_IK_ROTATION + && j.type <= BONE_DATABASE_BONE_LEGS_IK_ROTATION) { + vec3 trans; + mat4_mult_vec3(&cam->view_projection, &j.ik_target, &trans); + cube_line_points.push_back({ j.ik_target, trans.z }); + } - vec3_mult_scalar(trans[0], CUBE_LINE_POINT_SIZE, trans[0]); - vec3_mult_scalar(trans[1], CUBE_LINE_POINT_SIZE, trans[1]); - vec3_mult_scalar(trans[2], CUBE_LINE_POINT_SIZE, trans[2]); - vec3_mult_scalar(trans[3], CUBE_LINE_POINT_SIZE, trans[3]); + quicksort_custom(cube_line_points.data(), cube_line_points.size(), + sizeof(std::pair), cube_line_points_sort); - mat4_mult_vec3(&cam->inv_view_rot, &trans[0], &trans[0]); - mat4_mult_vec3(&cam->inv_view_rot, &trans[1], &trans[1]); - mat4_mult_vec3(&cam->inv_view_rot, &trans[2], &trans[2]); - mat4_mult_vec3(&cam->inv_view_rot, &trans[3], &trans[3]); + gl_state_bind_array_buffer(cube_line_point_instance_vbo); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(sizeof(std::pair) + * cube_line_points.size()), cube_line_points.data(), GL_STREAM_DRAW); + gl_state_bind_array_buffer(0); + + vec3 trans[4]; + trans[0] = { -CUBE_LINE_POINT_SIZE, CUBE_LINE_POINT_SIZE, 0.0f }; + trans[1] = { CUBE_LINE_POINT_SIZE, CUBE_LINE_POINT_SIZE, 0.0f }; + trans[2] = { -CUBE_LINE_POINT_SIZE, -CUBE_LINE_POINT_SIZE, 0.0f }; + trans[3] = { CUBE_LINE_POINT_SIZE, -CUBE_LINE_POINT_SIZE, 0.0f }; + + mat4_mult_vec3(&cam->inv_view_rot, &trans[0], &trans[0]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[1], &trans[1]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[2], &trans[2]); + mat4_mult_vec3(&cam->inv_view_rot, &trans[3], &trans[3]); + + gl_state_bind_vertex_array(cube_line_point_vao); + cube_line_point_shader->use(); + cube_line_point_shader->set("trans", 4, trans); + cube_line_point_shader->set("border_end", + ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE))); + cube_line_point_shader->set("border_start", + (1.0f - ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE)))); + cube_line_point_shader->set("border_color", 0.0f, 0.0f, 0.0f); + cube_line_point_shader->set("center_color", 0.0f, 1.0f, 0.0f); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)cube_line_points.size()); + gl_state_bind_vertex_array(0); + cube_line_points.clear(); + cube_line_points.shrink_to_fit(); + } - gl_state_bind_vertex_array(cube_line_point_vao); - cube_line_point_shader->use(); - cube_line_point_shader->set("trans", 4, trans); - cube_line_point_shader->set("dark_border_end", - ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE))); - cube_line_point_shader->set("dark_border_start", - (1.0f - ((CUBE_LINE_POINT_SIZE - (CUBE_LINE_SIZE * 1.125f)) / (2.0f * CUBE_LINE_POINT_SIZE)))); - glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)cube_line_points.size()); - cube_line_points.clear(); - cube_line_points.shrink_to_fit(); - } gl_state_bind_vertex_array(0); gl_state_enable_cull_face(); gl_state_bind_framebuffer(0); @@ -1420,7 +1518,8 @@ static void render_dispose(render_context* rctx) { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(imgui_context); - lock_free(&imgui_context_lock); + delete imgui_context_lock; + imgui_context_lock = 0; //pv_game_data.SetDest(); Glitter::glt_particle_manager_free_task(); @@ -1433,12 +1532,13 @@ static void render_dispose(render_context* rctx) { render_timer->reset(); while (app::task_work->tasks.size()) { render_timer->start_of_cycle(); - lock_lock(&render_lock); + lock_lock(render_lock); game_state_ctrl(); app::TaskWork::Ctrl(); + sound_ctrl(); file_handler_storage_ctrl(); app::TaskWork::Basic(); - lock_unlock(&render_lock); + lock_unlock(render_lock); render_timer->end_of_cycle(); } @@ -1459,6 +1559,15 @@ static void render_dispose(render_context* rctx) { cube_line_shader = 0; } + sound_work_unload_farc("rom/sound/se.farc"); + sound_work_unload_farc("rom/sound/button.farc"); + sound_work_unload_farc("rom/sound/se_cmn.farc"); + sound_work_unload_farc("rom/sound/se_sel.farc"); + sound_work_unload_farc("rom/sound/se_aime.farc"); + sound_work_unload_farc("rom/sound/pvchange.farc"); + sound_work_unload_farc("rom/sound/slide_se.farc"); + sound_work_unload_farc("rom/sound/slide_long.farc"); + object_storage_unload_set(dbg_set_id); task_data_test_glitter_particle_free(); @@ -1477,12 +1586,6 @@ static void render_dispose(render_context* rctx) { task_wind_free(); rob_free(); - app::task_work_free(); - - item_table_array_free(); - object_storage_free(); - data_struct_free(); - glDeleteBuffers(1, &common_data_ubo); glDeleteBuffers(1, &grid_vbo); glDeleteBuffers(1, &cube_line_point_instance_vbo); @@ -1490,25 +1593,34 @@ static void render_dispose(render_context* rctx) { glDeleteBuffers(1, &cube_line_vbo); glDeleteVertexArrays(1, &cube_line_vao); - motion_storage_free(); - mothead_storage_free(); + app::task_work_free(); + + rand_state_array_free(); + item_table_array_free(); + object_storage_free(); + wave_audio_storage_free(); + sound_free(); + render_shaders_free(); + osage_setting_data_free(); + data_struct_free(); + + osage_setting_data_free(); + mothead_storage_free(); + motion_storage_free(); + render_texture_data_free(); - delete rctx; file_handler_storage_free(); - - texture_storage_free(); - - render_shaders_free(); + delete rctx; } static void render_imgui(render_context* rctx) { - lock_lock(&imgui_context_lock); + lock_lock(imgui_context_lock); ImGui::SetCurrentContext(imgui_context); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - lock_unlock(&imgui_context_lock); + lock_unlock(imgui_context_lock); } static bool render_load_shaders(void* data, const char* path, const char* file, uint32_t hash) { @@ -1560,8 +1672,8 @@ static void render_resize_fb(render_context* rctx, bool change_fb) { internal_res.x = (int32_t)res_width; internal_res.y = (int32_t)res_height; - internal_2d_res.x = clamp(internal_res.x, 1, sv_max_texture_size); - internal_2d_res.y = clamp(internal_res.y, 1, sv_max_texture_size); + internal_2d_res.x = clamp_def(internal_res.x, 1, sv_max_texture_size); + internal_2d_res.y = clamp_def(internal_res.y, 1, sv_max_texture_size); #if BAKE_PNG || BAKE_VIDEO internal_3d_res.x = (int32_t)roundf((float_t)(internal_res.x * 2)); internal_3d_res.y = (int32_t)roundf((float_t)(internal_res.y * 2)); @@ -1569,8 +1681,8 @@ static void render_resize_fb(render_context* rctx, bool change_fb) { internal_3d_res.x = (int32_t)roundf((float_t)(internal_res.x * render_scale_table[scale_index])); internal_3d_res.y = (int32_t)roundf((float_t)(internal_res.y * render_scale_table[scale_index])); #endif - internal_3d_res.x = clamp(internal_3d_res.x, 1, sv_max_texture_size); - internal_3d_res.y = clamp(internal_3d_res.y, 1, sv_max_texture_size); + internal_3d_res.x = clamp_def(internal_3d_res.x, 1, sv_max_texture_size); + internal_3d_res.y = clamp_def(internal_3d_res.y, 1, sv_max_texture_size); bool fb_changed = old_internal_2d_res.x != internal_2d_res.x || old_internal_2d_res.y != internal_2d_res.y @@ -1580,12 +1692,7 @@ static void render_resize_fb(render_context* rctx, bool change_fb) { old_internal_2d_res = internal_2d_res; old_internal_3d_res = internal_3d_res; - bool st = false; - lock_lock(&state_lock); - st = state == RENDER_INITIALIZED; - lock_unlock(&state_lock); - - if (st && fb_changed && change_fb) { + if (fb_changed && change_fb) { rctx->post_process.init_fbo(internal_3d_res.x, internal_3d_res.y, internal_2d_res.x, internal_2d_res.y, width, height); rctx->litproj->resize(internal_3d_res.x, internal_3d_res.y); @@ -1594,6 +1701,8 @@ static void render_resize_fb(render_context* rctx, bool change_fb) { static void render_imgui_context_menu(classes_data* classes, const size_t classes_count, render_context* rctx) { +#pragma warning(disable:26115) +#pragma warning(disable:26117) for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; if (!c->name || ~c->flags & CLASSES_IN_CONTEXT_MENU) @@ -1610,23 +1719,22 @@ static void render_imgui_context_menu(classes_data* classes, ImGui::MenuItem(c->name, 0, false, false); else if (ImGui::MenuItem(c->name, 0)) { if (~c->data.flags & CLASS_INIT) { - lock_init(&c->data.lock); - if (lock_check_init(&c->data.lock) && c->init) { - lock_lock(&c->data.lock); + c->data.lock = new lock; + if (c->data.lock->check_init() && c->init) { + lock_lock(c->data.lock); if (c->init(&c->data, rctx)) c->data.flags = CLASS_INIT; else c->data.flags = (class_flags)(CLASS_DISPOSED | CLASS_HIDDEN); - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } } - if (lock_check_init(&c->data.lock)) { - lock_lock(&c->data.lock); - if (c->data.flags & CLASS_INIT && ((c->show && c->show(&c->data)) || !c->show)) { + if (c->data.lock->check_init()) { + lock_lock(c->data.lock); + if (c->data.flags & CLASS_INIT && ((c->show && c->show(&c->data)) || !c->show)) enum_and(c->data.flags, ~(CLASS_HIDE | CLASS_HIDDEN | CLASS_HIDE_WINDOW)); - } - lock_unlock(&c->data.lock); + lock_unlock(c->data.lock); } } } diff --git a/src/ReDIVA/render.hpp b/src/ReDIVA/render.hpp index 3952c0d1..684532fe 100644 --- a/src/ReDIVA/render.hpp +++ b/src/ReDIVA/render.hpp @@ -36,7 +36,7 @@ struct render_init_struct { extern const double_t render_scale_table[]; -extern int32_t render_main(void* arg); +extern int32_t render_main(render_init_struct* ris); extern double_t render_get_scale(); extern int32_t render_get_scale_index(); extern void render_set_scale_index(int32_t index); diff --git a/src/ReDIVA/shared.cpp b/src/ReDIVA/shared.cpp index 46a8a2f5..998ba57f 100644 --- a/src/ReDIVA/shared.cpp +++ b/src/ReDIVA/shared.cpp @@ -103,7 +103,3 @@ classes_data classes[] = { }; const size_t classes_count = sizeof(classes) / sizeof(classes_data); - -render_state state; -thread_flag thread_flags; -lock state_lock; diff --git a/src/ReDIVA/shared.hpp b/src/ReDIVA/shared.hpp index d80f8f38..ed58300b 100644 --- a/src/ReDIVA/shared.hpp +++ b/src/ReDIVA/shared.hpp @@ -10,22 +10,5 @@ #include #include -enum render_state { - RENDER_UNINITIALIZED = 0, - RENDER_INITIALIZING = 1, - RENDER_INITIALIZED = 2, - RENDER_DISPOSING = 3, - RENDER_DISPOSED = 4, -}; - -enum thread_flag { - THREAD_RENDER = 0x01, - THREAD_SOUND = 0x02, - THREAD_INPUT = 0x04, -}; - extern classes_data classes[]; extern const size_t classes_count; -extern render_state state; -extern thread_flag thread_flags; -extern lock state_lock; diff --git a/src/ReDIVA/sound.cpp b/src/ReDIVA/sound.cpp deleted file mode 100644 index 653bd84a..00000000 --- a/src/ReDIVA/sound.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "sound.hpp" -#include "../CRE/timer.hpp" -#include - -timer* sound_timer; - -extern bool close; - -int32_t sound_main(void* arg) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - timeBeginPeriod(1); - sound_timer = new timer(60.0); - - bool state_wait = false; - bool state_disposed = false; - do { - lock_lock(&state_lock); - state_wait = state != RENDER_INITIALIZING; - state_disposed = state == RENDER_DISPOSING; - lock_unlock(&state_lock); - if (state_disposed) { - delete sound_timer; - return 0; - } - sound_timer->sleep(0.0625); - } while (state_wait); - - lock_lock(&state_lock); - enum_or(thread_flags, THREAD_SOUND); - lock_unlock(&state_lock); - - bool local_close = false; - sound_timer->reset(); - while (!close && !local_close) { - sound_timer->start_of_cycle(); - lock_lock(&state_lock); - local_close = state == RENDER_DISPOSING; - lock_unlock(&state_lock); - - classes_process_sound(classes, classes_count); - sound_timer->end_of_cycle(); - } - delete sound_timer; - - lock_lock(&state_lock); - enum_and(thread_flags, ~THREAD_SOUND); - lock_unlock(&state_lock); - return 0; -} diff --git a/src/ReDIVA/sound.hpp b/src/ReDIVA/sound.hpp deleted file mode 100644 index c9d727bd..00000000 --- a/src/ReDIVA/sound.hpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "shared.hpp" - -extern int32_t sound_main(void* arg); diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index e7acb85f..c16090ba 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -1,4 +1,4 @@ -/* +/* by korenkonder GitHub/GitLab: korenkonder @@ -15,6 +15,7 @@ #include "../CRE/object.hpp" #include "../CRE/pv_expression.hpp" #include "../CRE/pv_param.hpp" +#include "../CRE/sound.hpp" #include "../KKdLib/farc.hpp" #include "../KKdLib/interpolation.hpp" #include "../KKdLib/sort.hpp" @@ -560,6 +561,19 @@ x_pv_play_data::~x_pv_play_data() { } void x_pv_play_data::reset() { + if (rob_chr) { + data_struct* aft_data = &data_list[DATA_AFT]; + bone_database* aft_bone_data = &aft_data->data_ft.bone_data; + motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + + int32_t mottbl_index = hand_anim_id_to_mottbl_index(2); + + rob_chr->reset_data(&rob_chr->pv_data, aft_bone_data, aft_mot_db); + rob_chr->set_hand_l_mottbl_motion(0, mottbl_index, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + rob_chr->set_hand_r_mottbl_motion(0, mottbl_index, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + rob_chr->set_visibility(false); + } + motion.clear(); motion.shrink_to_fit(); rob_chr = 0; @@ -713,7 +727,8 @@ x_pv_game_song_effect_glitter::x_pv_game_song_effect_glitter() : scene_counter() void x_pv_game_song_effect_glitter::reset() { name.str.clear(); name.str.shrink_to_fit(); - name.hash = hash_murmurhash_empty; + name.hash_fnv1a64m = hash_fnv1a64m_empty; + name.hash_murmurhash = hash_murmurhash_empty; scene_counter = 0; field_8 = false; for (bool& i : field_9) @@ -749,10 +764,10 @@ x_pv_game_camera::~x_pv_game_camera() { void x_pv_game_camera::ctrl(float_t curr_time) { switch (state) { case 10: { - if (!auth_3d_data_check_category_loaded(category.hash)) + if (!auth_3d_data_check_category_loaded(category.hash_murmurhash)) break; - int32_t id = auth_3d_data_load_hash(file.hash, &data_list[DATA_X], 0, 0); + int32_t id = auth_3d_data_load_hash(file.hash_murmurhash, &data_list[DATA_X], 0, 0); if (auth_3d_data_check_id_not_empty(&id)) { auth_3d_data_read_file_modern(&id); auth_3d_data_set_enable(&id, false); @@ -799,7 +814,7 @@ void x_pv_game_camera::load_data() { if (state || !category.str.size()) return; - auth_3d_data_load_category(&data_list[DATA_X], category.c_str(), category.hash); + auth_3d_data_load_category(&data_list[DATA_X], category.c_str(), category.hash_murmurhash); state = 10; } @@ -807,10 +822,12 @@ void x_pv_game_camera::reset() { state = 0; category.str.clear(); category.str.shrink_to_fit(); - category.hash = hash_murmurhash_empty; + category.hash_fnv1a64m = hash_fnv1a64m_empty; + category.hash_murmurhash = hash_murmurhash_empty; file.str.clear(); file.str.shrink_to_fit(); - file.hash = hash_murmurhash_empty; + file.hash_fnv1a64m = hash_fnv1a64m_empty; + file.hash_murmurhash = hash_murmurhash_empty; auth_3d_id = -1; } @@ -824,7 +841,7 @@ void x_pv_game_camera::unload() { return; auth_3d_data_unload_id(auth_3d_id, rctx_ptr); - auth_3d_data_unload_category(category.hash); + auth_3d_data_unload_category(category.hash_murmurhash); state = 0; } @@ -843,12 +860,12 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { bool wait_load = false; for (string_hash& i : pv_auth_3d) - if (!auth_3d_data_check_category_loaded(i.hash)) + if (!auth_3d_data_check_category_loaded(i.hash_murmurhash)) wait_load |= true; for (string_hash& i : pv_obj_set) - if (object_storage_get_obj_set_handler(i.hash) - && object_storage_load_obj_set_check_not_read(i.hash, obj_db, tex_db)) + if (object_storage_get_obj_set_handler(i.hash_murmurhash) + && object_storage_load_obj_set_check_not_read(i.hash_murmurhash, obj_db, tex_db)) wait_load |= true; if (wait_load) @@ -863,7 +880,7 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { x_pv_game_song_effect& song_effect = this->song_effect[i]; pvpp_effect& effect = play_param->effect[i]; for (string_hash& j : effect.auth_3d) { - int32_t id = auth_3d_data_load_hash(j.hash, x_data, obj_db, tex_db); + int32_t id = auth_3d_data_load_hash(j.hash_murmurhash, x_data, obj_db, tex_db); if (!auth_3d_data_check_id_not_empty(&id)) { continue; } @@ -890,7 +907,7 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { wait_load |= true; for (string_hash& i : pv_glitter) - if (!Glitter::glt_particle_manager->CheckNoFileReaders(i.hash)) + if (!Glitter::glt_particle_manager->CheckNoFileReaders(i.hash_murmurhash)) wait_load |= true; if (wait_load) @@ -917,7 +934,7 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { if (k < play_param->chara.size()) { pvpp_chara& chara = play_param->chara[k]; for (pvpp_glitter& l : chara.glitter) - if (j.name.hash == l.name.hash) { + if (j.name.hash_murmurhash == l.name.hash_murmurhash) { v121 = true; break; } @@ -931,7 +948,7 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { data_struct* x_data = &data_list[DATA_X]; for (string_hash& i : pv_glitter) { - Glitter::EffectGroup* eff_group = Glitter::glt_particle_manager->GetEffectGroup(i.hash); + Glitter::EffectGroup* eff_group = Glitter::glt_particle_manager->GetEffectGroup(i.hash_murmurhash); if (eff_group && eff_group->CheckModel()) eff_group->LoadModel(x_data); } @@ -943,7 +960,7 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { bool wait_load = false; for (string_hash& i : pv_glitter) { - Glitter::EffectGroup* eff_group = Glitter::glt_particle_manager->GetEffectGroup(i.hash); + Glitter::EffectGroup* eff_group = Glitter::glt_particle_manager->GetEffectGroup(i.hash_murmurhash); if (eff_group && eff_group->CheckLoadModel()) wait_load |= true; } @@ -979,10 +996,10 @@ void x_pv_game_effect::load(int32_t pv_id, pvpp* play_param, FrameRateControl* f char buf[0x100]; size_t len = sprintf_s(buf, sizeof(buf), "A3D_EFFPV%03d", pv_id); - pv_auth_3d.push_back({ std::string(buf, len), hash_murmurhash(buf, len) }); + pv_auth_3d.push_back(std::string(buf, len)); len = sprintf_s(buf, sizeof(buf), "effpv%03d", 800 + (pv_id % 100)); - pv_obj_set.push_back({ std::string(buf, len), hash_murmurhash(buf, len) }); + pv_obj_set.push_back(std::string(buf, len)); break; } } @@ -994,10 +1011,10 @@ void x_pv_game_effect::load_data(int32_t pv_id) { data_struct* x_data = &data_list[DATA_X]; for (string_hash& i : pv_obj_set) - object_storage_load_set_hash(x_data, i.hash); + object_storage_load_set_hash(x_data, i.hash_murmurhash); for (string_hash& i : pv_auth_3d) - auth_3d_data_load_category(x_data, i.c_str(), i.hash); + auth_3d_data_load_category(x_data, i.c_str(), i.hash_murmurhash); size_t effect_count = play_param->effect.size(); for (size_t i = 0; i < effect_count; i++) { @@ -1010,7 +1027,7 @@ void x_pv_game_effect::load_data(int32_t pv_id) { uint32_t hash = (uint32_t)Glitter::glt_particle_manager->LoadFile(Glitter::X, x_data, buf, 0, -1.0f, false, 0); if (hash != hash_murmurhash_empty) - pv_glitter.push_back({ buf, hash }); + pv_glitter.push_back(std::string(buf, len)); break; } @@ -1075,7 +1092,7 @@ void x_pv_game_effect::set_song_effect(int32_t index, int64_t time) { } for (x_pv_game_song_effect_glitter& i : song_effect.glitter) { - i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(i.name.hash, i.name.c_str()); + i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(i.name.hash_murmurhash, i.name.c_str()); if (!i.scene_counter) continue; @@ -1143,7 +1160,7 @@ void x_pv_game_effect::stop() { stop_song_effect((int32_t)i, false); for (string_hash& i : pv_glitter) - Glitter::glt_particle_manager->FreeScene(i.hash); + Glitter::glt_particle_manager->FreeScene(i.hash_murmurhash); } void x_pv_game_effect::stop_song_effect(int32_t index, bool free_glitter) { @@ -1178,7 +1195,7 @@ void x_pv_game_effect::unload() { stop_song_effect((int32_t)i, false); for (string_hash& i : pv_glitter) - Glitter::glt_particle_manager->FreeScene(i.hash); + Glitter::glt_particle_manager->FreeScene(i.hash_murmurhash); for (x_pv_game_song_effect& i : song_effect) for (x_pv_game_song_effect_auth_3d& j : i.auth_3d) { @@ -1187,17 +1204,17 @@ void x_pv_game_effect::unload() { } for (string_hash& i : pv_auth_3d) - auth_3d_data_unload_category(i.hash); + auth_3d_data_unload_category(i.hash_murmurhash); for (string_hash& i : pv_obj_set) - object_storage_unload_set(i.hash); + object_storage_unload_set(i.hash_murmurhash); for (string_hash& i : pv_glitter) { - Glitter::EffectGroup* eff_group = Glitter::glt_particle_manager->GetEffectGroup(i.hash); + Glitter::EffectGroup* eff_group = Glitter::glt_particle_manager->GetEffectGroup(i.hash_murmurhash); if (eff_group) eff_group->FreeModel(); - Glitter::glt_particle_manager->UnloadEffectGroup(i.hash); + Glitter::glt_particle_manager->UnloadEffectGroup(i.hash_murmurhash); } song_effect.clear(); @@ -1221,13 +1238,16 @@ void x_pv_game_chara_effect_auth_3d::reset() { dst_chara = CHARA_MAX; file.str.clear(); file.str.shrink_to_fit(); - file.hash = hash_murmurhash_empty; + file.hash_fnv1a64m = hash_fnv1a64m_empty; + file.hash_murmurhash = hash_murmurhash_empty; category.str.clear(); category.str.shrink_to_fit(); - category.hash = hash_murmurhash_empty; + category.hash_fnv1a64m = hash_fnv1a64m_empty; + category.hash_murmurhash = hash_murmurhash_empty; object_set.str.clear(); object_set.str.shrink_to_fit(); - object_set.hash = hash_murmurhash_empty; + object_set.hash_fnv1a64m = hash_fnv1a64m_empty; + object_set.hash_murmurhash = hash_murmurhash_empty; id = -1; time = -1; } @@ -1250,11 +1270,11 @@ void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex if (!j.category.str.size()) continue; - if (!auth_3d_data_check_category_loaded(j.category.hash)) + if (!auth_3d_data_check_category_loaded(j.category.hash_murmurhash)) wait_load |= true; - if (object_storage_get_obj_set_handler(j.object_set.hash) - && object_storage_load_obj_set_check_not_read(j.object_set.hash, obj_db, tex_db)) + if (object_storage_get_obj_set_handler(j.object_set.hash_murmurhash) + && object_storage_load_obj_set_check_not_read(j.object_set.hash_murmurhash, obj_db, tex_db)) wait_load |= true; } @@ -1264,11 +1284,11 @@ void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex data_struct* x_data = &data_list[DATA_X]; for (std::vector& i : auth_3d) - for (x_pv_game_chara_effect_auth_3d j : i) { + for (x_pv_game_chara_effect_auth_3d& j : i) { if (!j.category.str.size()) continue; - int32_t id = auth_3d_data_load_hash(j.file.hash, x_data, obj_db, tex_db); + int32_t id = auth_3d_data_load_hash(j.file.hash_murmurhash, x_data, obj_db, tex_db); if (!auth_3d_data_check_id_not_empty(&id)) { j.id = -1; continue; @@ -1352,15 +1372,14 @@ void x_pv_game_chara_effect::load(int32_t pv_id, pvpp* play_param, if (src_chara != dst_chara) { - size_t pos = 0; - pos = object_set.find(src_chara_str); + size_t pos = object_set.find(dst_chara_str); if (pos && pos != -1) - object_set.replace(pos, src_chara_str.size(), dst_chara_str); + object_set.replace(pos, dst_chara_str.size(), src_chara_str); if (!auth_3d.field_0) { - size_t pos = file.find(src_chara_str); + size_t pos = file.find(dst_chara_str); if (pos != -1) - file = file.replace(pos, src_chara_str.size(), dst_chara_str); + file = file.replace(pos, dst_chara_str.size(), src_chara_str); } } @@ -1392,11 +1411,11 @@ void x_pv_game_chara_effect::load_data() { if (!j.category.str.size()) continue; - auth_3d_data_load_category(x_data, j.category.c_str(), j.category.hash); - object_storage_load_set_hash(x_data, j.object_set.hash); + auth_3d_data_load_category(x_data, j.category.c_str(), j.category.hash_murmurhash); + object_storage_load_set_hash(x_data, j.object_set.hash_murmurhash); } - state = 10; + state = 20; } void x_pv_game_chara_effect::reset() { @@ -1501,8 +1520,8 @@ void x_pv_game_chara_effect::unload() { continue; auth_3d_data_unload_id(j.id, rctx_ptr); - auth_3d_data_unload_category(j.category.hash); - object_storage_unload_set(j.object_set.hash); + auth_3d_data_unload_category(j.category.hash_murmurhash); + object_storage_unload_set(j.object_set.hash_murmurhash); } state = 10; } @@ -1626,7 +1645,7 @@ int64_t x_pv_game_dsc_data::find_pv_end() { i = dsc.data.data(); i_end = dsc.data.data() + dsc.data.size(); find(DSC_X_END, &end_time, &pv_branch_mode, i, i_end); - return max(pv_end_time, end_time); + return max_def(pv_end_time, end_time); } void x_pv_game_dsc_data::find_stage_effects(std::vector>& stage_effects) { @@ -1711,7 +1730,7 @@ void x_pv_game_data::ctrl(float_t curr_time, float_t delta_time) { case 20: { effect.load_data(pv_id); chara_effect.load_data(); - pv_expression_file_load(&data_list[DATA_X], "root+/pv_expression/", exp_file.hash); + pv_expression_file_load(&data_list[DATA_X], "root+/pv_expression/", exp_file.hash_murmurhash); state = 21; } break; case 21: { @@ -1725,7 +1744,7 @@ void x_pv_game_data::ctrl(float_t curr_time, float_t delta_time) { case 22: { bool wait_load = false; - wait_load |= pv_expression_file_check_not_ready(exp_file.hash); + wait_load |= pv_expression_file_check_not_ready(exp_file.hash_murmurhash); wait_load |= camera.state && camera.state != 20; wait_load |= effect.state && effect.state != 20; wait_load |= chara_effect.state && chara_effect.state != 10 && chara_effect.state != 30; @@ -1809,8 +1828,8 @@ void x_pv_game_data::load(int32_t pv_id, FrameRateControl* frame_rate_control, c chara_effect.load(pv_id, play_param, frame_rate_control, charas); char buf[0x100]; - sprintf_s(buf, sizeof(buf), "exp_PV%03d", pv_id); - exp_file = { buf, hash_utf8_murmurhash(buf) }; + size_t len = sprintf_s(buf, sizeof(buf), "exp_PV%03d", pv_id); + exp_file = std::string(buf, len); camera.load(pv_id, stage->stage_id, frame_rate_control); @@ -1819,6 +1838,7 @@ void x_pv_game_data::load(int32_t pv_id, FrameRateControl* frame_rate_control, c void x_pv_game_data::reset() { pv_id = 0; + play_param_file_handler.free_data(); if (play_param) { delete play_param; play_param = 0; @@ -1837,11 +1857,14 @@ void x_pv_game_data::reset() { next_stage_effect_bar = 0; stage_effects.clear(); stage_effects.shrink_to_fit(); + camera.reset(); effect.reset(); + chara_effect.reset(); dsc_data.reset(); exp_file.str.clear(); exp_file.str.shrink_to_fit(); - exp_file.hash = hash_murmurhash_empty; + exp_file.hash_fnv1a64m = hash_fnv1a64m_empty; + exp_file.hash_murmurhash = hash_murmurhash_empty; //dof = {}; stage = 0; obj_db.object_set.clear(); @@ -1869,7 +1892,7 @@ void x_pv_game_data::unload() { chara_effect.unload(); //dof = {}; dsc_data.unload(); - pv_expression_file_unload(exp_file.hash); + pv_expression_file_unload(exp_file.hash_murmurhash); obj_db.object_set.clear(); obj_db.object_set.shrink_to_fit(); tex_db.texture.clear(); @@ -1900,7 +1923,8 @@ x_pv_game_stage_effect_glitter::x_pv_game_stage_effect_glitter() : void x_pv_game_stage_effect_glitter::reset() { name.str.clear(); name.str.shrink_to_fit(); - name.hash = hash_murmurhash_empty; + name.hash_fnv1a64m = hash_fnv1a64m_empty; + name.hash_murmurhash = hash_murmurhash_empty; scene_counter = 0; fade_time = 0.0f; fade_time_left = 0.0f; @@ -2174,7 +2198,7 @@ void x_pv_game_stage::ctrl(float_t delta_time) { } for (string_hash& i : stage_auth_3d) - auth_3d_data_load_category(x_data, i.c_str(), i.hash); + auth_3d_data_load_category(x_data, i.c_str(), i.hash_murmurhash); state = 11; } break; @@ -2185,7 +2209,7 @@ void x_pv_game_stage::ctrl(float_t delta_time) { bool wait_load = false; for (string_hash& i : stage_auth_3d) - if (!auth_3d_data_check_category_loaded(i.hash)) + if (!auth_3d_data_check_category_loaded(i.hash_murmurhash)) wait_load |= true; for (uint32_t& i : stage_glitter) @@ -2225,20 +2249,27 @@ void x_pv_game_stage::ctrl(float_t delta_time) { int32_t stage_effect = i + 1; - int32_t id = auth_3d_data_load_hash(stg_eff_auth_3d.name.hash, x_data, &obj_db, &tex_db); - if (!auth_3d_data_check_id_not_empty(&id)) { - eff_auth_3d.id = -1; - continue; + auto elem = auth_3d_ids.find(stg_eff_auth_3d.name.hash_murmurhash); + if (elem == auth_3d_ids.end()) { + int32_t id = auth_3d_data_load_hash(stg_eff_auth_3d.name.hash_murmurhash, x_data, &obj_db, &tex_db); + if (!auth_3d_data_check_id_not_empty(&id)) { + eff_auth_3d.id = -1; + continue; + } + + auth_3d_data_read_file_modern(&id); + auth_3d_data_set_enable(&id, false); + auth_3d_data_set_repeat(&id, true); + auth_3d_data_set_paused(&id, false); + auth_3d_data_set_visibility(&id, false); + auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); + eff_auth_3d.id = id; + + auth_3d_ids.insert({ stg_eff_auth_3d.name.hash_murmurhash, id }); } + else + eff_auth_3d.id = elem->second; - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_repeat(&id, true); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); - - eff_auth_3d.id = id; if (stage_effect >= 8 && stage_effect <= 9) eff_auth_3d.repeat = false; else if (stage_effect == 7) @@ -2336,10 +2367,12 @@ void x_pv_game_stage::ctrl_inner() { switch (stage_effect_transition_state) { case 0: { if (v6) { - if (set_change_effect_frame(bar_beat->get_bar_current_frame())) { + if (set_change_effect_frame_part_1()) { chg_eff.bars_left = chg_eff.bar_count; stage_effect_transition_state = 1; stop_stage_effect_auth_3d(curr_stage_effect); + + set_change_effect_frame_part_2(bar_beat->get_bar_current_frame()); } else { stop_stage_effect_auth_3d(curr_stage_effect); @@ -2491,24 +2524,31 @@ void x_pv_game_stage::load_change_effect(int32_t curr_stage_effect, int32_t next chg_eff_auth_3d.reset(); - int32_t id = auth_3d_data_load_hash(stg_chg_eff_auth_3d.name.hash, x_data, &obj_db, &tex_db); - if (!auth_3d_data_check_id_not_empty(&id)) { - chg_eff_auth_3d.id = -1; - continue; + auto elem = auth_3d_ids.find(stg_chg_eff_auth_3d.name.hash_murmurhash); + if (elem == auth_3d_ids.end()) { + int32_t id = auth_3d_data_load_hash(stg_chg_eff_auth_3d.name.hash_murmurhash, x_data, &obj_db, &tex_db); + if (!auth_3d_data_check_id_not_empty(&id)) { + chg_eff_auth_3d.id = -1; + continue; + } + + auth_3d_data_read_file_modern(&id); + auth_3d_data_set_enable(&id, false); + auth_3d_data_set_repeat(&id, false); + auth_3d_data_set_paused(&id, false); + auth_3d_data_set_visibility(&id, false); + auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); + chg_eff_auth_3d.id = id; + + auth_3d_ids.insert({ stg_chg_eff_auth_3d.name.hash_murmurhash, id }); } + else + chg_eff_auth_3d.id = elem->second; - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_repeat(&id, false); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); - - chg_eff_auth_3d.id = id; chg_eff_auth_3d.field_1 = true; chg_eff_auth_3d.repeat = !!(stg_chg_eff_auth_3d.flags & PVSR_AUTH_3D_REPEAT); } - + for (size_t i = 0; i < glitter_count; i++) { pvsr_glitter& stg_chg_eff_glt = stg_chg_eff.glitter[i]; x_pv_game_stage_effect_glitter& chg_eff_glt = chg_eff.glitter[i]; @@ -2524,6 +2564,7 @@ void x_pv_game_stage::reset() { stage_id = 0; field_8 = 0; state = 0; + stage_resource_file_handler.free_data(); if (stage_resource) { delete stage_resource; stage_resource = 0; @@ -2548,6 +2589,7 @@ void x_pv_game_stage::reset() { obj_db.object_set.shrink_to_fit(); tex_db.texture.clear(); tex_db.texture.shrink_to_fit(); + auth_3d_ids.clear(); } void x_pv_game_stage::reset_stage_effect() { @@ -2565,7 +2607,7 @@ void x_pv_game_stage::reset_stage_effect() { Glitter::glt_particle_manager->FreeScene(i); } -bool x_pv_game_stage::set_change_effect_frame(float_t frame) { +bool x_pv_game_stage::set_change_effect_frame_part_1() { if (!curr_stage_effect || !next_stage_effect) return false; @@ -2584,6 +2626,28 @@ bool x_pv_game_stage::set_change_effect_frame(float_t frame) { x_pv_game_stage_change_effect& chg_eff = change_effect[curr_stg_eff][next_sta_eff]; if (!chg_eff.enable) return false; + return true; +} + +void x_pv_game_stage::set_change_effect_frame_part_2(float_t frame) { + if (!curr_stage_effect || !next_stage_effect) + return; + + int32_t curr_stg_eff = curr_stage_effect; + if (curr_stg_eff >= 1 && curr_stg_eff <= 12) + curr_stg_eff--; + else + curr_stg_eff = 0; + + int32_t next_sta_eff = next_stage_effect; + if (next_sta_eff >= 1 && next_sta_eff <= 12) + next_sta_eff--; + else + next_sta_eff = 0; + + x_pv_game_stage_change_effect& chg_eff = change_effect[curr_stg_eff][next_sta_eff]; + if (!chg_eff.enable) + return; for (x_pv_game_stage_effect_auth_3d& i : chg_eff.auth_3d) { int32_t& id = i.id; @@ -2598,17 +2662,16 @@ bool x_pv_game_stage::set_change_effect_frame(float_t frame) { } for (x_pv_game_stage_effect_glitter& i : chg_eff.glitter) { - if (i.name.hash == hash_murmurhash_empty) + if (i.name.hash_murmurhash == hash_murmurhash_empty) continue; - i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(i.name.hash, i.name.c_str()); + i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(i.name.hash_murmurhash, i.name.c_str()); if (!i.scene_counter) continue; Glitter::glt_particle_manager->SetSceneFrameRate(i.scene_counter, &bpm_frame_rate_control); Glitter::glt_particle_manager->SetSceneEffectReqFrame(i.scene_counter, frame); } - return true; } void x_pv_game_stage::set_stage_effect(int32_t stage_effect) { @@ -2685,7 +2748,7 @@ void x_pv_game_stage::set_stage_effect_glitter_frame(int32_t stage_effect, float std::vector& glitter = effect[stage_effect - 1ULL].glitter; for (x_pv_game_stage_effect_glitter& i : glitter) { - i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(i.name.hash, i.name.c_str()); + i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(i.name.hash_murmurhash, i.name.c_str()); if (!i.scene_counter) continue; @@ -2797,18 +2860,17 @@ void x_pv_game_stage::unload() { if (!stage_resource || !stage_id) return; - for (x_pv_game_stage_effect& i : effect) { - for (x_pv_game_stage_effect_auth_3d& j : i.auth_3d) { - auth_3d_data_unload_id(j.id, rctx_ptr); - j.id = -1; - } + for (std::pair i : auth_3d_ids) + auth_3d_data_unload_id(i.second, rctx_ptr); + auth_3d_ids.clear(); + + for (x_pv_game_stage_effect& i : effect) for (x_pv_game_stage_effect_glitter& j : i.glitter) if (j.scene_counter) { Glitter::glt_particle_manager->FreeSceneEffect(j.scene_counter, false); j.scene_counter = 0; } - } if (stage_effect_transition_state == 1) stop_stage_change_effect(); @@ -2816,11 +2878,6 @@ void x_pv_game_stage::unload() { for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) { x_pv_game_stage_change_effect& chg_eff = change_effect[i][j]; - for (x_pv_game_stage_effect_auth_3d& k : chg_eff.auth_3d) { - auth_3d_data_unload_id(k.id, rctx_ptr); - k.id = -1; - } - for (x_pv_game_stage_effect_glitter& k : chg_eff.glitter) if (k.scene_counter) { Glitter::glt_particle_manager->FreeSceneEffect(k.scene_counter, false); @@ -2843,9 +2900,9 @@ void x_pv_game_stage::unload() { Glitter::glt_particle_manager->UnloadEffectGroup(i); } - + for (string_hash& i : stage_auth_3d) - auth_3d_data_unload_category(i.hash); + auth_3d_data_unload_category(i.hash_murmurhash); delete stage_resource; stage_resource = 0; @@ -2884,6 +2941,31 @@ static bool img_write = false; FILE* pipe; #endif +#if DOF_BAKE +static void a3da_key_rev(a3da_key& k, std::vector& values_src) { + std::vector value; + int32_t type = interpolate_chs_reverse_sequence(values_src, value); + + k = {}; + switch (type) { + case 0: + default: + k.type = A3DA_KEY_NONE; + return; + case 1: + k.value = value[0].value; + k.type = A3DA_KEY_STATIC; + break; + case 2: + break; + } + + k.type = A3DA_KEY_HERMITE; + k.keys = value; + k.max_frame = (float_t)(values_src.size() + 1); +} +#endif + bool x_pv_game::Ctrl() { if (state_old == 20) ctrl((float_t)((frame_float + get_delta_frame()) * (1.0 / 60.0)), get_delta_frame() * (float_t)(1.0 / 60.0)); @@ -2919,6 +3001,8 @@ bool x_pv_game::Ctrl() { if (wait_load) break; + stage_data.load(stage_id, &field_71994, false); + for (int32_t i = 0; i < pv_count; i++) { x_pv_game_data& pv_data = this->pv_data[i]; @@ -2946,8 +3030,6 @@ bool x_pv_game::Ctrl() { } } - stage_data.load(stage_id, &field_71994, false); - state_old = 3; } break; case 3: { @@ -3020,7 +3102,7 @@ bool x_pv_game::Ctrl() { { data_struct* x_data = &data_list[DATA_X]; - dsc dscouth; + dsc dsc_mouth; dsc dsc_scene; dsc dsc_system; dsc dsc_easy; @@ -3034,9 +3116,9 @@ bool x_pv_game::Ctrl() { x_data->load_file(&dsc_common_farc, path_buf, file_buf, farc::load_file); sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_mouth.dsc", pv_data[pv_index].pv_id); - farc_file* dscouth_ff = dsc_common_farc.read_file(file_buf); - if (dscouth_ff) - dscouth.parse(dscouth_ff->data, dscouth_ff->size, DSC_X); + farc_file* dsc_mouth_ff = dsc_common_farc.read_file(file_buf); + if (dsc_mouth_ff) + dsc_mouth.parse(dsc_mouth_ff->data, dsc_mouth_ff->size, DSC_X); sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_scene.dsc", pv_data[pv_index].pv_id); farc_file* dsc_scene_ff = dsc_common_farc.read_file(file_buf); @@ -3052,7 +3134,74 @@ bool x_pv_game::Ctrl() { dsc_easy.type = DSC_X; x_data->load_file(&dsc_easy, path_buf, file_buf, dsc::load_file); - dsc_data.dsc.merge(4, &dscouth, &dsc_scene, &dsc_system, &dsc_easy); + /*if (pv_id == 826) { + dsc dsc_hand_keys[5]; + + char file_buf[0x200]; + for (int32_t i = 2; i <= 6; i++) { + stream s; + sprintf_s(file_buf, sizeof(file_buf), "pv_826_hand_%d.txt", i); + s.open(file_buf, "rb"); + size_t length = s.length; + uint8_t* data = force_malloc_s(uint8_t, length); + s.read(data, length); + s.close(); + + dsc& d = dsc_hand_keys[i - 2]; + d.parse_text(data, length, DSC_X); + d.signature = 0x13120420; + free_def(data); + + { + int32_t hand_l_time = -1; + int32_t hand_l_id = -1; + int32_t hand_l_duration = -1; + ::dsc_data* hand_l_data = 0; + int32_t hand_r_time = -1; + int32_t hand_r_id = -1; + int32_t hand_r_duration = -1; + ::dsc_data* hand_r_data = 0; + int32_t time = -1; + for (::dsc_data& j : d.data) { + if (j.func == DSC_X_END) + break; + + uint32_t* data = d.get_func_data(&j); + switch (j.func) { + case DSC_X_TIME: + time = (int32_t)data[0]; + break; + case DSC_X_HAND_ANIM: { + if (data[1] == 0) { + if (hand_l_time > -1 && hand_l_duration > time - hand_l_time) + data[3] = (time - hand_l_time) / 100; + + hand_l_time = time; + hand_l_id = (int32_t)data[2]; + hand_l_duration = (int32_t)data[3] * 100; + hand_l_data = &j; + } + if (data[1] == 1) { + if (hand_r_time > -1 && hand_r_duration > time - hand_r_time) + data[3] = (time - hand_r_time) / 100; + + hand_r_time = time; + hand_r_id = (int32_t)data[2]; + hand_r_duration = (int32_t)data[3] * 100; + hand_r_data = &j; + } + } break; + } + } + } + } + + dsc_data.dsc.merge(9, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy, + &dsc_hand_keys[0], &dsc_hand_keys[1], &dsc_hand_keys[2], &dsc_hand_keys[3], dsc_hand_keys[4]); + } + else + dsc_data.dsc.merge(4, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy);*/ + dsc_data.dsc.merge(4, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy); struct miku_state { bool disp; @@ -3073,6 +3222,10 @@ bool x_pv_game::Ctrl() { x_pv_bar_beat_data* bar_beat_data = 0; int32_t beat_counter = 0; + /*std::vector> miku_disp; + std::vector> set_motion; + std::vector> set_playdata;*/ + int32_t time = -1; int32_t frame = -1; for (::dsc_data& i : dsc_data.dsc.data) { @@ -3093,16 +3246,21 @@ bool x_pv_game::Ctrl() { state[chara_id].disp = (int32_t)data[1] == 1; if (state[chara_id].disp) state[chara_id].disp_time = time; + //miku_disp.push_back({ time, i.data_offset }); } break; case DSC_X_SET_MOTION: { int32_t chara_id = (int32_t)data[0]; state[chara_id].set_motion_time = time; state[chara_id].set_motion_data_offset = i.data_offset; + //set_motion.push_back({ time, i.data_offset }); } break; + /*case DSC_X_SET_PLAYDATA: { + set_playdata.push_back({ time, i.data_offset }); + } break;*/ } } - if (state_vec.size()) { + if (state_vec.size()/* || miku_disp.size() || set_motion.size() || set_playdata.size()*/) { int32_t time = -1; for (miku_state& i : state_vec) { if (i.disp_time != time) { @@ -3117,6 +3275,61 @@ bool x_pv_game::Ctrl() { uint32_t* data = dsc_data.dsc.data_buffer.data() + i.set_motion_data_offset; memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_SET_MOTION)); } + + /*time = -1; + for (std::pair& i : miku_disp) { + if (i.first != time) { + uint32_t* data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_TIME), + DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME)); + data[0] = i.first; + time = i.first; + } + + for (int32_t j = 1; j < 6; j++) { + uint32_t* new_data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_MIKU_DISP), + DSC_X_MIKU_DISP, dsc_x_get_func_length(DSC_X_MIKU_DISP)); + uint32_t* data = dsc_m.data_buffer.data() + i.second; + memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_MIKU_DISP)); + new_data[0] = j; + } + } + + time = -1; + for (std::pair& i : set_motion) { + if (i.first != time) { + uint32_t* data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_TIME), + DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME)); + data[0] = i.first; + time = i.first; + } + + for (int32_t j = 1; j < 6; j++) { + uint32_t* new_data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_SET_MOTION), + DSC_X_SET_MOTION, dsc_x_get_func_length(DSC_X_SET_MOTION)); + uint32_t* data = dsc_m.data_buffer.data() + i.second; + memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_SET_MOTION)); + new_data[0] = j; + } + } + + time = -1; + for (std::pair& i : set_playdata) { + if (i.first != time) { + uint32_t* data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_TIME), + DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME)); + data[0] = i.first; + time = i.first; + } + + for (int32_t j = 1; j < 6; j++) { + uint32_t* new_data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_SET_PLAYDATA), + DSC_X_SET_PLAYDATA, dsc_x_get_func_length(DSC_X_SET_PLAYDATA)); + uint32_t* data = dsc_m.data_buffer.data() + i.second; + memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_SET_PLAYDATA)); + new_data[0] = j; + } + }*/ + dsc_data.dsc.rebuild(); } @@ -3127,7 +3340,7 @@ bool x_pv_game::Ctrl() { stream s; s.open(file_buf, "wb"); s.write(data, size); - free(data);*/ + free_def(data);*/ } pv_expression_array_reset(); @@ -3240,6 +3453,7 @@ bool x_pv_game::Ctrl() { pause = true; state_old = 20; + //sound_work_release_se("load01_2", false); } break; case 20: { float_t delta_frame = get_delta_frame(); @@ -3264,6 +3478,75 @@ bool x_pv_game::Ctrl() { fflush(pipe); _pclose(pipe); #endif + + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) + pv_expression_array_reset_motion(i); + +#if DOF_BAKE + { + x_pv_game_data& pv_data = this->pv_data[pv_index]; + + data_struct* x_data = &data_list[DATA_X]; + + char buf[0x200]; + sprintf_s(buf, sizeof(buf), "CAMPV%03d", pv_data.pv_id); + + farc* f = new farc; + x_data->load_file(f, "root+/auth_3d/", hash_utf8_murmurhash(buf), ".farc", farc::load_file); + + if ((pv_data.pv_id % 100) >= 25 && (pv_data.pv_id % 100) <= 30 + && stage_data.stage_id >= 25 && stage_data.stage_id <= 30) + sprintf_s(buf, sizeof(buf), "CAMPV%03d_100.a3da", pv_data.pv_id); + else + sprintf_s(buf, sizeof(buf), "CAMPV%03d_BASE.a3da", pv_data.pv_id); + + a3da a; + farc_file* ff = f->read_file(buf); + if (ff) + a.read(ff->data, ff->size); + delete f; + + if ((pv_data.pv_id % 100) >= 25 && (pv_data.pv_id % 100) <= 30 + && stage_data.stage_id >= 25 && stage_data.stage_id <= 30) + sprintf_s(buf, sizeof(buf), "DOF\\auth_3d\\CAMPV%03d_100", pv_data.pv_id); + else + sprintf_s(buf, sizeof(buf), "DOF\\auth_3d\\CAMPV%03d_BASE", pv_data.pv_id); + + a.ready = true; + a.compressed = true; + a.format = A3DA_FORMAT_AFT; + a.dof = {}; + a.dof.has_dof = true; + + a3da_key_rev(a.dof.model_transform.translation.x, dof_cam_data.position_x); + a3da_key_rev(a.dof.model_transform.translation.y, dof_cam_data.position_y); + a3da_key_rev(a.dof.model_transform.translation.z, dof_cam_data.position_z); + a.dof.model_transform.translation.x.raw_data = true; + a.dof.model_transform.translation.y.raw_data = true; + a.dof.model_transform.translation.z.raw_data = true; + a3da_key_rev(a.dof.model_transform.scale.x, dof_cam_data.focus_range); + a3da_key_rev(a.dof.model_transform.rotation.x, dof_cam_data.fuzzing_range); + a3da_key_rev(a.dof.model_transform.rotation.y, dof_cam_data.ratio); + + a3da_key& rot_z = a.dof.model_transform.rotation.z; + if (dof_cam_data.enable_frame.size() > 1) { + rot_z.type = A3DA_KEY_HOLD; + rot_z.keys.reserve(dof_cam_data.enable_frame.size()); + for (std::pair& i : dof_cam_data.enable_frame) + rot_z.keys.push_back({ (float_t)i.first, i.second ? 1.00051f : 0.0f }); + rot_z.max_frame = a.play_control.size; + } + else if (dof_cam_data.enable_frame.size()) { + rot_z.type = A3DA_KEY_STATIC; + rot_z.value = dof_cam_data.enable_frame[0].second ? 1.00051f : 0.0f; + } + else + rot_z.type = A3DA_KEY_NONE; + + a.write(buf); + } +#endif + unload(); state_old = 22; } break; @@ -3278,94 +3561,10 @@ bool x_pv_game::Ctrl() { return false; } -#if DOF_BAKE -static void a3da_key_rev(a3da_key& k, std::vector& values_src) { - std::vector value; - int32_t type = interpolate_chs_reverse_sequence(values_src, value); - - k = {}; - switch (type) { - case 0: - default: - k.type = A3DA_KEY_NONE; - return; - case 1: - k.value = value[0].value; - k.type = A3DA_KEY_STATIC; - break; - case 2: - break; - } - - k.type = A3DA_KEY_HERMITE; - k.keys = value; - k.max_frame = (float_t)(values_src.size() + 1); -} -#endif - bool x_pv_game::Dest() { -#if DOF_BAKE - { - data_struct* x_data = &data_list[DATA_X]; + if (!Unload()) + return false; - char buf[0x200]; - sprintf_s(buf, sizeof(buf), "CAMPV%03d", pv_data.pv_id); - - farc* f = new farc; - x_data->load_file(f, "root+/auth_3d/", hash_utf8_murmurhash(buf), ".farc", farc::load_file); - - if ((pv_data.pv_id % 100) >= 25 && (pv_data.pv_id % 100) <= 30 && stage_data.stage_id >= 25 && stage_data.stage_id <= 30) - sprintf_s(buf, sizeof(buf), "CAMPV%03d_100.a3da", pv_data.pv_id); - else - sprintf_s(buf, sizeof(buf), "CAMPV%03d_BASE.a3da", pv_data.pv_id); - - a3da a; - farc_file* ff = f->read_file(buf); - if (ff) - a.read(ff->data, ff->size); - delete f; - - if ((pv_data.pv_id % 100) >= 25 && (pv_data.pv_id % 100) <= 30 && stage_data.stage_id >= 25 && stage_data.stage_id <= 30) - sprintf_s(buf, sizeof(buf), "DOF\\auth_3d\\CAMPV%03d_100", pv_data.pv_id); - else - sprintf_s(buf, sizeof(buf), "DOF\\auth_3d\\CAMPV%03d_BASE", pv_data.pv_id); - - a.ready = true; - a.compressed = true; - a.format = A3DA_FORMAT_AFT; - a.dof = {}; - a.dof.has_dof = true; - - a3da_key_rev(a.dof.model_transform.translation.x, dof_cam_data.position_x); - a3da_key_rev(a.dof.model_transform.translation.y, dof_cam_data.position_y); - a3da_key_rev(a.dof.model_transform.translation.z, dof_cam_data.position_z); - a.dof.model_transform.translation.x.raw_data = true; - a.dof.model_transform.translation.y.raw_data = true; - a.dof.model_transform.translation.z.raw_data = true; - a3da_key_rev(a.dof.model_transform.scale.x, dof_cam_data.focus_range); - a3da_key_rev(a.dof.model_transform.rotation.x, dof_cam_data.fuzzing_range); - a3da_key_rev(a.dof.model_transform.rotation.y, dof_cam_data.ratio); - - a3da_key& rot_z = a.dof.model_transform.rotation.z; - if (dof_cam_data.enable_frame.size() > 1) { - rot_z.type = A3DA_KEY_HOLD; - rot_z.keys.reserve(dof_cam_data.enable_frame.size()); - for (std::pair& i : dof_cam_data.enable_frame) - rot_z.keys.push_back({ (float_t)i.first, i.second ? 1.00051f : 0.0f }); - rot_z.max_frame = a.play_control.size; - } - else if (dof_cam_data.enable_frame.size()) { - rot_z.type = A3DA_KEY_STATIC; - rot_z.value = dof_cam_data.enable_frame[0].second ? 1.00051f : 0.0f; - } - else - rot_z.type = A3DA_KEY_NONE; - - a.write(buf); - } -#endif - - Unload(); task_rob_manager_free_task(); light_param_data_storage_data_reset(); @@ -3453,6 +3652,45 @@ void x_pv_game::Basic() { extern float_t frame_speed; frame_speed = pause ? 0.0f : 1.0f; + /*if (get_delta_frame() != 0.0f && frame > 0) + for (auto& i : effchrpv_auth_3d_rob_mot_ids) { + rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i.first]); + x_pv_game_a3da_to_mot& a2m = i.second; + + rob_chara_bone_data* rob_bone_data = rob_chr->bone_data; + + bone_database_skeleton_type skeleton_type = rob_bone_data->base_skeleton_type; + motion_blend_mot* mot = rob_bone_data->motion_loaded.front(); + std::vector* bones = &mot->bone_data.bones; + std::vector* bone_indices = &mot->bone_data.bone_indices; + + bone_data* bones_data = bones->data(); + for (uint16_t& i : *bone_indices) { + bone_data* data = &bones_data[i]; + ::motion_bone_index motion_bone_index = (::motion_bone_index)data->motion_bone_index; + if (motion_bone_index >= MOTION_BONE_N_HITO_L_EX + && motion_bone_index <= MOTION_BONE_NL_OYA_C_L_WJ) { + auto elem = a2m.bone_keys.find(motion_bone_index); + if (elem == a2m.bone_keys.end()) + elem = a2m.bone_keys.insert({ motion_bone_index, {} }).first; + + elem->second.x.push_back(data->rotation.x); + elem->second.y.push_back(data->rotation.y); + elem->second.z.push_back(data->rotation.z); + } + else if (motion_bone_index >= MOTION_BONE_N_HITO_R_EX + && motion_bone_index <= MOTION_BONE_NL_OYA_C_R_WJ) { + auto elem = a2m.bone_keys.find(motion_bone_index); + if (elem == a2m.bone_keys.end()) + elem = a2m.bone_keys.insert({ motion_bone_index, {} }).first; + + elem->second.x.push_back(data->rotation.x); + elem->second.y.push_back(data->rotation.y); + elem->second.z.push_back(data->rotation.z); + } + } + }*/ + #if BAKE_VIDEO if (img_write && frame_prev != frame) { texture* rend_texture = rctx_ptr->post_process.rend_texture.color_texture; @@ -3678,9 +3916,8 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, ::chara_index charas[6], i i.shrink_to_fit(); } - //pv_auth_3d_chara_count.clear(); - Glitter::glt_particle_manager->draw_all = false; + //sound_work_play_se(1, "load01_2", 1.0f); } mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, @@ -3754,7 +3991,35 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, } } -/*bool mot_write_motion(void* data, const char* path, const char* file, uint32_t hash) { +/*static void fix_rotation(std::vector& vec) { + if (vec.size() < 2) + return; + + const float_t half_pi = (float_t)(M_PI / 2.0); + + int32_t curr_rot = 0; + float_t rot_fix = 0.0f; + float_t rot_prev = vec.data()[0]; + float_t* i_begin = vec.data() + 1; + float_t* i_end = vec.data() + vec.size(); + for (float_t* i = i_begin; i != i_end; i++) { + float_t rot = *i; + if (rot < -half_pi && rot_prev > half_pi && fabsf(rot - rot_prev) > half_pi) { + curr_rot++; + rot_fix = (float_t)(M_PI * 2.0 * (double_t)curr_rot); + } + else if (rot > half_pi && rot_prev < -half_pi && fabsf(rot - rot_prev) > half_pi) { + curr_rot--; + rot_fix = (float_t)(M_PI * 2.0 * (double_t)curr_rot); + } + + if (curr_rot) + *i = rot + rot_fix; + rot_prev = rot; + } +} + +bool mot_write_motion(void* data, const char* path, const char* file, uint32_t hash) { x_pv_game* xpvgm = (x_pv_game*)data; data_struct* aft_data = &data_list[DATA_AFT]; @@ -3762,7 +4027,7 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, motion_database* aft_mot_db = &aft_data->data_ft.mot_db; char buf[0x200]; - sprintf_s(buf, sizeof(buf), "PV%03d", xpvgm->pv_data[xpvgm->pv_index].pv_id); + sprintf_s(buf, sizeof(buf), "PV%03d", xpvgm->pv_id); motion_set_info* set_info = aft_mot_db->get_motion_set_by_name(buf); if (!set_info) return true; @@ -3789,7 +4054,7 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, } for (auto& i : xpvgm->effchrpv_auth_3d_rob_mot_ids) { - char buf[0x200]; + char buf[0x100]; sprintf_s(buf, sizeof(buf), "PV826_OST_P%d_00", i.first + 1); int32_t motion_id = aft_mot_db->get_motion_id(buf); @@ -3832,10 +4097,16 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, if (elem != a2m.bone_keys.end()) { x_pv_game_a3da_to_mot_keys& keys = elem->second; + if (bone->type == BONE_DATABASE_BONE_ROTATION) { + fix_rotation(keys.x); + fix_rotation(keys.y); + fix_rotation(keys.z); + } + mot_key_set_data& key_set_data_x = mot_data->key_set[key_set_offset]; key_set_data_x.frames.clear(); key_set_data_x.values.clear(); - key_set_data_x.type = mot_fit_keys_into_curve(keys.x, + key_set_data_x.type = mot_set::fit_keys_into_curve(keys.x, key_set_data_x.frames, key_set_data_x.values); key_set_data_x.keys_count = (uint16_t)key_set_data_x.frames.size(); key_set_data_x.data_type = MOT_KEY_SET_DATA_F32; @@ -3843,7 +4114,7 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, mot_key_set_data& key_set_data_y = mot_data->key_set[key_set_offset + 1]; key_set_data_y.frames.clear(); key_set_data_y.values.clear(); - key_set_data_y.type = mot_fit_keys_into_curve(keys.y, + key_set_data_y.type = mot_set::fit_keys_into_curve(keys.y, key_set_data_y.frames, key_set_data_y.values); key_set_data_y.keys_count = (uint16_t)key_set_data_y.frames.size(); key_set_data_y.data_type = MOT_KEY_SET_DATA_F32; @@ -3851,7 +4122,7 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, mot_key_set_data& key_set_data_z = mot_data->key_set[key_set_offset + 2]; key_set_data_z.frames.clear(); key_set_data_z.values.clear(); - key_set_data_z.type = mot_fit_keys_into_curve(keys.z, + key_set_data_z.type = mot_set::fit_keys_into_curve(keys.z, key_set_data_z.frames, key_set_data_z.values); key_set_data_z.keys_count = (uint16_t)key_set_data_z.frames.size(); key_set_data_z.data_type = MOT_KEY_SET_DATA_F32; @@ -3861,10 +4132,14 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, if (elem != a2m.sec_bone_keys.end()) { x_pv_game_a3da_to_mot_keys& keys = elem->second; + fix_rotation(keys.x); + fix_rotation(keys.y); + fix_rotation(keys.z); + mot_key_set_data& key_set_data_x = mot_data->key_set[key_set_offset + 3]; key_set_data_x.frames.clear(); key_set_data_x.values.clear(); - key_set_data_x.type = mot_fit_keys_into_curve(keys.x, + key_set_data_x.type = mot_set::fit_keys_into_curve(keys.x, key_set_data_x.frames, key_set_data_x.values); key_set_data_x.keys_count = (uint16_t)key_set_data_x.frames.size(); key_set_data_x.data_type = MOT_KEY_SET_DATA_F32; @@ -3872,7 +4147,7 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, mot_key_set_data& key_set_data_y = mot_data->key_set[key_set_offset + 4]; key_set_data_y.frames.clear(); key_set_data_y.values.clear(); - key_set_data_y.type = mot_fit_keys_into_curve(keys.y, + key_set_data_y.type = mot_set::fit_keys_into_curve(keys.y, key_set_data_y.frames, key_set_data_y.values); key_set_data_y.keys_count = (uint16_t)key_set_data_y.frames.size(); key_set_data_y.data_type = MOT_KEY_SET_DATA_F32; @@ -3880,7 +4155,7 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, mot_key_set_data& key_set_data_z = mot_data->key_set[key_set_offset + 5]; key_set_data_z.frames.clear(); key_set_data_z.values.clear(); - key_set_data_z.type = mot_fit_keys_into_curve(keys.z, + key_set_data_z.type = mot_set::fit_keys_into_curve(keys.z, key_set_data_z.frames, key_set_data_z.values); key_set_data_z.keys_count = (uint16_t)key_set_data_z.frames.size(); key_set_data_z.data_type = MOT_KEY_SET_DATA_F32; @@ -3955,8 +4230,45 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, return true; }*/ -void x_pv_game::Unload() { - /*{ +bool x_pv_game::Unload() { + pv_osage_manager_array_set_not_reset_true(); + if (pv_osage_manager_array_get_disp()) + return false; + + /*if (pv_data[pv_index].pv_id == 826) { + for (auto& i : effchrpv_auth_3d_rob_mot_ids) { + rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i.first]); + x_pv_game_a3da_to_mot& a2m = i.second; + + bone_node* node = rob_chr->bone_data->nodes.data(); + + for (int32_t j = MOTION_BONE_N_HITO_L_EX; j <= MOTION_BONE_NL_OYA_C_L_WJ; j++) { + ::motion_bone_index motion_bone_index = (::motion_bone_index)j; + + auto elem = a2m.bone_keys.find(motion_bone_index); + if (elem == a2m.bone_keys.end()) + elem = a2m.bone_keys.insert({ motion_bone_index, {} }).first; + + vec3& rotation = node[j - MOTION_BONE_N_HITO_L_EX + ROB_BONE_N_HITO_L_EX].exp_data.rotation; + elem->second.x.push_back(rotation.x); + elem->second.y.push_back(rotation.y); + elem->second.z.push_back(rotation.z); + } + + for (int32_t j = MOTION_BONE_N_HITO_R_EX; j <= MOTION_BONE_NL_OYA_C_R_WJ; j++) { + ::motion_bone_index motion_bone_index = (::motion_bone_index)j; + + auto elem = a2m.bone_keys.find(motion_bone_index); + if (elem == a2m.bone_keys.end()) + elem = a2m.bone_keys.insert({ motion_bone_index, {} }).first; + + vec3& rotation = node[j - MOTION_BONE_N_HITO_R_EX + ROB_BONE_N_HITO_R_EX].exp_data.rotation; + elem->second.x.push_back(rotation.x); + elem->second.y.push_back(rotation.y); + elem->second.z.push_back(rotation.z); + } + } + data_struct* aft_data = &data_list[DATA_AFT]; motion_database* aft_mot_db = &aft_data->data_ft.mot_db; @@ -3972,9 +4284,6 @@ void x_pv_game::Unload() { data_struct* aft_data = &data_list[DATA_AFT]; motion_database* aft_mot_db = &aft_data->data_ft.mot_db; - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) - pv_expression_array_reset_motion(i); - pv_param::post_process_data_clear_data(); char buf[0x200]; @@ -4003,12 +4312,6 @@ void x_pv_game::Unload() { light_category.clear(); light_category.shrink_to_fit(); - /*for (uint32_t& i : objset_load) - object_storage_unload_set(i);*/ - - /*objset_load.clear(); - objset_load.shrink_to_fit();*/ - for (int32_t i = 0; i < pv_count; i++) pv_data[i].reset(); stage_data.reset(); @@ -4024,8 +4327,6 @@ void x_pv_game::Unload() { pv_data[pv_index].stage_effects.shrink_to_fit(); pv_data[pv_index].stage_effect_index = 0; - //pv_auth_3d_chara_count.clear(); - play = true; success = true; chara_id = 0; @@ -4047,6 +4348,7 @@ void x_pv_game::Unload() { Glitter::glt_particle_manager->draw_all = true; pv_param_task::post_process_task.SetDest(); + return true; } void x_pv_game::ctrl(float_t curr_time, float_t delta_time) { @@ -4151,7 +4453,7 @@ XPVGameSelector::XPVGameSelector() : charas(), modules(), start(), exit() { for (chara_index& i : charas) i = CHARA_MIKU; - + for (int32_t& i : modules) i = 0; } @@ -4185,73 +4487,73 @@ bool XPVGameSelector::Dest() { void XPVGameSelector::Window() { static const char* pv_names[] = { - "801. Strangers", - "802. Ai Dee", - "803. Streaming Heart", - "804. Babylon", - "805. The Lost One's Weeping", - "806. Slow Motion", - "807. Tale of the Deep-sea Lily", - "808. Love Trial", - "809. Love Song", - "810. The First Sound", - "811. LOL - lots of laugh -", - "812. Patchwork Staccato", - "813. Even a Kunoichi Needs Love", - "814. Calc.", - "815. A Single Red Leaf", - "816. Holy Lance Explosion Boy", - "817. Urotander, Underhanded Rangers", - "818. Humorous Dream of Mrs. Pumpkin", - "819. Solitary Envy", - "820. Raspberry * Monster", - "821. Brain Revolution Girl", - "822. Amazing Dolce", - "823. Name of the Sin", - "824. Satisfaction", - "825. Cute Medley - Idol Sounds", - "826. Beginning Medley - Primary Colors", - "827. Cool Medley - Cyber Rock Jam", - "828. Elegant Medley - Glossy Mixture", - "829. Quirky Medley - Giga-Remix", - "830. Ending Medley - Ultimate Exquisite Rampage", - "831. Sharing The World", - "832. Hand in Hand", + u8"801. Strangers", + u8"802. Ai Dee", + u8"803. Streaming Heart", + u8"804. Babylon", + u8"805. The Lost One's Weeping", + u8"806. Slow Motion", + u8"807. Tale of the Deep-sea Lily", + u8"808. Love Trial", + u8"809. Love Song", + u8"810. The First Sound", + u8"811. LOL - lots of laugh -", + u8"812. Patchwork Staccato", + u8"813. Even a Kunoichi Needs Love", + u8"814. Calc.", + u8"815. A Single Red Leaf", + u8"816. Holy Lance Explosion Boy", + u8"817. Urotander, Underhanded Rangers", + u8"818. Humorous Dream of Mrs. Pumpkin", + u8"819. Solitary Envy", + u8"820. Raspberry * Monster", + u8"821. Brain Revolution Girl", + u8"822. Amazing Dolce", + u8"823. Name of the Sin", + u8"824. Satisfaction", + u8"825. Cute Medley - Idol Sounds", + u8"826. Beginning Medley - Primary Colors", + u8"827. Cool Medley - Cyber Rock Jam", + u8"828. Elegant Medley - Glossy Mixture", + u8"829. Quirky Medley - Giga-Remix", + u8"830. Ending Medley - Ultimate Exquisite Rampage", + u8"831. Sharing The World", + u8"832. Hand in Hand", }; static const char* stage_names[] = { - "001. Nighttime Curb Stage", - "002. Digital Concert Stage", - "003. Secret Ruins Stage", - "004. Utopia Stage", - "005. Classroom Concert Stage", - "006. Capsule Room Stage", - "007. Deep Sea Stage", - "008. Verdict Stage", - "009. Sky Garden Stage", - "010. Musical Dawn Stage", - "011. Sweet Dreams Stage", - "012. Heart's Playroom Stage", - "013. Ninja Village Stage", - "014. Park of Promises Stage", - "015. Autumn Sakura Stage", - "016. Classy Lounge Stage", - "017. Secret Base Stage", - "018. Halloween Party Stage", - "019. Twilight Shrine Stage", - "020. Raspberry Stage", - "021. Cabaret Stage", - "022. Witch's House Stage", - "023. Lilies & Shadows Stage", - "024. Techno Club Stage", - "025. Cute Concert Hall", - "026. First Concert Hall", - "027. Cool Concert Hall", - "028. Elegant Concert Hall", - "029. Quirky Concert Hall", - "030. Ultimate Concert Hall", - "031. Highrise Stage", - "032. Mirai Concert Stage", + u8"001. Nighttime Curb Stage", + u8"002. Digital Concert Stage", + u8"003. Secret Ruins Stage", + u8"004. Utopia Stage", + u8"005. Classroom Concert Stage", + u8"006. Capsule Room Stage", + u8"007. Deep Sea Stage", + u8"008. Verdict Stage", + u8"009. Sky Garden Stage", + u8"010. Musical Dawn Stage", + u8"011. Sweet Dreams Stage", + u8"012. Heart's Playroom Stage", + u8"013. Ninja Village Stage", + u8"014. Park of Promises Stage", + u8"015. Autumn Sakura Stage", + u8"016. Classy Lounge Stage", + u8"017. Secret Base Stage", + u8"018. Halloween Party Stage", + u8"019. Twilight Shrine Stage", + u8"020. Raspberry Stage", + u8"021. Cabaret Stage", + u8"022. Witch's House Stage", + u8"023. Lilies & Shadows Stage", + u8"024. Techno Club Stage", + u8"025. Cute Concert Hall", + u8"026. First Concert Hall", + u8"027. Cool Concert Hall", + u8"028. Elegant Concert Hall", + u8"029. Quirky Concert Hall", + u8"030. Ultimate Concert Hall", + u8"031. Highrise Stage", + u8"032. Mirai Concert Stage", }; ImGuiIO& io = ImGui::GetIO(); @@ -4262,7 +4564,7 @@ void XPVGameSelector::Window() { float_t w = 400.0f; float_t h = (float_t)height; - h = min(h, 432.0f); + h = min_def(h, 432.0f); extern int32_t width; ImGui::SetNextWindowPos({ (float_t)width - w, 0.0f }, ImGuiCond_Always); @@ -4285,12 +4587,12 @@ void XPVGameSelector::Window() { } pv_id -= 801; - pv_id = max(pv_id, 0); + pv_id = max_def(pv_id, 0); ImGui::ColumnComboBox("PV", pv_names, 32, &pv_id, 0, false, &window_focus); pv_id += 801; stage_id--; - stage_id = max(stage_id, 0); + stage_id = max_def(stage_id, 0); ImGui::ColumnComboBox("Stage", stage_names, 32, &stage_id, 0, false, &window_focus); stage_id++; @@ -4344,15 +4646,28 @@ void XPVGameSelector::Window() { ImGui::End(); } -extern void x_pv_game_init() { +extern bool x_pv_game_init() { x_pv_game_ptr = new x_pv_game; + return true; } -extern void x_pv_game_free() { +extern bool x_pv_game_free() { if (x_pv_game_ptr) { + switch (x_pv_game_ptr->state_old) { + case 0: + break; + case 21: + case 22: + return false; + default: + x_pv_game_ptr->state_old = 21; + return false; + } + delete x_pv_game_ptr; x_pv_game_ptr = 0; } + return true; } #if DOF_BAKE @@ -4526,7 +4841,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { rob_chr->bone_data->disable_eye_motion = i.disable_eye_motion; rob_chr->data.motion.step_data.step = i.frame_speed; if (v45) - pv_expression_array_set_motion(pv_data.exp_file.hash, a1->chara_id, i.motion_id); + pv_expression_array_set_motion(pv_data.exp_file.hash_murmurhash, a1->chara_id, i.motion_id); //if (!a1->pv_game->data.pv->disable_calc_motfrm_limit) sub_140122B60(a1, a1->chara_id, i.motion_index, i.dsc_time); } @@ -4674,7 +4989,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { rob_chr->bone_data->disable_eye_motion = true; rob_chr->data.motion.step_data.step = set_motion.frame_speed; if (v84) - pv_expression_array_set_motion(pv_data.exp_file.hash, a1->chara_id, motion_id); + pv_expression_array_set_motion(pv_data.exp_file.hash_murmurhash, a1->chara_id, motion_id); //if (!a1->pv_game->data.pv->disable_calc_motfrm_limit) sub_140122B60(a1, a1->chara_id, motion_index, v56 ? v56->time : 0); } @@ -5159,7 +5474,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (!rob_chr) break; - rob_chr->item_equip->wet = clamp(value, 0.0f, 1.0f); + rob_chr->item_equip->wet = clamp_def(value, 0.0f, 1.0f); } break; case DSC_X_LIGHT_ROT: { @@ -5784,21 +6099,13 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { auth_3d* auth = auth_3d_data_get_auth_3d(a2m.auth_3d_id); auth_3d_object_hrc* oh = &auth->object_hrc[0]; - - if (rob_chr->data.motion.motion_id == 0xC3) { - data_struct* aft_data = &data_list[DATA_AFT]; - bone_database* aft_bone_data = &aft_data->data_ft.bone_data; - motion_database* aft_mot_db = &aft_data->data_ft.mot_db; - - char buf[0x200]; - sprintf_s(buf, sizeof(buf), "PV826_OST_P%d_00", i.first + 1); - int32_t motion_id = aft_mot_db->get_motion_id(buf); - - rob_chr->set_motion_id(motion_id, 0.0f, - 0.0f, false, false, MOTION_BLEND_CROSS, aft_bone_data, aft_mot_db); - rob_chr->set_motion_reset_data(motion_id, 0.0f); - rob_chr->set_motion_skin_param(motion_id, 0.0f); - } + float_t auth_frame = auth->frame; + bool auth_frame_changed = auth->frame_changed; + bool auth_paused = auth->paused; + auth->frame = (float_t)xpvgm->frame_float; + auth->frame_changed = false; + auth->paused = true; + auth->ctrl(rctx_ptr); rob_chr->set_visibility(oh->node[0].model_transform.visible); @@ -5807,10 +6114,8 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { mot_key_set* key_set = mot->mot_key_data.mot.key_sets; vec3 data[2]; - mat4 mat; - data[0].x = oh->node[a2m.gblctr].model_transform.translation_value.x; + data[0] = oh->node[a2m.gblctr].model_transform.translation_value; data[0].y = oh->node[a2m.n_hara].model_transform.translation_value.y; - data[0].z = oh->node[a2m.gblctr].model_transform.translation_value.z; data[1] = vec3_null; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_N_HARA_CP, key_set, data, 2); @@ -5827,10 +6132,9 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_N_HARA, key_set, data); - mat = oh->node[a2m.j_mune_wj].model_transform.mat; data[0] = { 0.0f, 0.945f, 0.0f }; - mat4_mult_vec3(&mat, &data[0], &data[1]); - mat4_get_translation(&mat, &data[0]); + mat4_mult_vec3(&oh->node[a2m.j_mune_wj].model_transform.mat, &data[0], &data[1]); + mat4_get_translation(&oh->node[a2m.j_mune_wj].model_transform.mat, &data[0]); vec3_add(data[0], data[1], data[0]); data[1] = vec3_null; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, @@ -5844,17 +6148,17 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_KL_KUBI, key_set, data); - data[0] = oh->node[a2m.n_kao].model_transform.rotation_value; - data[0].z -= (float_t)M_PI; + data[0] = { (float_t)(M_PI / 2.0), 0.0f, -(float_t)M_PI }; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_N_KAO, key_set, data); - mat = oh->node[a2m.j_kao_wj].model_transform.mat; data[0] = { 0.0f, 0.40f, 0.0f }; - mat4_mult_vec3(&mat, &data[0], &data[1]); - mat4_get_translation(&mat, &data[0]); + mat4_mult_vec3(&oh->node[a2m.j_kao_wj].model_transform.mat, &data[0], &data[1]); + mat4_get_translation(&oh->node[a2m.j_kao_wj].model_transform.mat, &data[0]); vec3_add(data[0], data[1], data[0]); - data[1] = vec3_null; + data[1] = oh->node[a2m.j_kao_wj].model_transform.rotation_value; + data[1].x = -data[1].x; + data[1].z = -data[1].z; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_CL_KAO, key_set, data, 2); @@ -5876,10 +6180,7 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_N_WAKI_L, key_set, data); - data[1] = oh->node[a2m.j_waki_l_wj].model_transform.rotation_value; - data[0].x = data[1].x; - data[0].y = data[1].z; - data[0].z = -data[1].y; + data[0] = oh->node[a2m.j_waki_l_wj].model_transform.rotation_value; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_KL_WAKI_L_WJ, key_set, data); @@ -5900,7 +6201,7 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { float_t pos_middle_dist; vec3_length(tl_up_kata_dir, pos_middle_dist); if (pos_middle_dist == 0.0f) { - mat = oh->node[a2m.j_kata_l_wj].model_transform.mat; + mat4& mat = oh->node[a2m.j_kata_l_wj].model_transform.mat; data[0] = { 0.0f, 0.3f, 0.0f }; mat4_mult_vec3(&mat, &data[0], &tl_up_kata_dir); } @@ -5910,16 +6211,14 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { vec3 tl_up_kata_pos; vec3_add(tl_up_kata_dir, pos_j_ude_l_wj, tl_up_kata_pos); - mat = oh->node[a2m.j_mune_b_wj].model_transform.mat; + mat4& mat = oh->node[a2m.j_mune_b_wj].model_transform.mat; mat4_mult_vec3_inv_trans(&mat, &tl_up_kata_pos, &data[0]); set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_TL_UP_KATA_L, key_set, data); } mat4_get_translation(&oh->node[a2m.j_te_l_wj].model_transform.mat, &data[0]); - data[1].x = -(float_t)(M_PI / 2.0); - data[1].y = -(float_t)(M_PI / 2.0); - data[1].z = -(float_t)(M_PI / 2.0); + data[1] = { -(float_t)(M_PI / 2.0), -(float_t)(M_PI / 2.0), -(float_t)(M_PI / 2.0) }; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_C_KATA_L, key_set, data, 2); @@ -5931,10 +6230,7 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_N_WAKI_R, key_set, data); - data[1] = oh->node[a2m.j_waki_l_wj].model_transform.rotation_value; - data[0].x = data[1].x; - data[0].y = data[1].z; - data[0].z = data[1].y; + data[0] = oh->node[a2m.j_waki_l_wj].model_transform.rotation_value; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_KL_WAKI_R_WJ, key_set, data); @@ -5955,7 +6251,7 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { float_t pos_middle_dist; vec3_length(tl_up_kata_dir, pos_middle_dist); if (pos_middle_dist == 0.0f) { - mat = oh->node[a2m.j_kata_r_wj].model_transform.mat; + mat4& mat = oh->node[a2m.j_kata_r_wj].model_transform.mat; data[0] = { 0.0f, 0.3f, 0.0f }; mat4_mult_vec3(&mat, &data[0], &tl_up_kata_dir); } @@ -5965,16 +6261,14 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { vec3 tl_up_kata_pos; vec3_add(tl_up_kata_dir, pos_j_ude_r_wj, tl_up_kata_pos); - mat = oh->node[a2m.j_mune_b_wj].model_transform.mat; + mat4& mat = oh->node[a2m.j_mune_b_wj].model_transform.mat; mat4_mult_vec3_inv_trans(&mat, &tl_up_kata_pos, &data[0]); set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_TL_UP_KATA_R, key_set, data); } mat4_get_translation(&oh->node[a2m.j_te_r_wj].model_transform.mat, &data[0]); - data[1].x = -(float_t)(M_PI / 2.0); - data[1].y = (float_t)(M_PI / 2.0); - data[1].z = (float_t)(M_PI / 2.0); + data[1] = { -(float_t)(M_PI / 2.0), (float_t)(M_PI / 2.0), (float_t)(M_PI / 2.0) }; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_C_KATA_R, key_set, data, 2); @@ -5983,15 +6277,31 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { MOTION_BONE_KL_TE_R_WJ, key_set, data); mat4_get_translation(&oh->node[a2m.j_asi_l_wj].model_transform.mat, &data[0]); - data[1] = vec3_null; + data[0].y -= 0.033f; + if (data[0].y < 0.103f) + data[0].y = 0.103f; + data[1] = oh->node[a2m.j_momo_l_wj].model_transform.rotation_value; + data[1].z -= (float_t)(M_PI / 2.0); set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_CL_MOMO_L, key_set, data, 2); mat4_get_translation(&oh->node[a2m.j_asi_r_wj].model_transform.mat, &data[0]); - data[1] = vec3_null; + data[0].y -= 0.033f; + if (data[0].y < 0.103f) + data[0].y = 0.103f; + data[1] = oh->node[a2m.j_momo_r_wj].model_transform.rotation_value; + data[1].z -= (float_t)(M_PI / 2.0); set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_CL_MOMO_R, key_set, data, 2); + data[0] = oh->node[a2m.j_asi_l_wj].model_transform.rotation_value; + set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, + MOTION_BONE_KL_ASI_L_WJ_CO, key_set, data); + + data[0] = oh->node[a2m.j_asi_r_wj].model_transform.rotation_value; + set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, + MOTION_BONE_KL_ASI_R_WJ_CO, key_set, data); + data[0] = { 0.0491406508f, 0.0f, 0.0f }; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_KL_AGO_WJ, key_set, data); @@ -5999,6 +6309,10 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { data[0] = { 0.0f, 0.0331281610f, 0.0f }; set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys, MOTION_BONE_N_KUBI_WJ_EX, key_set, data); + + auth->frame = auth_frame; + auth->frame_changed = auth_frame_changed; + auth->paused = auth_paused; } }*/ @@ -6012,7 +6326,7 @@ static void pv_game_dsc_data_find_playdata_item_anim(x_pv_game* xpvgm, int32_t c if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT) return; - x_pv_play_data* playdata = &xpvgm->playdata[chara_id]; + x_pv_play_data* playdata = &xpvgm->playdata[chara_id]; playdata->motion_data.set_item.clear(); int32_t pv_branch_mode = 0; diff --git a/src/ReDIVA/x_pv_game.hpp b/src/ReDIVA/x_pv_game.hpp index 5b08ecbd..21aaf431 100644 --- a/src/ReDIVA/x_pv_game.hpp +++ b/src/ReDIVA/x_pv_game.hpp @@ -493,6 +493,7 @@ struct x_pv_game_stage { object_database obj_db; texture_database tex_db; + std::map auth_3d_ids; x_pv_game_stage(); ~x_pv_game_stage(); @@ -504,7 +505,8 @@ struct x_pv_game_stage { void load_change_effect(int32_t curr_stage_effect, int32_t next_stage_effect); void reset(); void reset_stage_effect(); - bool set_change_effect_frame(float_t frame); + bool set_change_effect_frame_part_1(); + void set_change_effect_frame_part_2(float_t frame); void set_stage_effect(int32_t stage_effect); void set_stage_effect_auth_3d_frame(int32_t stage_effect, float_t frame); void set_stage_effect_glitter_frame(int32_t stage_effect, float_t frame); @@ -525,8 +527,6 @@ public: XPVFrameRateControl field_7198C; XPVFrameRateControl field_71994; - //std::vector objset_load; - int32_t state_old; int32_t frame; double_t frame_float; @@ -544,8 +544,6 @@ public: std::vector set_motion[ROB_CHARA_COUNT]; - //std::map> pv_auth_3d_chara_count; - bool play; bool success; int32_t chara_id; @@ -576,7 +574,7 @@ public: virtual void Window() override; void Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int32_t modules[6]); - void Unload(); + bool Unload(); void ctrl(float_t curr_time, float_t delta_time); void stop_current_pv(); @@ -604,6 +602,6 @@ public: extern x_pv_game* x_pv_game_ptr; extern XPVGameSelector x_pv_game_selector; -extern void x_pv_game_init(); -extern void x_pv_game_free(); +extern bool x_pv_game_init(); +extern bool x_pv_game_free(); #endif diff --git a/thirdparty.txt b/thirdparty.txt index 7fe73e69..cba936de 100644 --- a/thirdparty.txt +++ b/thirdparty.txt @@ -203,6 +203,8 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------- +lodepng + Copyright (c) 2005-2018 Lode Vandevenne This software is provided 'as-is', without any express or implied @@ -223,3 +225,69 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. + +------------------------------------------------------------------------------- + +libogg + +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------------- + +libvorbis/libvorbisfile + +Copyright (c) 2002-2020 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.