Fix a Big Mistake
This commit is contained in:
parent
b614217a82
commit
6a6c3ed1cf
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,6 +26,5 @@ missing
|
||||
config.log
|
||||
config.status
|
||||
Makefile
|
||||
picasso
|
||||
.deps/
|
||||
*.bz2
|
||||
|
@ -4,11 +4,11 @@ project(picasso)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-L${DEVKITPRO}/libctru/lib -L${DEVKITPRO}/picaGL/lib -L${DEVKITPRO}/portlibs/3ds/lib -specs=3dsx.specs -Wl,--gc-sections")
|
||||
|
||||
include_directories(${DEVKITPRO}/libctru/include ${DEVKITPRO}/picaGL/include ${DEVKITPRO}/portlibs/3ds/include)
|
||||
include_directories(${DEVKITPRO}/libctru/include ${DEVKITPRO}/picaGL/include ${DEVKITPRO}/portlibs/3ds/include ${CMAKE_SOURCE_DIR}/include)
|
||||
add_definitions("-D__3DS__")
|
||||
|
||||
enable_language(ASM)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC source/picasso_assembler.cpp source/picasso_library.cpp)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE include)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
@ -1,7 +1,7 @@
|
||||
#include <3ds.h>
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <picasso.hpp>
|
||||
#include <pica.hpp>
|
||||
|
||||
static const char *const vertShader = R"text(
|
||||
; Example PICA200 vertex shader
|
||||
|
131
include/picasso/FileClass.h
Normal file
131
include/picasso/FileClass.h
Normal file
@ -0,0 +1,131 @@
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include "picasso/types.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
class FileClass
|
||||
{
|
||||
std::stringstream f;
|
||||
bool LittleEndian, own;
|
||||
int filePos;
|
||||
|
||||
size_t _RawRead(void* buffer, size_t size)
|
||||
{
|
||||
f.read((char*)buffer, size);
|
||||
filePos += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t _RawWrite(const void* buffer, size_t size)
|
||||
{
|
||||
f.write((const char*)buffer, size);
|
||||
filePos += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
public:
|
||||
FileClass(const char* file, const char* mode) : LittleEndian(true), own(true), filePos(0)
|
||||
{
|
||||
//Do nothing
|
||||
}
|
||||
~FileClass()
|
||||
{
|
||||
//Do nothing
|
||||
}
|
||||
|
||||
void SetLittleEndian() { LittleEndian = true; }
|
||||
void SetBigEndian() { LittleEndian = false; }
|
||||
|
||||
std::stringstream* get_ptr() { return &f; }
|
||||
bool openerror() { return false; }
|
||||
|
||||
dword_t ReadDword()
|
||||
{
|
||||
dword_t value;
|
||||
_RawRead(&value, sizeof(dword_t));
|
||||
return LittleEndian ? le_dword(value) : be_dword(value);
|
||||
}
|
||||
|
||||
void WriteDword(dword_t value)
|
||||
{
|
||||
value = LittleEndian ? le_dword(value) : be_dword(value);
|
||||
_RawWrite(&value, sizeof(dword_t));
|
||||
}
|
||||
|
||||
word_t ReadWord()
|
||||
{
|
||||
word_t value;
|
||||
_RawRead(&value, sizeof(word_t));
|
||||
return LittleEndian ? le_word(value) : be_word(value);
|
||||
}
|
||||
|
||||
void WriteWord(word_t value)
|
||||
{
|
||||
value = LittleEndian ? le_word(value) : be_word(value);
|
||||
_RawWrite(&value, sizeof(word_t));
|
||||
}
|
||||
|
||||
hword_t ReadHword()
|
||||
{
|
||||
hword_t value;
|
||||
_RawRead(&value, sizeof(hword_t));
|
||||
return LittleEndian ? le_hword(value) : be_hword(value);
|
||||
}
|
||||
|
||||
void WriteHword(hword_t value)
|
||||
{
|
||||
value = LittleEndian ? le_hword(value) : be_hword(value);
|
||||
_RawWrite(&value, sizeof(hword_t));
|
||||
}
|
||||
|
||||
byte_t ReadByte()
|
||||
{
|
||||
byte_t value;
|
||||
_RawRead(&value, sizeof(byte_t));
|
||||
return value;
|
||||
}
|
||||
|
||||
void WriteByte(byte_t value)
|
||||
{
|
||||
_RawWrite(&value, sizeof(byte_t));
|
||||
}
|
||||
|
||||
float ReadFloat()
|
||||
{
|
||||
union { word_t w; float f; } t;
|
||||
t.w = ReadWord();
|
||||
return t.f;
|
||||
}
|
||||
|
||||
void WriteFloat(float value)
|
||||
{
|
||||
union { word_t w; float f; } t;
|
||||
t.f = value;
|
||||
WriteWord(t.w);
|
||||
}
|
||||
|
||||
bool ReadRaw(void* buffer, size_t size) { return _RawRead(buffer, size) == size; }
|
||||
bool WriteRaw(const void* buffer, size_t size) { return _RawWrite(buffer, size) == size; }
|
||||
|
||||
int Tell() { return filePos /*ftell(f)*/; }
|
||||
};
|
||||
|
||||
static inline char* StringFromFile(const char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "rb");
|
||||
if (!f) return NULL;
|
||||
fseek(f, 0, SEEK_END);
|
||||
int size = ftell(f);
|
||||
rewind(f);
|
||||
char* buf = (char*)malloc(size+1);
|
||||
if (!buf)
|
||||
{
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
fread(buf, 1, size, f);
|
||||
buf[size] = 0;
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
57
include/picasso/maestro_opcodes.h
Normal file
57
include/picasso/maestro_opcodes.h
Normal file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
enum
|
||||
{
|
||||
MAESTRO_ADD = 0x00,
|
||||
MAESTRO_DP3,
|
||||
MAESTRO_DP4,
|
||||
MAESTRO_DPH,
|
||||
MAESTRO_DST,
|
||||
MAESTRO_EX2,
|
||||
MAESTRO_LG2,
|
||||
MAESTRO_LITP,
|
||||
MAESTRO_MUL,
|
||||
MAESTRO_SGE,
|
||||
MAESTRO_SLT,
|
||||
MAESTRO_FLR,
|
||||
MAESTRO_MAX,
|
||||
MAESTRO_MIN,
|
||||
MAESTRO_RCP,
|
||||
MAESTRO_RSQ,
|
||||
|
||||
MAESTRO_unk10,
|
||||
MAESTRO_unk11,
|
||||
MAESTRO_MOVA,
|
||||
MAESTRO_MOV,
|
||||
MAESTRO_unk14,
|
||||
MAESTRO_unk15,
|
||||
MAESTRO_unk16,
|
||||
MAESTRO_unk17,
|
||||
MAESTRO_DPHI,
|
||||
MAESTRO_DSTI,
|
||||
MAESTRO_SGEI,
|
||||
MAESTRO_SLTI,
|
||||
MAESTRO_unk1C,
|
||||
MAESTRO_unk1D,
|
||||
MAESTRO_unk1E,
|
||||
MAESTRO_unk1F,
|
||||
|
||||
MAESTRO_BREAK,
|
||||
MAESTRO_NOP,
|
||||
MAESTRO_END,
|
||||
MAESTRO_BREAKC,
|
||||
MAESTRO_CALL,
|
||||
MAESTRO_CALLC,
|
||||
MAESTRO_CALLU,
|
||||
MAESTRO_IFU,
|
||||
MAESTRO_IFC,
|
||||
MAESTRO_FOR,
|
||||
MAESTRO_EMIT, // Geometry shader related
|
||||
MAESTRO_SETEMIT, // Geometry shader related
|
||||
MAESTRO_JMPC,
|
||||
MAESTRO_JMPU,
|
||||
MAESTRO_CMP, // only the upper 5 bits are used for the opcode
|
||||
|
||||
// Only the upper 3 bits are used for the following opcodes
|
||||
MAESTRO_MADI = 0x30,
|
||||
MAESTRO_MAD = 0x38,
|
||||
};
|
256
include/picasso/picasso.h
Normal file
256
include/picasso/picasso.h
Normal file
@ -0,0 +1,256 @@
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <getopt.h>
|
||||
#ifdef WIN32
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "types.h"
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "picasso/FileClass.h"
|
||||
|
||||
#include "picasso/maestro_opcodes.h"
|
||||
|
||||
#if !defined(WIN32) && !defined(stricmp)
|
||||
#define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
COMP_X = 0,
|
||||
COMP_Y,
|
||||
COMP_Z,
|
||||
COMP_W,
|
||||
};
|
||||
|
||||
#define SWIZZLE_COMP(n,v) ((v) << (6-(n)*2))
|
||||
#define OPSRC_MAKE(neg, sw) ((neg) | ((sw) << 1))
|
||||
#define OPDESC_MAKE(out, src1, src2, src3) ((out) | ((src1) << 4) | ((src2) << (4+9)) | ((src3) << (4+9*2)))
|
||||
#define FMT_OPCODE(n) ((n)<<26)
|
||||
#define OUTPUT_MAKE(i, reg, mask) ((i) | ((reg)<<16) | ((u64)(mask)<<32))
|
||||
|
||||
#define DEFAULT_SWIZZLE (SWIZZLE_COMP(0,COMP_X) | SWIZZLE_COMP(1,COMP_Y) | SWIZZLE_COMP(2,COMP_Z) | SWIZZLE_COMP(3,COMP_W))
|
||||
#define DEFAULT_OPSRC OPSRC_MAKE(0, DEFAULT_SWIZZLE)
|
||||
|
||||
#define OPDESC_MASK_D123 OPDESC_MAKE(0xF, 0x1FF, 0x1FF, 0x1FF)
|
||||
#define OPDESC_MASK_D12 OPDESC_MAKE(0xF, 0x1FF, 0x1FF, 0)
|
||||
#define OPDESC_MASK_D1 OPDESC_MAKE(0xF, 0x1FF, 0, 0)
|
||||
#define OPDESC_MASK_1 OPDESC_MAKE(0, 0x1FF, 0, 0)
|
||||
#define OPDESC_MASK_12 OPDESC_MAKE(0, 0x1FF, 0x1FF, 0)
|
||||
|
||||
enum
|
||||
{
|
||||
COND_EQ = 0,
|
||||
COND_NE,
|
||||
COND_LT,
|
||||
COND_LE,
|
||||
COND_GT,
|
||||
COND_GE,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Global data
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Output buffer
|
||||
#define MAX_VSH_SIZE 512
|
||||
typedef std::vector<u32> outputBufType;
|
||||
typedef outputBufType::iterator outputBufIter;
|
||||
extern outputBufType g_outputBuf;
|
||||
|
||||
enum
|
||||
{
|
||||
SE_PROC,
|
||||
SE_FOR,
|
||||
SE_IF,
|
||||
SE_ARRAY,
|
||||
};
|
||||
|
||||
struct StackEntry
|
||||
{
|
||||
int type;
|
||||
size_t pos;
|
||||
union
|
||||
{
|
||||
const char* strExtra;
|
||||
size_t uExtra;
|
||||
};
|
||||
};
|
||||
|
||||
// Stack used to keep track of stuff.
|
||||
#define MAX_STACK 32
|
||||
extern StackEntry g_stack[MAX_STACK];
|
||||
extern int g_stackPos;
|
||||
|
||||
// Operand descriptor stuff.
|
||||
#define MAX_OPDESC 128
|
||||
extern int g_opdescTable[MAX_OPDESC];
|
||||
extern int g_opdeskMasks[MAX_OPDESC]; // used to keep track of used bits
|
||||
extern int g_opdescCount;
|
||||
|
||||
enum
|
||||
{
|
||||
UTYPE_BOOL = 0,
|
||||
UTYPE_IVEC,
|
||||
UTYPE_FVEC,
|
||||
};
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
std::string name;
|
||||
int pos, size;
|
||||
int type;
|
||||
|
||||
inline bool operator <(const Uniform& rhs) const
|
||||
{
|
||||
return pos < rhs.pos;
|
||||
}
|
||||
|
||||
void init(const char* name, int pos, int size, int type)
|
||||
{
|
||||
this->name = name;
|
||||
this->pos = pos;
|
||||
this->size = size;
|
||||
this->type = type;
|
||||
}
|
||||
};
|
||||
|
||||
// List of uniforms
|
||||
#define MAX_UNIFORM 0x60
|
||||
extern Uniform g_uniformTable[MAX_UNIFORM];
|
||||
extern int g_uniformCount;
|
||||
|
||||
struct DVLEData; // Forward declaration
|
||||
|
||||
typedef std::pair<size_t, size_t> procedure; // position, size
|
||||
typedef std::pair<size_t, std::string> relocation; // position, name
|
||||
|
||||
typedef std::map<std::string, procedure> procTableType;
|
||||
typedef std::map<std::string, size_t> labelTableType;
|
||||
typedef std::map<std::string, int> aliasTableType;
|
||||
typedef std::vector<relocation> relocTableType;
|
||||
typedef std::list<DVLEData> dvleTableType;
|
||||
|
||||
typedef procTableType::iterator procTableIter;
|
||||
typedef labelTableType::iterator labelTableIter;
|
||||
typedef aliasTableType::iterator aliasTableIter;
|
||||
typedef relocTableType::iterator relocTableIter;
|
||||
typedef dvleTableType::iterator dvleTableIter;
|
||||
|
||||
extern procTableType g_procTable;
|
||||
extern dvleTableType g_dvleTable;
|
||||
extern relocTableType g_procRelocTable;
|
||||
extern int g_totalDvleCount;
|
||||
|
||||
// The following are cleared before each file is processed
|
||||
extern labelTableType g_labels;
|
||||
extern relocTableType g_labelRelocTable;
|
||||
extern aliasTableType g_aliases;
|
||||
|
||||
extern bool g_autoNop;
|
||||
|
||||
int AssembleString(char* str, const char* initialFilename);
|
||||
int RelocateProduct(void);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local data
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
OUTTYPE_POS = 0,
|
||||
OUTTYPE_NQUAT = 1,
|
||||
OUTTYPE_CLR = 2,
|
||||
OUTTYPE_TCOORD0 = 3,
|
||||
OUTTYPE_TCOORD0W = 4,
|
||||
OUTTYPE_TCOORD1 = 5,
|
||||
OUTTYPE_TCOORD2 = 6,
|
||||
OUTTYPE_VIEW = 8,
|
||||
OUTTYPE_DUMMY = 9,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GSHTYPE_POINT = 0,
|
||||
GSHTYPE_VARIABLE = 1,
|
||||
GSHTYPE_FIXED = 2,
|
||||
};
|
||||
|
||||
struct Constant
|
||||
{
|
||||
int regId;
|
||||
int type;
|
||||
union
|
||||
{
|
||||
float fparam[4];
|
||||
u8 iparam[4];
|
||||
bool bparam;
|
||||
};
|
||||
};
|
||||
|
||||
struct DVLEData
|
||||
{
|
||||
// General config
|
||||
std::string filename;
|
||||
std::string entrypoint;
|
||||
size_t entryStart, entryEnd;
|
||||
bool nodvle, isGeoShader, isCompatGeoShader, isMerge;
|
||||
u16 inputMask, outputMask;
|
||||
u8 geoShaderType;
|
||||
u8 geoShaderFixedStart;
|
||||
u8 geoShaderVariableNum;
|
||||
u8 geoShaderFixedNum;
|
||||
|
||||
// Uniforms
|
||||
Uniform uniformTable[MAX_UNIFORM];
|
||||
int uniformCount;
|
||||
size_t symbolSize;
|
||||
|
||||
// Constants
|
||||
#define MAX_CONSTANT 0x60
|
||||
Constant constantTable[MAX_CONSTANT];
|
||||
int constantCount;
|
||||
|
||||
// Outputs
|
||||
#define MAX_OUTPUT 16
|
||||
u64 outputTable[MAX_OUTPUT];
|
||||
u32 outputUsedReg;
|
||||
int outputCount;
|
||||
|
||||
bool usesGshSpace() const { return isGeoShader && !isCompatGeoShader; }
|
||||
int findFreeOutput() const
|
||||
{
|
||||
for (int i = 0; i < maxOutputReg(); i ++)
|
||||
if (!(outputMask & BIT(i)))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int findFreeInput() const
|
||||
{
|
||||
for (int i = 0; i < 16; i ++)
|
||||
if (!(inputMask & BIT(i)))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int maxOutputReg() const
|
||||
{
|
||||
return isGeoShader ? 0x07 : 0x10;
|
||||
}
|
||||
|
||||
DVLEData(const char* filename) :
|
||||
filename(filename), entrypoint("main"),
|
||||
nodvle(false), isGeoShader(false), isCompatGeoShader(false), isMerge(false),
|
||||
inputMask(0), outputMask(0), geoShaderType(0), geoShaderFixedStart(0), geoShaderVariableNum(0), geoShaderFixedNum(0),
|
||||
uniformCount(0), symbolSize(0), constantCount(0), outputUsedReg(0), outputCount(0) { }
|
||||
};
|
68
include/picasso/types.h
Normal file
68
include/picasso/types.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint64_t dword_t;
|
||||
typedef uint32_t word_t;
|
||||
typedef uint16_t hword_t;
|
||||
typedef uint8_t byte_t;
|
||||
typedef int64_t dlong_t;
|
||||
typedef int32_t long_t;
|
||||
typedef int16_t short_t;
|
||||
typedef int8_t char_t;
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
#define BIT(n) (1U << (n))
|
||||
|
||||
#ifndef __BYTE_ORDER__
|
||||
#include <sys/param.h>
|
||||
#define __BYTE_ORDER__ BYTE_ORDER
|
||||
#define __ORDER_LITTLE_ENDIAN__ LITTLE_ENDIAN
|
||||
#define __ORDER_BIG_ENDIAN__ BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifndef __llvm__
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
|
||||
|
||||
static inline uint16_t __builtin_bswap16(uint16_t x)
|
||||
{
|
||||
return ((x << 8) & 0xff00) | ((x >> 8) & 0x00ff);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
|
||||
static inline uint32_t __builtin_bswap32(uint32_t x)
|
||||
{
|
||||
return ((x << 24) & 0xff000000) |
|
||||
((x << 8) & 0x00ff0000) |
|
||||
((x >> 8) & 0x0000ff00) |
|
||||
((x >> 24) & 0x000000ff);
|
||||
}
|
||||
|
||||
static inline uint64_t __builtin_bswap64(uint64_t x)
|
||||
{
|
||||
return (uint64_t)__builtin_bswap32(x>>32) |
|
||||
((uint64_t)__builtin_bswap32(x&0xFFFFFFFF) << 32);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define be_dword(a) __builtin_bswap64(a)
|
||||
#define be_word(a) __builtin_bswap32(a)
|
||||
#define be_hword(a) __builtin_bswap16(a)
|
||||
#define le_dword(a) (a)
|
||||
#define le_word(a) (a)
|
||||
#define le_hword(a) (a)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define be_dword(a) (a)
|
||||
#define be_word(a) (a)
|
||||
#define be_hword(a) (a)
|
||||
#define le_dword(a) __builtin_bswap64(a)
|
||||
#define le_word(a) __builtin_bswap32(a)
|
||||
#define le_hword(a) __builtin_bswap16(a)
|
||||
#else
|
||||
#error "What's the endianness of the platform you're targeting?"
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
#include <picasso/picasso.h>
|
||||
#include "picasso/picasso.h"
|
||||
|
||||
//#define DEBUG
|
||||
#define BUF g_outputBuf
|
||||
|
Loading…
Reference in New Issue
Block a user